@@ -2084,11 +2084,25 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
2084
2084
// perform the bitcast.
2085
2085
if (const auto *FixedSrc = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2086
2086
if (const auto *ScalableDst = dyn_cast<llvm::ScalableVectorType>(DstTy)) {
2087
+ // If we are casting a fixed i8 vector to a scalable 16 x i1 predicate
2088
+ // vector, use a vector insert and bitcast the result.
2089
+ bool NeedsBitCast = false;
2090
+ auto PredType = llvm::ScalableVectorType::get(Builder.getInt1Ty(), 16);
2091
+ llvm::Type *OrigType = DstTy;
2092
+ if (ScalableDst == PredType &&
2093
+ FixedSrc->getElementType() == Builder.getInt8Ty()) {
2094
+ DstTy = llvm::ScalableVectorType::get(Builder.getInt8Ty(), 2);
2095
+ ScalableDst = dyn_cast<llvm::ScalableVectorType>(DstTy);
2096
+ NeedsBitCast = true;
2097
+ }
2087
2098
if (FixedSrc->getElementType() == ScalableDst->getElementType()) {
2088
2099
llvm::Value *UndefVec = llvm::UndefValue::get(DstTy);
2089
2100
llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
2090
- return Builder.CreateInsertVector (DstTy, UndefVec, Src, Zero,
2091
- " castScalableSve" );
2101
+ llvm::Value *Result = Builder.CreateInsertVector(
2102
+ DstTy, UndefVec, Src, Zero, "castScalableSve");
2103
+ if (NeedsBitCast)
2104
+ Result = Builder.CreateBitCast(Result, OrigType);
2105
+ return Result;
2092
2106
}
2093
2107
}
2094
2108
}
@@ -2098,6 +2112,15 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
2098
2112
// perform the bitcast.
2099
2113
if (const auto *ScalableSrc = dyn_cast<llvm::ScalableVectorType>(SrcTy)) {
2100
2114
if (const auto *FixedDst = dyn_cast<llvm::FixedVectorType>(DstTy)) {
2115
+ // If we are casting a scalable 16 x i1 predicate vector to a fixed i8
2116
+ // vector, bitcast the source and use a vector extract.
2117
+ auto PredType = llvm::ScalableVectorType::get(Builder.getInt1Ty(), 16);
2118
+ if (ScalableSrc == PredType &&
2119
+ FixedDst->getElementType() == Builder.getInt8Ty()) {
2120
+ SrcTy = llvm::ScalableVectorType::get(Builder.getInt8Ty(), 2);
2121
+ ScalableSrc = dyn_cast<llvm::ScalableVectorType>(SrcTy);
2122
+ Src = Builder.CreateBitCast(Src, SrcTy);
2123
+ }
2101
2124
if (ScalableSrc->getElementType() == FixedDst->getElementType()) {
2102
2125
llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty);
2103
2126
return Builder.CreateExtractVector(DstTy, Src, Zero, "castFixedSve");
@@ -2108,10 +2131,9 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
2108
2131
// Perform VLAT <-> VLST bitcast through memory.
2109
2132
// TODO: since the llvm.experimental.vector.{insert,extract} intrinsics
2110
2133
// require the element types of the vectors to be the same, we
2111
- // need to keep this around for casting between predicates, or more
2112
- // generally for bitcasts between VLAT <-> VLST where the element
2113
- // types of the vectors are not the same, until we figure out a better
2114
- // way of doing these casts.
2134
+ // need to keep this around for bitcasts between VLAT <-> VLST where
2135
+ // the element types of the vectors are not the same, until we figure
2136
+ // out a better way of doing these casts.
2115
2137
if ((isa<llvm::FixedVectorType>(SrcTy) &&
2116
2138
isa<llvm::ScalableVectorType>(DstTy)) ||
2117
2139
(isa<llvm::ScalableVectorType>(SrcTy) &&
0 commit comments