Skip to content

Commit c623ec4

Browse files
wenju-hevmaksimo
authored andcommitted
Fix global ctor/dtor translation from SPIRV to LLVM IR
Translate global variable if its storage is StorageClassFunction and its name is either llvm.global_ctors or llvm.global_dtors. Apply appending linkage to the global variable. SPV_INTEL_function_pointers extension is required for the translation.
1 parent 4643f5b commit c623ec4

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3309,6 +3309,8 @@ bool SPIRVToLLVM::translate() {
33093309
auto BV = BM->getVariable(I);
33103310
if (BV->getStorageClass() != StorageClassFunction)
33113311
transValue(BV, nullptr, nullptr);
3312+
else
3313+
transGlobalCtorDtors(BV);
33123314
}
33133315

33143316
// Compile unit might be needed during translation of debug intrinsics.
@@ -3651,6 +3653,15 @@ bool SPIRVToLLVM::transDecoration(SPIRVValue *BV, Value *V) {
36513653
return true;
36523654
}
36533655

3656+
void SPIRVToLLVM::transGlobalCtorDtors(SPIRVVariable *BV) {
3657+
if (BV->getName() != "llvm.global_ctors" &&
3658+
BV->getName() != "llvm.global_dtors")
3659+
return;
3660+
3661+
Value *V = transValue(BV, nullptr, nullptr);
3662+
cast<GlobalValue>(V)->setLinkage(GlobalValue::AppendingLinkage);
3663+
}
3664+
36543665
bool SPIRVToLLVM::transFPContractMetadata() {
36553666
bool ContractOff = false;
36563667
for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) {

llvm-spirv/lib/SPIRV/SPIRVReader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ class SPIRVToLLVM {
270270

271271
void transUserSemantic(SPIRV::SPIRVFunction *Fun);
272272
void transGlobalAnnotations();
273+
void transGlobalCtorDtors(SPIRVVariable *BV);
273274
void transIntelFPGADecorations(SPIRVValue *BV, Value *V);
274275
}; // class SPIRVToLLVM
275276

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_function_pointers -spirv-text -o - | FileCheck %s
3+
; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_INTEL_function_pointers -o %t.spv
4+
; RUN: llvm-spirv -r %t.spv
5+
6+
target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64"
7+
target triple = "spir64-unknown-unknown"
8+
9+
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_test.cpp.ctor, i8* null }]
10+
@llvm.global_dtors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_test.cpp.dtor, i8* null }]
11+
@_ZL15DIVERGENCE = internal addrspace(1) global i32 0, align 4
12+
13+
; CHECK: Name [[NameCtor:[0-9]+]] "_GLOBAL__sub_I_test.cpp.ctor"
14+
; CHECK: Name [[Name1:[0-9]+]] "llvm.global_ctors"
15+
; CHECK: Name [[NameDtor:[0-9]+]] "_GLOBAL__sub_I_test.cpp.dtor"
16+
; CHECK: Name [[Name2:[0-9]+]] "llvm.global_dtors"
17+
; CHECK: Name [[NameInit:[0-9]+]] "__cxx_global_var_init"
18+
19+
; CHECK: LinkageAttributes "llvm.global_ctors" Export
20+
; CHECK: LinkageAttributes "llvm.global_dtors" Export
21+
22+
; CHECK: TypeFunction {{[0-9]+}} [[TF:[0-9]+]]
23+
24+
; CHECK: TypePointer [[TP:[0-9]+]]
25+
; CHECK: ConstFunctionPointerINTEL [[TP]] [[FPCtor:[0-9]+]] [[NameCtor]]
26+
; CHECK: ConstantComposite {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} [[FPCtor]]
27+
; CHECK: ConstFunctionPointerINTEL [[TP]] [[FPDtor:[0-9]+]] [[NameDtor]]
28+
; CHECK: ConstantComposite {{[0-9]+}} {{[0-9]+}} {{[0-9]+}} [[FPDtor]]
29+
30+
; CHECK: 5 Function [[TF]] [[NameCtor]] 0
31+
; CHECK-EMPTY:
32+
; CHECK-NEXT: Label {{[0-9]+}}
33+
; CHECK-NEXT: FunctionCall {{[0-9]+}} {{[0-9]+}} [[NameInit]]
34+
; CHECK-NEXT: Return
35+
; CHECK-EMPTY:
36+
; CHECK-NEXT: FunctionEnd
37+
38+
; Function Attrs: nounwind sspstrong
39+
define internal void @_GLOBAL__sub_I_test.cpp.ctor() #0 {
40+
call void @__cxx_global_var_init()
41+
ret void
42+
}
43+
44+
; Function Attrs: nounwind sspstrong
45+
define internal void @__cxx_global_var_init() #0 {
46+
store i32 0, i32 addrspace(4)* addrspacecast (i32 addrspace(1)* @_ZL15DIVERGENCE to i32 addrspace(4)*), align 4
47+
ret void
48+
}
49+
50+
; CHECK: 5 Function [[TF]] [[NameDtor]] 0
51+
; CHECK-EMPTY:
52+
; CHECK-NEXT: Label {{[0-9]+}}
53+
; CHECK-NEXT: Return
54+
; CHECK-EMPTY:
55+
; CHECK-NEXT: FunctionEnd
56+
57+
; Function Attrs: nounwind sspstrong
58+
define internal void @_GLOBAL__sub_I_test.cpp.dtor() #0 {
59+
ret void
60+
}
61+
62+
; Ctor/dtor functions should not be serialized twice.
63+
; CHECK-NOT: 5 Function [[TF]] [[NameCtor]] 0
64+
; CHECK-NOT: 5 Function [[TF]] [[NameDtor]] 0
65+
66+
attributes #0 = { nounwind sspstrong "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
67+
68+
!opencl.spir.version = !{!0}
69+
!opencl.used.extensions = !{!1}
70+
!opencl.used.optional.core.features = !{!1}
71+
!opencl.compiler.options = !{!1}
72+
73+
!0 = !{i32 1, i32 2}
74+
!1 = !{}

0 commit comments

Comments
 (0)