diff --git a/tools/clang/lib/CodeGen/CGExpr.cpp b/tools/clang/lib/CodeGen/CGExpr.cpp index cc46d067e6..efef0593b3 100644 --- a/tools/clang/lib/CodeGen/CGExpr.cpp +++ b/tools/clang/lib/CodeGen/CGExpr.cpp @@ -1137,6 +1137,12 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) { return MDHelper.createRange(Min, End); } +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, unsigned Alignment, QualType Ty, SourceLocation Loc, @@ -1236,7 +1242,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(); + } +}