From a29afb754fb445a2cccc361c556d4e072604b3be Mon Sep 17 00:00:00 2001 From: Chris B Date: Wed, 11 Sep 2024 17:27:09 -0500 Subject: [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 --- clang/lib/CodeGen/CGExprScalar.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'clang/lib/CodeGen/CGExprScalar.cpp') 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(E)); - SmallVector Mask; - unsigned NumElts = DestTy->castAs()->getNumElements(); - for (unsigned I = 0; I != NumElts; ++I) - Mask.push_back(I); + if (auto *VecTy = DestTy->getAs()) { + SmallVector 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 -- cgit v1.2.3