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.
This commit is contained in:
Antonio Maiorano 2024-05-09 16:35:54 -04:00 коммит произвёл GitHub
Родитель 5275debcde
Коммит 35de5018ab
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
3 изменённых файлов: 43 добавлений и 1 удалений

Просмотреть файл

@ -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<llvm::IntegerType>(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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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<PointerType>(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();
}
}