Skip to content

Commit 5d2598f

Browse files
KorovinVladigcbot
authored andcommitted
Break constexprs before SLM resolution
The same constexpr which uses SLM var may be located in different kernels/function groups. This leads to an issue while trying to replace uses of the SLM variable since its user(constexpr) is the same for different kernels which makes impossible to use different offsets for the same SLM var. The solution is to get rid of constexprs since such issue is not possible with instructions.
1 parent db90e14 commit 5d2598f

File tree

2 files changed

+27
-22
lines changed

2 files changed

+27
-22
lines changed

IGC/VectorCompiler/lib/GenXCodeGen/GenXSLMResolution.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ SPDX-License-Identifier: MIT
3838
#include "GenXUtil.h"
3939

4040
#include "vc/Support/GenXDiagnostic.h"
41+
#include "vc/Utils/GenX/BreakConst.h"
4142
#include "vc/Utils/GenX/GlobalVariable.h"
4243
#include "vc/Utils/GenX/KernelInfo.h"
4344
#include "vc/Utils/General/Types.h"
@@ -123,16 +124,11 @@ static void lowerSlmInit(Instruction &I) {
123124

124125
static bool isUserInList(const User &U,
125126
const SmallPtrSetImpl<Function *> &FunctionSet) {
126-
if (auto *I = dyn_cast<Instruction>(&U)) {
127-
auto *F = I->getFunction();
128-
return FunctionSet.count(F);
129-
}
130-
IGC_ASSERT_MESSAGE(isa<Constant>(&U), "unexpected SLM variable user");
131-
// For constant user continue recursively traversing until instruction
132-
// is met.
133-
return llvm::any_of(U.users(), [&FunctionSet](const User *U) {
134-
return isUserInList(*U, FunctionSet);
135-
});
127+
auto *UserInst = dyn_cast<Instruction>(&U);
128+
if (!UserInst)
129+
return false;
130+
auto *F = UserInst->getFunction();
131+
return FunctionSet.count(F);
136132
}
137133

138134
static bool isBelongToKernel(const GlobalVariable &GV,
@@ -281,6 +277,11 @@ bool GenXSLMResolution::runOnModule(Module &M) {
281277
llvm::for_each(SLMInitToErase, [](Instruction *I) { I->eraseFromParent(); });
282278

283279
auto SLMVars = collectSLMVariables(M);
280+
if (!SLMVars.empty())
281+
for (auto &F : M.functions())
282+
Modified |=
283+
vc::breakConstantExprs(&F, vc::LegalizationStage::NotLegalized);
284+
284285
for (auto &F : M.functions())
285286
if (vc::isKernel(&F))
286287
Modified |= runForKernel(F, M, SLMVars);

IGC/VectorCompiler/test/GenXSLMResolution/cfg.ll

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,25 @@ define internal spir_func i32 @bar(i32 addrspace(3)* %arg) #1 {
3535
ret i32 %arg.ld
3636
}
3737

38-
; CHECK: define internal spir_func i32 @foo
39-
; CHECK: %bar.res = call spir_func i32 @bar(i32 addrspace(3)* getelementptr inbounds ([4 x i32], [4 x i32] addrspace(3)* inttoptr (i32 268435456 to [4 x i32] addrspace(3)*), i64 0, i64 1))
38+
; CHECK-LABEL: define internal spir_func i32 @foo
4039
define internal spir_func i32 @foo(i32 addrspace(3)* %arg) #1 {
40+
; CHECK: [[SPLIT_FOO:%[^ ]+]] = getelementptr inbounds [4 x i32], [4 x i32] addrspace(3)* inttoptr (i32 268435456 to [4 x i32] addrspace(3)*), i64 0, i64 1
41+
; CHECK: %bar.res = call spir_func i32 @bar(i32 addrspace(3)* [[SPLIT_FOO]])
4142
%arg.ld = load i32, i32 addrspace(3)* %arg, align 4
4243
%bar.res = call spir_func i32 @bar(i32 addrspace(3)* getelementptr inbounds ([4 x i32], [4 x i32] addrspace(3)* @SLM_GV, i64 0, i64 1))
4344
%res = add i32 %bar.res, %arg.ld
4445
ret i32 %res
4546
}
4647

47-
; CHECK: define internal spir_func i32 @f1
48-
; CHECK: %gv.p3 = getelementptr inbounds [4 x i32], [4 x i32] addrspace(3)* inttoptr (i32 268435456 to [4 x i32] addrspace(3)*), i64 0, i64 2
48+
; CHECK-LABEL: define internal spir_func i32 @f1
4949
define internal spir_func i32 @f1() #1 {
50+
; CHECK: %gv.p3 = getelementptr inbounds [4 x i32], [4 x i32] addrspace(3)* inttoptr (i32 268435456 to [4 x i32] addrspace(3)*), i64 0, i64 2
5051
%gv.p3 = getelementptr inbounds [4 x i32], [4 x i32] addrspace(3)* @SLM_GV, i64 0, i64 2
5152
%foo.res = call spir_func i32 @foo(i32 addrspace(3)* %gv.p3)
5253
ret i32 %foo.res
5354
}
5455

