aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@sifive.com>2025-05-14 10:27:00 -0700
committerGitHub <noreply@github.com>2025-05-14 10:27:00 -0700
commitbf0655f2080248a59aa2b79f2579798b8158869c (patch)
treea69855a810b70dda6e4a7c9389ce523cd34948be /clang/lib/CodeGen/CGCall.cpp
parenta3ba00a3dbc314794d8ca14d0c0993ef5a229069 (diff)
downloadllvm-bf0655f2080248a59aa2b79f2579798b8158869c.zip
llvm-bf0655f2080248a59aa2b79f2579798b8158869c.tar.gz
llvm-bf0655f2080248a59aa2b79f2579798b8158869c.tar.bz2
[RISCV] Improve casting between i1 scalable vectors and i8 fixed vectors for -mrvv-vector-bits (#139190)
For i1 vectors, we used an i8 fixed vector as the storage type. If the known minimum number of elements of the scalable vector type is less than 8, we were doing the cast through memory. This used a load or store from a fixed vector alloca. If is less than 8, DataLayout indicates that the load/store reads/writes vscale bytes even if vscale is known and vscale*X is less than or equal to 8. This means the load or store is outside the bounds of the fixed size alloca as far as DataLayout is concerned leading to undefined behavior. This patch avoids this by widening the i1 scalable vector type with zero elements until it is divisible by 8. This allows it be bitcasted to/from an i8 scalable vector. We then insert or extract the i8 fixed vector into this type. Hopefully this enables #130973 to be accepted.
Diffstat (limited to 'clang/lib/CodeGen/CGCall.cpp')
-rw-r--r--clang/lib/CodeGen/CGCall.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index aa19094..bcd5794 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -1366,19 +1366,23 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty,
// If we are casting a fixed i8 vector to a scalable i1 predicate
// vector, use a vector insert and bitcast the result.
if (ScalableDstTy->getElementType()->isIntegerTy(1) &&
- ScalableDstTy->getElementCount().isKnownMultipleOf(8) &&
FixedSrcTy->getElementType()->isIntegerTy(8)) {
ScalableDstTy = llvm::ScalableVectorType::get(
FixedSrcTy->getElementType(),
- ScalableDstTy->getElementCount().getKnownMinValue() / 8);
+ llvm::divideCeil(
+ ScalableDstTy->getElementCount().getKnownMinValue(), 8));
}
if (ScalableDstTy->getElementType() == FixedSrcTy->getElementType()) {
auto *Load = CGF.Builder.CreateLoad(Src);
auto *PoisonVec = llvm::PoisonValue::get(ScalableDstTy);
llvm::Value *Result = CGF.Builder.CreateInsertVector(
ScalableDstTy, PoisonVec, Load, uint64_t(0), "cast.scalable");
- if (ScalableDstTy != Ty)
- Result = CGF.Builder.CreateBitCast(Result, Ty);
+ ScalableDstTy = cast<llvm::ScalableVectorType>(
+ llvm::VectorType::getWithSizeAndScalar(ScalableDstTy, Ty));
+ if (Result->getType() != ScalableDstTy)
+ Result = CGF.Builder.CreateBitCast(Result, ScalableDstTy);
+ if (Result->getType() != Ty)
+ Result = CGF.Builder.CreateExtractVector(Ty, Result, uint64_t(0));
return Result;
}
}
@@ -1476,8 +1480,14 @@ CoerceScalableToFixed(CodeGenFunction &CGF, llvm::FixedVectorType *ToTy,
// If we are casting a scalable i1 predicate vector to a fixed i8
// vector, first bitcast the source.
if (FromTy->getElementType()->isIntegerTy(1) &&
- FromTy->getElementCount().isKnownMultipleOf(8) &&
ToTy->getElementType() == CGF.Builder.getInt8Ty()) {
+ if (!FromTy->getElementCount().isKnownMultipleOf(8)) {
+ FromTy = llvm::ScalableVectorType::get(
+ FromTy->getElementType(),
+ llvm::alignTo<8>(FromTy->getElementCount().getKnownMinValue()));
+ llvm::Value *ZeroVec = llvm::Constant::getNullValue(FromTy);
+ V = CGF.Builder.CreateInsertVector(FromTy, ZeroVec, V, uint64_t(0));
+ }
FromTy = llvm::ScalableVectorType::get(
ToTy->getElementType(),
FromTy->getElementCount().getKnownMinValue() / 8);