Skip to content

Commit 2a247a4

Browse files
authored
Avoid duplication of builtin global variables (#2480)
Add logic to emit only one global variable when both SPIRV builtin and OCL builtin variants are present in the source code. Signed-off-by: Arvind Sudarsanam <[email protected]>
1 parent 0414482 commit 2a247a4

File tree

2 files changed

+53
-3
lines changed

2 files changed

+53
-3
lines changed

lib/SPIRV/SPIRVUtil.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,9 +2140,26 @@ bool lowerBuiltinCallsToVariables(Module *M) {
21402140
bool IsVec = F.getFunctionType()->getNumParams() > 0;
21412141
Type *GVType =
21422142
IsVec ? FixedVectorType::get(F.getReturnType(), 3) : F.getReturnType();
2143-
auto *BV = new GlobalVariable(
2144-
*M, GVType, /*isConstant=*/true, GlobalValue::ExternalLinkage, nullptr,
2145-
BuiltinVarName, 0, GlobalVariable::NotThreadLocal, SPIRAS_Input);
2143+
GlobalVariable *BV = nullptr;
2144+
// Consider the following LLVM IR:
2145+
// @__spirv_BuiltInLocalInvocationId = <Global constant>
2146+
// .....
2147+
// define spir_kernel void @kernel1(....) {
2148+
// %3 = tail call i64 @_Z12get_local_idj(i32 0)
2149+
// .....
2150+
// return void
2151+
// }
2152+
// During the OCLToSPIRV pass, the opencl call will get lowered to
2153+
// yet another global variable with the name
2154+
// '@__spirv_BuiltInLocalInvocationId'. In such a case, we would want to
2155+
// create only a single global variable with this name.
2156+
if (GlobalVariable *GV = M->getGlobalVariable(BuiltinVarName))
2157+
BV = GV;
2158+
else
2159+
BV = new GlobalVariable(*M, GVType, /*isConstant=*/true,
2160+
GlobalValue::ExternalLinkage, nullptr,
2161+
BuiltinVarName, 0, GlobalVariable::NotThreadLocal,
2162+
SPIRAS_Input);
21462163
for (auto *U : F.users()) {
21472164
auto *CI = dyn_cast<CallInst>(U);
21482165
assert(CI && "invalid instruction");

test/builtin_duplicate.ll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
;; This test checks if we generate a single builtin variable for the following
2+
;; LLVM IR.
3+
;; @__spirv_BuiltInLocalInvocationId - A global variable
4+
;; %3 = tail call i64 @_Z12get_local_idj(i32 0) - A function call
5+
6+
; RUN: llvm-as %s -o %t.bc
7+
; RUN: llvm-spirv %t.bc -o %t.spv
8+
; RUN: llvm-spirv %t.bc -spirv-text -o %t.txt
9+
; RUN: FileCheck < %t.txt %s --check-prefix=CHECK-SPIRV
10+
; RUN: spirv-val %t.spv
11+
12+
target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
13+
target triple = "spir-unknown-unknown"
14+
15+
%opencl.event_t = type opaque
16+
17+
; CHECK-SPIRV: {{[0-9]+}} Name {{[0-9]+}} "__spirv_BuiltInLocalInvocationId"
18+
; CHECK-SPIRV-NOT: {{[0-9]+}} Name {{[0-9]+}} "__spirv_BuiltInLocalInvocationId.1"
19+
20+
@__spirv_BuiltInLocalInvocationId = external dso_local local_unnamed_addr addrspace(1) constant <3 x i64>, align 32
21+
22+
declare spir_func i64 @_Z12get_local_idj(i32) local_unnamed_addr
23+
24+
; Function Attrs: nounwind
25+
define spir_kernel void @test_fn(i32 %a) {
26+
entry:
27+
%3 = tail call i64 @_Z12get_local_idj(i32 0)
28+
ret void
29+
}
30+
31+
!spirv.Source = !{!0}
32+
33+
!0 = !{i32 6, i32 100000}

0 commit comments

Comments
 (0)