From 15e180b21b0eb0da6e828bd7972e401b4e3ae8c7 Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Mon, 6 May 2024 14:08:45 -0400 Subject: [PATCH 1/2] Fix invalid module bitcode when indexing a swizzled bool vector MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When indexing a swizzled bool vector, some HLSL-specific code in EmitCXXMemberOrOperatorMemberCallExpr kicks in to handle the HLSLVecType. In this case, we’re dealing with an ExtVectorElt because of the swizzle, so this function creates a GEP, Load, and Store on the vector. However, we need to truncate the loaded value from i32 to i1, otherwise we attempt to write an i32 to an i1, which trips the assert. --- tools/clang/lib/CodeGen/CGExpr.cpp | 8 ++++- tools/clang/lib/CodeGen/CGExprCXX.cpp | 5 ++++ .../swizzle/indexSwizzledBoolVec.hlsl | 30 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tools/clang/test/CodeGenDXIL/operators/swizzle/indexSwizzledBoolVec.hlsl diff --git a/tools/clang/lib/CodeGen/CGExpr.cpp b/tools/clang/lib/CodeGen/CGExpr.cpp index cc46d067e6..80f670b029 100644 --- a/tools/clang/lib/CodeGen/CGExpr.cpp +++ b/tools/clang/lib/CodeGen/CGExpr.cpp @@ -1137,6 +1137,11 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) { return MDHelper.createRange(Min, End); } +bool ShouldEmitRangeMD(llvm::Value *Value, QualType Ty) { + return hasBooleanRepresentation(Ty) && + cast(Value->getType())->getBitWidth() != 1; +} + llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, SourceLocation Loc, @@ -1236,7 +1241,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile, EmitCheck(std::make_pair(Check, Kind), "load_invalid_value", StaticArgs, EmitCheckValue(Load)); } - } else if (CGM.getCodeGenOpts().OptimizationLevel > 0) + } else if (CGM.getCodeGenOpts().OptimizationLevel > 0 && + ShouldEmitRangeMD(Load, Ty)) if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo); diff --git a/tools/clang/lib/CodeGen/CGExprCXX.cpp b/tools/clang/lib/CodeGen/CGExprCXX.cpp index 2efde7c30f..924a0f806e 100644 --- a/tools/clang/lib/CodeGen/CGExprCXX.cpp +++ b/tools/clang/lib/CodeGen/CGExprCXX.cpp @@ -235,12 +235,17 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr( llvm::Constant *zero = Builder.getInt32(0); llvm::Value *TmpThis = CreateTempAlloca(Ty); + QualType ElTy = hlsl::GetElementTypeOrType(Base->getType()); + bool IsBool = ElTy->isSpecificBuiltinType(BuiltinType::Bool); for (unsigned i = 0; i < Ty->getVectorNumElements(); i++) { llvm::Value *EltIdx = Elts->getAggregateElement(i); llvm::Value *EltGEP = Builder.CreateGEP(This, {zero, EltIdx}); llvm::Value *TmpEltGEP = Builder.CreateGEP(TmpThis, {zero, Builder.getInt32(i)}); llvm::Value *Elt = Builder.CreateLoad(EltGEP); + if (IsBool) + Elt = Builder.CreateTrunc( + Elt, llvm::Type::getInt1Ty(getLLVMContext())); Builder.CreateStore(Elt, TmpEltGEP); } This = TmpThis; diff --git a/tools/clang/test/CodeGenDXIL/operators/swizzle/indexSwizzledBoolVec.hlsl b/tools/clang/test/CodeGenDXIL/operators/swizzle/indexSwizzledBoolVec.hlsl new file mode 100644 index 0000000000..a47482d204 --- /dev/null +++ b/tools/clang/test/CodeGenDXIL/operators/swizzle/indexSwizzledBoolVec.hlsl @@ -0,0 +1,30 @@ +// Test indexing a swizzled bool vector +// RUN: %dxc -fcgl -T cs_6_0 %s | FileCheck %s + +// This was asserting in Instructions.cpp with: +// void llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() == cast(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"' failed. + +// Make sure load of i32 gets truncated to i1 when indexing bool vectors +// CHECK: [[TMP:%[a-z0-9\.]+]] = alloca <2 x i1> +// CHECK: [[VA0:%[a-z0-9\.]+]] = getelementptr <2 x i1>, <2 x i1>* [[TMP]], i32 0, i32 0, +// CHECK-NEXT: [[VA1:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds (<4 x i32>, <4 x i32>* @"\01?v_bool4@?1??main@@YAXXZ@3V?$vector@_N$03@@B", i32 0, i32 2), +// CHECK-NEXT: [[VA2:%[a-z0-9\.]+]] = trunc i32 [[VA1]] to i1, +// CHECK-NEXT: store i1 [[VA2]], i1* [[VA0]], +// CHECK-NEXT: [[VB0:%[a-z0-9\.]+]] = getelementptr <2 x i1>, <2 x i1>* [[TMP]], i32 0, i32 1, +// CHECK-NEXT: [[VB1:%[a-z0-9\.]+]] = load i32, i32* getelementptr inbounds (<4 x i32>, <4 x i32>* @"\01?v_bool4@?1??main@@YAXXZ@3V?$vector@_N$03@@B", i32 0, i32 3), +// CHECK-NEXT: [[VB2:%[a-z0-9\.]+]] = trunc i32 [[VB1]] to i1, +// CHECK-NEXT: store i1 [[VB2]], i1* [[VB0]], + + +cbuffer cbuffer_tint_symbol_3 : register(b0) { + uint4 global_uint4[1]; +}; + +[numthreads(1, 1, 1)] +void main() { + const bool4 v_bool4 = bool4(true, true, true, true); + const uint gx = global_uint4[0].x; + if (v_bool4.zw[gx] == 0) { + GroupMemoryBarrierWithGroupSync(); + } +} From e058de707cfea5b0f62fa27f2d3657d39d1c8dbe Mon Sep 17 00:00:00 2001 From: Antonio Maiorano Date: Wed, 8 May 2024 11:41:44 -0400 Subject: [PATCH 2/2] Address PR comments --- tools/clang/lib/CodeGen/CGExpr.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/clang/lib/CodeGen/CGExpr.cpp b/tools/clang/lib/CodeGen/CGExpr.cpp index 80f670b029..efef0593b3 100644 --- a/tools/clang/lib/CodeGen/CGExpr.cpp +++ b/tools/clang/lib/CodeGen/CGExpr.cpp @@ -1137,9 +1137,10 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) { return MDHelper.createRange(Min, End); } -bool ShouldEmitRangeMD(llvm::Value *Value, QualType Ty) { - return hasBooleanRepresentation(Ty) && - cast(Value->getType())->getBitWidth() != 1; +static bool ShouldEmitRangeMD(llvm::Value *Value, QualType Ty) { + if (hasBooleanRepresentation(Ty)) + return cast(Value->getType())->getBitWidth() != 1; + return true; } llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,