diff options
| author | Bradley Smith <bradley.smith@arm.com> | 2021-07-26 10:34:08 +0000 |
|---|---|---|
| committer | Bradley Smith <bradley.smith@arm.com> | 2021-08-04 16:10:37 +0000 |
| commit | e57e1e4e00264b77b2b35ad2bf419a48aecdd6bc (patch) | |
| tree | 85a0a4a20e1faed7eb6a1b0dc7835016dacaacd9 /clang/lib/CodeGen/CGExprScalar.cpp | |
| parent | 66d4430492131a2205f159071c15e90c10e2fced (diff) | |
[clang][AArch64][SVE] Avoid going through memory for fixed/scalable predicate casts
For fixed SVE types, predicates are represented using vectors of i8,
where as for scalable types they are represented using vectors of i1. We
can avoid going through memory for casts between these by bitcasting the
i1 scalable vectors to/from a scalable i8 vector of matching size, which
can then use the existing vector insert/extract logic.
Differential Revision: https://reviews.llvm.org/D106860
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) && |
