summaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
authorChris B <chris.bieneman@me.com>2024-09-11 17:27:09 -0500
committerGitHub <noreply@github.com>2024-09-11 17:27:09 -0500
commita29afb754fb445a2cccc361c556d4e072604b3be (patch)
tree871ceb92a9232113d446eecac46bc4aa315900c3 /clang/lib/CodeGen/CGExprScalar.cpp
parenta85883662ad1904844b1bd5a34bf93d9b383e3b8 (diff)
[HLSL] Allow truncation to scalar (#104844)
HLSL allows implicit conversions to truncate vectors to scalar pr-values. These conversions are scored as vector truncations and should warn appropriately. This change allows forming a truncation cast to a pr-value, but not an l-value. Truncating a vector to a scalar is performed by loading the first element of the vector and disregarding the remaining elements. Fixes #102964
Diffstat (limited to 'clang/lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp17
1 files changed, 11 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 9027bab6b680..82caf65ac68d 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2709,14 +2709,19 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);
case CK_HLSLVectorTruncation: {
- assert(DestTy->isVectorType() && "Expected dest type to be vector type");
+ assert((DestTy->isVectorType() || DestTy->isBuiltinType()) &&
+ "Destination type must be a vector or builtin type.");
Value *Vec = Visit(const_cast<Expr *>(E));
- SmallVector<int, 16> Mask;
- unsigned NumElts = DestTy->castAs<VectorType>()->getNumElements();
- for (unsigned I = 0; I != NumElts; ++I)
- Mask.push_back(I);
+ if (auto *VecTy = DestTy->getAs<VectorType>()) {
+ SmallVector<int> Mask;
+ unsigned NumElts = VecTy->getNumElements();
+ for (unsigned I = 0; I != NumElts; ++I)
+ Mask.push_back(I);
- return Builder.CreateShuffleVector(Vec, Mask, "trunc");
+ return Builder.CreateShuffleVector(Vec, Mask, "trunc");
+ }
+ llvm::Value *Zero = llvm::Constant::getNullValue(CGF.SizeTy);
+ return Builder.CreateExtractElement(Vec, Zero, "cast.vtrunc");
}
} // end of switch