Skip to content

Commit 35de501

Browse files
authored
Fix invalid module bitcode when indexing a swizzled bool vector (#6582)
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, boolean scalars are returned as type i11 while the store is storing to a bool, which is an i32, so we need to insert a cast before the store.
1 parent 5275deb commit 35de501

3 files changed

Lines changed: 43 additions & 1 deletion

File tree

tools/clang/lib/CodeGen/CGExpr.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,12 @@ llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
11371137
return MDHelper.createRange(Min, End);
11381138
}
11391139

1140+
static bool ShouldEmitRangeMD(llvm::Value *Value, QualType Ty) {
1141+
if (hasBooleanRepresentation(Ty))
1142+
return cast<llvm::IntegerType>(Value->getType())->getBitWidth() != 1;
1143+
return true;
1144+
}
1145+
11401146
llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
11411147
unsigned Alignment, QualType Ty,
11421148
SourceLocation Loc,
@@ -1236,7 +1242,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
12361242
EmitCheck(std::make_pair(Check, Kind), "load_invalid_value", StaticArgs,
12371243
EmitCheckValue(Load));
12381244
}
1239-
} else if (CGM.getCodeGenOpts().OptimizationLevel > 0)
1245+
} else if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1246+
ShouldEmitRangeMD(Load, Ty))
12401247
if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty))
12411248
Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
12421249

tools/clang/lib/CodeGen/CGExprCXX.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,12 +235,17 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
235235

236236
llvm::Constant *zero = Builder.getInt32(0);
237237
llvm::Value *TmpThis = CreateTempAlloca(Ty);
238+
QualType ElTy = hlsl::GetElementTypeOrType(Base->getType());
239+
bool IsBool = ElTy->isSpecificBuiltinType(BuiltinType::Bool);
238240
for (unsigned i = 0; i < Ty->getVectorNumElements(); i++) {
239241
llvm::Value *EltIdx = Elts->getAggregateElement(i);
240242
llvm::Value *EltGEP = Builder.CreateGEP(This, {zero, EltIdx});
241243
llvm::Value *TmpEltGEP =
242244
Builder.CreateGEP(TmpThis, {zero, Builder.getInt32(i)});
243245
llvm::Value *Elt = Builder.CreateLoad(EltGEP);
246+
if (IsBool)
247+
Elt = Builder.CreateTrunc(
248+
Elt, llvm::Type::getInt1Ty(getLLVMContext()));
244249
Builder.CreateStore(Elt, TmpEltGEP);
245250
}
246251
This = TmpThis;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Test indexing a swizzled bool vector
2+
// RUN: %dxc -fcgl -T cs_6_0 %s | FileCheck %s
3+
4+
// This was asserting in Instructions.cpp with:
5+
// void llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"' failed.
6+
7+
// Make sure load of i32 gets truncated to i1 when indexing bool vectors
8+
// CHECK: [[TMP:%[a-z0-9\.]+]] = alloca <2 x i1>
9+
// CHECK: [[VA0:%[a-z0-9\.]+]] = getelementptr <2 x i1>, <2 x i1>* [[TMP]], i32 0, i32 0,
10+
// 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),
11+
// CHECK-NEXT: [[VA2:%[a-z0-9\.]+]] = trunc i32 [[VA1]] to i1,
12+
// CHECK-NEXT: store i1 [[VA2]], i1* [[VA0]],
13+
// CHECK-NEXT: [[VB0:%[a-z0-9\.]+]] = getelementptr <2 x i1>, <2 x i1>* [[TMP]], i32 0, i32 1,
14+
// 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),
15+
// CHECK-NEXT: [[VB2:%[a-z0-9\.]+]] = trunc i32 [[VB1]] to i1,
16+
// CHECK-NEXT: store i1 [[VB2]], i1* [[VB0]],
17+
18+
19+
cbuffer cbuffer_tint_symbol_3 : register(b0) {
20+
uint4 global_uint4[1];
21+
};
22+
23+
[numthreads(1, 1, 1)]
24+
void main() {
25+
const bool4 v_bool4 = bool4(true, true, true, true);
26+
const uint gx = global_uint4[0].x;
27+
if (v_bool4.zw[gx] == 0) {
28+
GroupMemoryBarrierWithGroupSync();
29+
}
30+
}

0 commit comments

Comments
 (0)