summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp34
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) &&