55-
; CHECK: define internal spir_func i32 @f2
56+
; CHECK-LABEL: define internal spir_func i32 @f2
5657
define internal spir_func i32 @f2() #1 {
5758
; CHECK: %gv.p3.0 = getelementptr inbounds [4 x i32], [4 x i32] addrspace(3)* inttoptr (i32 268435456 to [4 x i32] addrspace(3)*), i64 0, i64
5859
%gv.p3.0 = getelementptr inbounds [4 x i32], [4 x i32] addrspace(3)* @SLM_GV, i64 0, i64 0
@@ -71,7 +72,7 @@ define internal spir_func i32 @f2() #1 {
7172
ret i32 %sum.res
7273
}
7374

74-
; CHECK: define internal spir_func i32 @f0
75+
; CHECK-LABEL: define internal spir_func i32 @f0
7576
define internal spir_func i32 @f0(i32 addrspace(3)* %arg) #1 {
7677
%arg.ld = load i32, i32 addrspace(3)* %arg, align 4
7778

@@ -93,25 +94,28 @@ exit:
9394
ret i32 %f0.res
9495
}
9596

96-
; CHECK: define internal spir_func i32 @f3
97-
; CHECK: %bar.res = call spir_func i32 @bar(i32 addrspace(3)* getelementptr inbounds ([4 x i32], [4 x i32] addrspace(3)* inttoptr (i32 268435456 to [4 x i32] addrspace(3)*), i64 0, i64 0))
97+
; CHECK-LABEL: define internal spir_func i32 @f3
9898
define internal spir_func i32 @f3(i32 addrspace(3)* %arg) #1 {
99+
; CHECK: [[SPLIT_F3:%[^ ]+]] = getelementptr inbounds [4 x i32], [4 x i32] addrspace(3)* inttoptr (i32 64 to [4 x i32] addrspace(3)*), i64 0, i64 0
100+
; CHECK: %bar.res = call spir_func i32 @bar(i32 addrspace(3)* [[SPLIT_F3]])
99101
%bar.res = call spir_func i32 @bar(i32 addrspace(3)* getelementptr inbounds ([4 x i32], [4 x i32] addrspace(3)* @SLM_GV, i64 0, i64 0))
100102
%arg.ld = load i32, i32 addrspace(3)* %arg, align 4
101103
%sum = add i32 %bar.res, %arg.ld
102104
ret i32 %sum
103105
}
104106

105-
; CHECK: define dllexport spir_kernel void @kernelA
106-
; CHECK: %res = call spir_func i32 @f0(i32 addrspace(3)* getelementptr inbounds ([4 x i32], [4 x i32] addrspace(3)* inttoptr (i32 268435456 to [4 x i32] addrspace(3)*), i64 0, i64 0))
107+
; CHECK-LABEL: define dllexport spir_kernel void @kernelA
107108
define dllexport spir_kernel void @kernelA() #2 {
109+
; CHECK: [[SPLIT_KA:%[^ ]+]] = getelementptr inbounds [4 x i32], [4 x i32] addrspace(3)* inttoptr (i32 268435456 to [4 x i32] addrspace(3)*), i64 0, i64 0
110+
; CHECK: %res = call spir_func i32 @f0(i32 addrspace(3)* [[SPLIT_KA]])
108111
%res = call spir_func i32 @f0(i32 addrspace(3)* getelementptr inbounds ([4 x i32], [4 x i32] addrspace(3)* @SLM_GV, i64 0, i64 0))
109112
ret void
110113
}
111114

112-
; CHECK: define dllexport spir_kernel void @kernelB
113-
; CHECK: %res = call spir_func i32 @f3(i32 addrspace(3)* getelementptr inbounds ([4 x i32], [4 x i32] addrspace(3)* inttoptr (i32 64 to [4 x i32] addrspace(3)*), i64 0, i64 3))
115+
; CHECK-LABEL: define dllexport spir_kernel void @kernelB
114116
define dllexport spir_kernel void @kernelB() #2 {
117+
; CHECK: [[SPLIT_KB:%[^ ]+]] = getelementptr inbounds [4 x i32], [4 x i32] addrspace(3)* inttoptr (i32 64 to [4 x i32] addrspace(3)*), i64 0, i64 3
118+
; CHECK: %res = call spir_func i32 @f3(i32 addrspace(3)* [[SPLIT_KB]])
115119
%res = call spir_func i32 @f3(i32 addrspace(3)* getelementptr inbounds ([4 x i32], [4 x i32] addrspace(3)* @SLM_GV, i64 0, i64 3))
116120
ret void
117121
}

0 commit comments

Comments
 (0)