diff options
| author | Chris B <chris.bieneman@me.com> | 2024-09-11 17:27:09 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-11 17:27:09 -0500 |
| commit | a29afb754fb445a2cccc361c556d4e072604b3be (patch) | |
| tree | 871ceb92a9232113d446eecac46bc4aa315900c3 /clang/lib/CodeGen/CGExprScalar.cpp | |
| parent | a85883662ad1904844b1bd5a34bf93d9b383e3b8 (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.cpp | 17 |
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 |
