Skip to content

Commit 4bea79a

Browse files
authored
Special ICB variables for nops are now arrays for driver compat. (#2774) (#2776)
1 parent ab68415 commit 4bea79a

18 files changed

Lines changed: 150 additions & 79 deletions

lib/HLSL/DxilNoops.cpp

Lines changed: 58 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ using namespace llvm;
103103
namespace {
104104
StringRef kNoopName = "dx.noop";
105105
StringRef kPreservePrefix = "dx.preserve.";
106-
StringRef kNothingName = "dx.nothing";
107-
StringRef kPreserveName = "dx.preserve.value";
106+
StringRef kNothingName = "dx.nothing.a";
107+
StringRef kPreserveName = "dx.preserve.value.a";
108108
}
109109

110110
static Function *GetOrCreateNoopF(Module &M) {
@@ -115,6 +115,12 @@ static Function *GetOrCreateNoopF(Module &M) {
115115
return NoopF;
116116
}
117117

118+
static Constant *GetConstGep(Constant *Ptr, unsigned Idx0, unsigned Idx1) {
119+
Type *i32Ty = Type::getInt32Ty(Ptr->getContext());
120+
Constant *Indices[] = { ConstantInt::get(i32Ty, Idx0), ConstantInt::get(i32Ty, Idx1) };
121+
return ConstantExpr::getGetElementPtr(nullptr, Ptr, Indices);
122+
}
123+
118124
static bool ShouldPreserve(Value *V) {
119125
if (isa<Constant>(V)) return true;
120126
if (isa<Argument>(V)) return true;
@@ -190,26 +196,39 @@ static void FindAllStores(Value *Ptr, std::vector<Store_Info> *Stores, std::vect
190196
}
191197
}
192198

199+
static User *GetUniqueUser(Value *V) {
200+
if (V->user_begin() != V->user_end()) {
201+
if (std::next(V->user_begin()) == V->user_end())
202+
return *V->user_begin();
203+
}
204+
return nullptr;
205+
}
206+
193207
static Value *GetOrCreatePreserveCond(Function *F) {
194208
assert(!F->isDeclaration());
195209

196210
Module *M = F->getParent();
197211
GlobalVariable *GV = M->getGlobalVariable(kPreserveName, true);
198212
if (!GV) {
199213
Type *i32Ty = Type::getInt32Ty(M->getContext());
214+
Type *i32ArrayTy = ArrayType::get(i32Ty, 1);
215+
216+
unsigned int Values[1] = { 0 };
217+
Constant *InitialValue = llvm::ConstantDataArray::get(M->getContext(), Values);
218+
200219
GV = new GlobalVariable(*M,
201-
i32Ty, true,
220+
i32ArrayTy, true,
202221
llvm::GlobalValue::InternalLinkage,
203-
llvm::ConstantInt::get(i32Ty, 0), kPreserveName);
222+
InitialValue, kPreserveName);
204223
}
205224

206225
for (User *U : GV->users()) {
207-
LoadInst *LI = cast<LoadInst>(U);
208-
if (LI->getParent()->getParent() == F) {
209-
assert(LI->user_begin() != LI->user_end() &&
210-
std::next(LI->user_begin()) == LI->user_end());
211-
212-
return *LI->user_begin();
226+
GEPOperator *Gep = Gep = cast<GEPOperator>(U);
227+
for (User *GepU : Gep->users()) {
228+
LoadInst *LI = cast<LoadInst>(GepU);
229+
if (LI->getParent()->getParent() == F) {
230+
return GetUniqueUser(LI);
231+
}
213232
}
214233
}
215234

@@ -220,7 +239,8 @@ static Value *GetOrCreatePreserveCond(Function *F) {
220239

221240
IRBuilder<> B(InsertPt);
222241

223-
LoadInst *Load = B.CreateLoad(GV);
242+
Constant *Gep = GetConstGep(GV, 0, 0);
243+
LoadInst *Load = B.CreateLoad(Gep);
224244
return B.CreateTrunc(Load, B.getInt1Ty());
225245
}
226246

@@ -461,18 +481,24 @@ class DxilFinalizePreserves : public ModulePass {
461481
}
462482

463483
Instruction *GetFinalNoopInst(Module &M, Instruction *InsertBefore) {
484+
Type *i32Ty = Type::getInt32Ty(M.getContext());
464485
if (!NothingGV) {
465486
NothingGV = M.getGlobalVariable(kNothingName);
466487
if (!NothingGV) {
467-
Type *i32Ty = Type::getInt32Ty(M.getContext());
488+
Type *i32ArrayTy = ArrayType::get(i32Ty, 1);
489+
490+
unsigned int Values[1] = { 0 };
491+
Constant *InitialValue = llvm::ConstantDataArray::get(M.getContext(), Values);
492+
468493
NothingGV = new GlobalVariable(M,
469-
i32Ty, true,
494+
i32ArrayTy, true,
470495
llvm::GlobalValue::InternalLinkage,
471-
llvm::ConstantInt::get(i32Ty, 0), kNothingName);
496+
InitialValue, kNothingName);
472497
}
473498
}
474499

475-
return new llvm::LoadInst(NothingGV, nullptr, InsertBefore);
500+
Constant *Gep = GetConstGep(NothingGV, 0, 0);
501+
return new llvm::LoadInst(Gep, nullptr, InsertBefore);
476502
}
477503

478504
bool LowerPreserves(Module &M);
@@ -491,20 +517,23 @@ bool DxilFinalizePreserves::LowerPreserves(Module &M) {
491517
GlobalVariable *GV = M.getGlobalVariable(kPreserveName, true);
492518
if (GV) {
493519
for (User *U : GV->users()) {
494-
LoadInst *LI = cast<LoadInst>(U);
495-
assert(LI->user_begin() != LI->user_end() &&
496-
std::next(LI->user_begin()) == LI->user_end());
497-
Instruction *I = cast<Instruction>(*LI->user_begin());
498-
499-
for (User *UU : I->users()) {
500-
501-
SelectInst *P = cast<SelectInst>(UU);
502-
Value *PrevV = P->getTrueValue();
503-
Value *CurV = P->getFalseValue();
504-
505-
if (isa<UndefValue>(PrevV) || isa<Constant>(PrevV)) {
506-
P->setOperand(1, CurV);
507-
Changed = true;
520+
GEPOperator *Gep = cast<GEPOperator>(U);
521+
for (User *GepU : Gep->users()) {
522+
LoadInst *LI = cast<LoadInst>(GepU);
523+
assert(LI->user_begin() != LI->user_end() &&
524+
std::next(LI->user_begin()) == LI->user_end());
525+
Instruction *I = cast<Instruction>(*LI->user_begin());
526+
527+
for (User *UU : I->users()) {
528+
529+
SelectInst *P = cast<SelectInst>(UU);
530+
Value *PrevV = P->getTrueValue();
531+
Value *CurV = P->getFalseValue();
532+
533+
if (isa<UndefValue>(PrevV) || isa<Constant>(PrevV)) {
534+
P->setOperand(1, CurV);
535+
Changed = true;
536+
}
508537
}
509538
}
510539
}
888 Bytes
Binary file not shown.
1012 Bytes
Binary file not shown.
756 Bytes
Binary file not shown.

tools/clang/test/HLSLFileCheck/dxil/debug/noop_no_fold_double.hlsl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ Texture2D tex1 : register(t1);
77

88
[RootSignature("DescriptorTable(SRV(t0), SRV(t1))")]
99
float4 main() : SV_Target {
10-
// CHECK: %[[p_load:[0-9]+]] = load i32, i32* @dx.preserve.value
10+
// CHECK: %[[p_load:[0-9]+]] = load i32, i32*
11+
// CHECK-SAME: @dx.preserve.value
1112
// CHECK: %[[p:[0-9]+]] = trunc i32 %[[p_load]] to i1
1213

1314
double x = 10;
@@ -26,12 +27,14 @@ float4 main() : SV_Target {
2627
// select i1 %[[p]], double [[c1]], double [[c1]]
2728

2829
Texture2D tex = tex0;
29-
// CHECK: load i32, i32* @dx.nothing
30+
// CHECK: load i32, i32*
31+
// CHECK-SAME: @dx.nothing
3032

3133
// CHECK: br i1
3234
if (w >= 0) {
3335
tex = tex1;
34-
// CHECK: load i32, i32* @dx.nothing
36+
// CHECK: load i32, i32*
37+
// CHECK-SAME: @dx.nothing
3538
// CHECK: br
3639
}
3740

tools/clang/test/HLSLFileCheck/dxil/debug/noop_no_fold_int.hlsl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ Texture2D tex1 : register(t1);
77

88
[RootSignature("DescriptorTable(SRV(t0), SRV(t1))")]
99
float4 main() : SV_Target {
10-
// CHECK: %[[p_load:[0-9]+]] = load i32, i32* @dx.preserve.value
10+
// CHECK: %[[p_load:[0-9]+]] = load i32, i32*
11+
// CHECK-SAME: @dx.preserve.value
1112
// CHECK: %[[p:[0-9]+]] = trunc i32 %[[p_load]] to i1
1213

1314
int x = 10;
@@ -28,12 +29,14 @@ float4 main() : SV_Target {
2829
// select i1 %[[p]], i32 [[c1]], i32 [[c1]]
2930

3031
Texture2D tex = tex0;
31-
// CHECK: load i32, i32* @dx.nothing
32+
// CHECK: load i32, i32*
33+
// CHECK-SAME: @dx.nothing
3234

3335
// CHECK: br i1
3436
if (w >= 0) {
3537
tex = tex1;
36-
// CHECK: load i32, i32* @dx.nothing
38+
// CHECK: load i32, i32*
39+
// CHECK-SAME: @dx.nothing
3740
// CHECK: br
3841
}
3942

tools/clang/test/HLSLFileCheck/dxil/debug/noop_out_args.hlsl

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,28 +25,35 @@ void baz(inout float x, inout float y) {
2525

2626
[RootSignature("")]
2727
float main() : SV_Target {
28-
// CHECK: %[[p_load:[0-9]+]] = load i32, i32* @dx.preserve.value
28+
// CHECK: %[[p_load:[0-9]+]] = load i32, i32*
29+
// CHECK-SAME: @dx.preserve.value
2930
// CHECK: %[[p:[0-9]+]] = trunc i32 %[[p_load]] to i1
3031

3132
S s;
3233

33-
// CHECK: load i32, i32* @dx.nothing
34+
// CHECK: load i32, i32*
35+
// CHECK: @dx.nothing
3436
foo(s);
3537
// CHECK: select i1 %[[p]]
3638
// CHECK: select i1 %[[p]]
37-
// CHECK: load i32, i32* @dx.nothing
39+
// CHECK: load i32, i32*
40+
// CHECK: @dx.nothing
3841

39-
// CHECK: load i32, i32* @dx.nothing
42+
// CHECK: load i32, i32*
43+
// CHECK: @dx.nothing
4044
bar(s);
4145
// CHECK: fmul
4246
// CHECK: fmul
43-
// CHECK: load i32, i32* @dx.nothing
47+
// CHECK: load i32, i32*
48+
// CHECK: @dx.nothing
4449

45-
// CHECK: load i32, i32* @dx.nothing
50+
// CHECK: load i32, i32*
51+
// CHECK: @dx.nothing
4652
baz(s.x, s.y);
4753
// CHECK: fmul
4854
// CHECK: fmul
49-
// CHECK: load i32, i32* @dx.nothing
55+
// CHECK: load i32, i32*
56+
// CHECK: @dx.nothing
5057

5158
// CHECK: fadd
5259
return s.x + s.y;

tools/clang/test/HLSLFileCheck/dxil/debug/noop_resource_var.hlsl

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,25 @@ void store_things() {
1919
[numthreads(1, 1, 1)]
2020
[RootSignature("CBV(b0), DescriptorTable(UAV(u0))")]
2121
void main() {
22-
// CHECK: %[[p_load:[0-9]+]] = load i32, i32* @dx.preserve.value
22+
// CHECK: %[[p_load:[0-9]+]] = load i32, i32*
23+
// CHECK-SAME: @dx.preserve.value
2324
// CHECK: %[[p:[0-9]+]] = trunc i32 %[[p_load]] to i1
2425

25-
// CHECK: load i32, i32* @dx.nothing
26+
// CHECK: load i32, i32*
27+
// CHECK: @dx.nothing
2628
my_uav = uav;
2729

2830
// select i1 [[p]],
2931
float ret = foo;
3032

31-
// CHECK: load i32, i32* @dx.nothing
33+
// CHECK: load i32, i32*
34+
// CHECK: @dx.nothing
3235
store_things();
3336
// CHECK: unary.f32(i32 13
34-
// CHECK: load i32, i32* @dx.nothing
35-
// CHECK: load i32, i32* @dx.nothing
37+
// CHECK: load i32, i32*
38+
// CHECK: @dx.nothing
39+
// CHECK: load i32, i32*
40+
// CHECK: @dx.nothing
3641
// CHECK: call void @dx.op.bufferStore.f32(
3742

3843
// CHECK: call void @dx.op.bufferStore.f32(

tools/clang/test/HLSLFileCheck/dxil/debug/noop_void_return.hlsl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@ void foo() {
99

1010
[RootSignature("")]
1111
float main() : SV_Target {
12-
// CHECK: %[[p_load:[0-9]+]] = load i32, i32* @dx.preserve.value
12+
// CHECK: %[[p_load:[0-9]+]] = load i32, i32*
13+
// CHECK-SAME: @dx.preserve.value
1314
// CHECK: %[[p:[0-9]+]] = trunc i32 %[[p_load]] to i1
1415

1516
// CHECK: select i1 %[[p]]
1617
my_glob = 0;
1718

1819
// Function call
19-
// CHECK: load i32, i32* @dx.nothing
20+
// CHECK: load i32, i32*
21+
// CHECK: @dx.nothing
2022
foo();
2123
// CHECK: select i1 %[[p]]
2224
// void return

tools/clang/test/HLSLFileCheck/dxil/debug/noops_call.hlsl

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,16 @@ float4 depth2(float4 val)
6060
return val;
6161
}
6262

63-
// CHECK: @dx.nothing = internal constant i32 0
64-
6563
[RootSignature("")]
6664
float4 main( float4 unused : SV_POSITION, float4 color : COLOR ) : SV_Target
6765
{
68-
// CHECK: %[[p_load:[0-9]+]] = load i32, i32* @dx.preserve.value
66+
// CHECK: %[[p_load:[0-9]+]] = load i32, i32*
67+
// CHECK-SAME: @dx.preserve.value
6968
// CHECK: %[[p:[0-9]+]] = trunc i32 %[[p_load]] to i1
7069
float4 ret1 = localScopeVar_func(color);
7170
// ** call **
72-
// CHECK: load i32, i32* @dx.nothing
71+
// CHECK: load i32, i32*
72+
// CHECK-SAME: @dx.nothing
7373
// CHECK: %[[v1:.+]] = fmul
7474
// CHECK: %[[v2:.+]] = fmul
7575
// CHECK: %[[v3:.+]] = fmul
@@ -82,7 +82,8 @@ float4 main( float4 unused : SV_POSITION, float4 color : COLOR ) : SV_Target
8282

8383
float4 ret2 = localRegVar_func(ret1);
8484
// ** call **
85-
// CHECK: load i32, i32* @dx.nothing
85+
// CHECK: load i32, i32*
86+
// CHECK-SAME: @dx.nothing
8687
// ** copy **
8788
// CHECK: select i1 %[[p]],
8889
// CHECK: select i1 %[[p]],
@@ -92,7 +93,8 @@ float4 main( float4 unused : SV_POSITION, float4 color : COLOR ) : SV_Target
9293

9394
float4 ret3 = array_func(ret2);
9495
// ** call **
95-
// CHECK: load i32, i32* @dx.nothing
96+
// CHECK: load i32, i32*
97+
// CHECK-SAME: @dx.nothing
9698
// CHECK: store
9799
// CHECK: store
98100
// CHECK: store
@@ -105,7 +107,8 @@ float4 main( float4 unused : SV_POSITION, float4 color : COLOR ) : SV_Target
105107

106108
float4 ret4 = typedef_func(ret3);
107109
// ** call **
108-
// CHECK: load i32, i32* @dx.nothing
110+
// CHECK: load i32, i32*
111+
// CHECK-SAME: @dx.nothing
109112
// ** copy **
110113
// CHECK: select i1 %[[p]], float %{{.+}}
111114
// CHECK: select i1 %[[p]], float %{{.+}}
@@ -115,7 +118,8 @@ float4 main( float4 unused : SV_POSITION, float4 color : COLOR ) : SV_Target
115118

116119
float4 ret5 = global_func(ret4);
117120
// ** call **
118-
// CHECK: load i32, i32* @dx.nothing
121+
// CHECK: load i32, i32*
122+
// CHECK-SAME: @dx.nothing
119123
// CHECK: %[[a1:.+]] = fmul
120124
// CHECK: %[[a2:.+]] = fmul
121125
// CHECK: %[[a3:.+]] = fmul
@@ -128,25 +132,30 @@ float4 main( float4 unused : SV_POSITION, float4 color : COLOR ) : SV_Target
128132

129133
float4 ret6 = depth2(ret5);
130134
// ** call **
131-
// CHECK: load i32, i32* @dx.nothing
135+
// CHECK: load i32, i32*
136+
// CHECK-SAME: @dx.nothing
132137
// depth2() {
133138
// ** call **
134-
// CHECK: load i32, i32* @dx.nothing
139+
// CHECK: load i32, i32*
140+
// CHECK-SAME: @dx.nothing
135141
// depth3() {
136142
// ** call **
137-
// CHECK: load i32, i32* @dx.nothing
143+
// CHECK: load i32, i32*
144+
// CHECK-SAME: @dx.nothing
138145
// depth4() {
139146
// CHECK: %[[b1:.+]] = fmul
140147
// CHECK: %[[b2:.+]] = fmul
141148
// CHECK: %[[b3:.+]] = fmul
142149
// CHECK: %[[b4:.+]] = fmul
143-
// CHECK: load i32, i32* @dx.nothing
150+
// CHECK: load i32, i32*
151+
// CHECK-SAME: @dx.nothing
144152
// }
145153
// CHECK: %[[c1:.+]] = fmul
146154
// CHECK: %[[c2:.+]] = fmul
147155
// CHECK: %[[c3:.+]] = fmul
148156
// CHECK: %[[c4:.+]] = fmul
149-
// CHECK: load i32, i32* @dx.nothing
157+
// CHECK: load i32, i32*
158+
// CHECK-SAME: @dx.nothing
150159
// }
151160
// CHECK: %[[d1:.+]] = fmul
152161
// CHECK: %[[d2:.+]] = fmul

0 commit comments

Comments
 (0)