diff options
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CGExprScalar.cpp | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 418f23bd1a97..e47701915f2f 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2063,11 +2063,25 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { // perform the bitcast. if (const auto *FixedSrc = dyn_cast<llvm::FixedVectorType>(SrcTy)) { if (const auto *ScalableDst = dyn_cast<llvm::ScalableVectorType>(DstTy)) { + // If we are casting a fixed i8 vector to a scalable 16 x i1 predicate + // vector, use a vector insert and bitcast the result. + bool NeedsBitCast = false; + auto PredType = llvm::ScalableVectorType::get(Builder.getInt1Ty(), 16); + llvm::Type *OrigType = DstTy; + if (ScalableDst == PredType && + FixedSrc->getElementType() == Builder.getInt8Ty()) { + DstTy = llvm::ScalableVectorType::get(Builder.getInt8Ty(), 2); + ScalableDst = dyn_cast<llvm::ScalableVectorType>(DstTy); + NeedsBitCast = true; + } if (FixedSrc->getElementType() == ScalableDst->getElementType()) { llvm::Value *UndefVec = llvm::UndefValue::get(DstTy); llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty); - return Builder.CreateInsertVector(DstTy, UndefVec, Src, Zero, - "castScalableSve"); + llvm::Value *Result = Builder.CreateInsertVector( + DstTy, UndefVec, Src, Zero, "castScalableSve"); + if (NeedsBitCast) + Result = Builder.CreateBitCast(Result, OrigType); + return Result; } } } @@ -2077,6 +2091,15 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { // perform the bitcast. if (const auto *ScalableSrc = dyn_cast<llvm::ScalableVectorType>(SrcTy)) { if (const auto *FixedDst = dyn_cast<llvm::FixedVectorType>(DstTy)) { + // If we are casting a scalable 16 x i1 predicate vector to a fixed i8 + // vector, bitcast the source and use a vector extract. + auto PredType = llvm::ScalableVectorType::get(Builder.getInt1Ty(), 16); + if (ScalableSrc == PredType && + FixedDst->getElementType() == Builder.getInt8Ty()) { + SrcTy = llvm::ScalableVectorType::get(Builder.getInt8Ty(), 2); + ScalableSrc = dyn_cast<llvm::ScalableVectorType>(SrcTy); + Src = Builder.CreateBitCast(Src, SrcTy); + } if (ScalableSrc->getElementType() == FixedDst->getElementType()) { llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty); return Builder.CreateExtractVector(DstTy, Src, Zero, "castFixedSve"); @@ -2087,10 +2110,9 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { // Perform VLAT <-> VLST bitcast through memory. // TODO: since the llvm.experimental.vector.{insert,extract} intrinsics // require the element types of the vectors to be the same, we - // need to keep this around for casting between predicates, or more - // generally for bitcasts between VLAT <-> VLST where the element - // types of the vectors are not the same, until we figure out a better - // way of doing these casts. + // need to keep this around for bitcasts between VLAT <-> VLST where + // the element types of the vectors are not the same, until we figure + // out a better way of doing these casts. if ((isa<llvm::FixedVectorType>(SrcTy) && isa<llvm::ScalableVectorType>(DstTy)) || (isa<llvm::ScalableVectorType>(SrcTy) && |
