Skip to content

Commit 485c8c7

Browse files
FznamznonAlexeySotkin
authored andcommitted
Map OpVariable to LLVM value before initializer translation
When some global variable contains constant function pointer to a function and this global variable is referenced from the pointed function, translation crashed because intializer for global variable was translated before mapping of OpVariable to LLVM value. It happened because during translation of initializer in such case the original variable was met for the second time, but it wasn't mapped to a proper llvm value.
1 parent 091c366 commit 485c8c7

File tree

4 files changed

+69
-29
lines changed

4 files changed

+69
-29
lines changed

lib/SPIRV/SPIRVReader.cpp

+19-19
Original file line numberDiff line numberDiff line change
@@ -1669,41 +1669,41 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
16691669
bool IsConst = BVar->isConstant();
16701670
llvm::GlobalValue::LinkageTypes LinkageTy = transLinkageType(BVar);
16711671
SPIRVStorageClassKind BS = BVar->getStorageClass();
1672-
Constant *Initializer = nullptr;
16731672
SPIRVValue *Init = BVar->getInitializer();
1674-
if (Init)
1675-
Initializer = dyn_cast<Constant>(transValue(Init, F, BB, false));
1676-
else if (LinkageTy == GlobalValue::CommonLinkage)
1677-
// In LLVM, variables with common linkage type must be initialized to 0.
1678-
Initializer = Constant::getNullValue(Ty);
1679-
else if (BS == SPIRVStorageClassKind::StorageClassWorkgroup)
1680-
Initializer = dyn_cast<Constant>(UndefValue::get(Ty));
1681-
else if ((LinkageTy != GlobalValue::ExternalLinkage) &&
1682-
(BS == SPIRVStorageClassKind::StorageClassCrossWorkgroup))
1683-
Initializer = Constant::getNullValue(Ty);
1684-
16851673
if (BS == StorageClassFunction && !Init) {
16861674
assert(BB && "Invalid BB");
16871675
return mapValue(BV, new AllocaInst(Ty, 0, BV->getName(), BB));
16881676
}
1689-
SPIRAddressSpace AddrSpace;
16901677

1678+
SPIRAddressSpace AddrSpace;
16911679
bool IsVectorCompute =
16921680
BVar->hasDecorate(DecorationVectorComputeVariableINTEL);
1681+
Constant *Initializer = nullptr;
16931682
if (IsVectorCompute) {
16941683
AddrSpace = VectorComputeUtil::getVCGlobalVarAddressSpace(BS);
1695-
if (!Initializer)
1696-
Initializer = UndefValue::get(Ty);
1684+
Initializer = UndefValue::get(Ty);
16971685
} else
16981686
AddrSpace = SPIRSPIRVAddrSpaceMap::rmap(BS);
1699-
1700-
auto LVar = new GlobalVariable(*M, Ty, IsConst, LinkageTy, Initializer,
1701-
BV->getName(), 0,
1687+
auto LVar = new GlobalVariable(*M, Ty, IsConst, LinkageTy,
1688+
/*Initializer=*/nullptr, BV->getName(), 0,
17021689
GlobalVariable::NotThreadLocal, AddrSpace);
1690+
auto Res = mapValue(BV, LVar);
1691+
if (Init)
1692+
Initializer = dyn_cast<Constant>(transValue(Init, F, BB, false));
1693+
else if (LinkageTy == GlobalValue::CommonLinkage)
1694+
// In LLVM, variables with common linkage type must be initialized to 0.
1695+
Initializer = Constant::getNullValue(Ty);
1696+
else if (BS == SPIRVStorageClassKind::StorageClassWorkgroup)
1697+
Initializer = dyn_cast<Constant>(UndefValue::get(Ty));
1698+
else if ((LinkageTy != GlobalValue::ExternalLinkage) &&
1699+
(BS == SPIRVStorageClassKind::StorageClassCrossWorkgroup))
1700+
Initializer = Constant::getNullValue(Ty);
1701+
17031702
LVar->setUnnamedAddr((IsConst && Ty->isArrayTy() &&
17041703
Ty->getArrayElementType()->isIntegerTy(8))
17051704
? GlobalValue::UnnamedAddr::Global
17061705
: GlobalValue::UnnamedAddr::None);
1706+
LVar->setInitializer(Initializer);
17071707

17081708
if (IsVectorCompute) {
17091709
LVar->addAttribute(kVCMetadata::VCGlobalVariable);
@@ -1717,7 +1717,7 @@ Value *SPIRVToLLVM::transValueWithoutDecoration(SPIRVValue *BV, Function *F,
17171717
SPIRVBuiltinVariableKind BVKind;
17181718
if (BVar->isBuiltin(&BVKind))
17191719
BuiltinGVMap[LVar] = BVKind;
1720-
return mapValue(BV, LVar);
1720+
return Res;
17211721
}
17221722

17231723
case OpVariableLengthArrayINTEL: {

test/transcoding/PipeStorage.ll

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
; RUN: llvm-spirv -r %t.spv -o %t.rev.bc
66
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
77

8-
; CHECK-LLVM: %spirv.ConstantPipeStorage = type { i32, i32, i32 }
9-
; CHECK-LLVM: %"[[CL_PIPE_STORAGE_NAME:[^"]+]]" = type { %spirv.PipeStorage addrspace(1)* }
10-
; CHECK-LLVM: %spirv.PipeStorage = type opaque
11-
; CHECK-LLVM: [[CREATOR_NAME:[^ ]+]] = linkonce_odr addrspace(1) global %spirv.ConstantPipeStorage { i32 16, i32 16, i32 1 }, align 4
12-
; CHECK-LLVM: @mygpipe = addrspace(1) global %"[[CL_PIPE_STORAGE_NAME]]" { %spirv.PipeStorage addrspace(1)* bitcast (%spirv.ConstantPipeStorage addrspace(1)* [[CREATOR_NAME]] to %spirv.PipeStorage addrspace(1)*) }, align 4
8+
; CHECK-LLVM-DAG: %spirv.ConstantPipeStorage = type { i32, i32, i32 }
9+
; CHECK-LLVM-DAG: %"[[CL_PIPE_STORAGE_NAME:[^"]+]]" = type { %spirv.PipeStorage addrspace(1)* }
10+
; CHECK-LLVM-DAG: %spirv.PipeStorage = type opaque
11+
; CHECK-LLVM-DAG: [[CREATOR_NAME:[^ ]+]] = linkonce_odr addrspace(1) global %spirv.ConstantPipeStorage { i32 16, i32 16, i32 1 }, align 4
12+
; CHECK-LLVM-DAG: @mygpipe = addrspace(1) global %"[[CL_PIPE_STORAGE_NAME]]" { %spirv.PipeStorage addrspace(1)* bitcast (%spirv.ConstantPipeStorage addrspace(1)* [[CREATOR_NAME]] to %spirv.PipeStorage addrspace(1)*) }, align 4
1313

1414
; check for magic number followed by version 1.1
1515
; CHECK-SPIRV: 119734787 65792

test/transcoding/PipeStorageIOINTEL.ll

+5-5
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
; RUN: llvm-spirv -spirv-text -r %t.spt -o %t.rev.bc
1010
; RUN: llvm-dis < %t.rev.bc | FileCheck %s --check-prefix=CHECK-LLVM
1111

12-
; CHECK-LLVM: %spirv.ConstantPipeStorage = type { i32, i32, i32 }
13-
; CHECK-LLVM: %"[[CL_PIPE_STORAGE_NAME:[^"]+]]" = type { %spirv.PipeStorage addrspace(1)* }
14-
; CHECK-LLVM: %spirv.PipeStorage = type opaque
15-
; CHECK-LLVM: [[CREATOR_NAME:[^ ]+]] = linkonce_odr addrspace(1) global %spirv.ConstantPipeStorage { i32 16, i32 16, i32 1 }, align 4
16-
; CHECK-LLVM: @mygpipe = addrspace(1) global %"[[CL_PIPE_STORAGE_NAME]]" { %spirv.PipeStorage addrspace(1)* bitcast (%spirv.ConstantPipeStorage addrspace(1)* [[CREATOR_NAME]] to %spirv.PipeStorage addrspace(1)*) }, align 4, !io_pipe_id ![[IO_MD:[0-9]+]]
12+
; CHECK-LLVM-DAG: %spirv.ConstantPipeStorage = type { i32, i32, i32 }
13+
; CHECK-LLVM-DAG: %"[[CL_PIPE_STORAGE_NAME:[^"]+]]" = type { %spirv.PipeStorage addrspace(1)* }
14+
; CHECK-LLVM-DAG: %spirv.PipeStorage = type opaque
15+
; CHECK-LLVM-DAG: [[CREATOR_NAME:[^ ]+]] = linkonce_odr addrspace(1) global %spirv.ConstantPipeStorage { i32 16, i32 16, i32 1 }, align 4
16+
; CHECK-LLVM-DAG: @mygpipe = addrspace(1) global %"[[CL_PIPE_STORAGE_NAME]]" { %spirv.PipeStorage addrspace(1)* bitcast (%spirv.ConstantPipeStorage addrspace(1)* [[CREATOR_NAME]] to %spirv.PipeStorage addrspace(1)*) }, align 4, !io_pipe_id ![[IO_MD:[0-9]+]]
1717
; CHECK-LLVM: ![[IO_MD]] = !{i32 1}
1818

1919
; CHECK-SPIRV: 2 Capability PipeStorage
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
; RUN: llvm-as %s -o %t.bc
2+
; RUN: llvm-spirv %t.bc -spirv-ext=+SPV_INTEL_function_pointers -o %t.spv
3+
; RUN: llvm-spirv -r %t.spv -o %t.r.bc
4+
; RUN: llvm-dis %t.r.bc -o %t.r.ll
5+
; RUN: FileCheck < %t.r.ll %s --check-prefix=CHECK-LLVM
6+
7+
; ModuleID = 't.bc'
8+
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024"
9+
target triple = "spir64-unknown-unknown"
10+
11+
%structtype.3 = type { [1 x i8 addrspace(4)*] }
12+
13+
; CHECK-LLVM: @A = addrspace(1) constant %structtype.3 { [1 x i8 addrspace(4)*] [i8 addrspace(4)* addrspacecast (i8* bitcast (void ()* @foo to i8*) to i8 addrspace(4)*)] }, align 8
14+
15+
@A = linkonce_odr addrspace(1) constant %structtype.3 { [1 x i8 addrspace(4)*] [i8 addrspace(4)* addrspacecast (i8* bitcast (void ()* @foo to i8*) to i8 addrspace(4)*)] }, align 8
16+
17+
; Function Attrs: nounwind
18+
define linkonce_odr spir_func void @foo() #0 {
19+
entry:
20+
; CHECK-LLVM: %0 = getelementptr inbounds %structtype.3, %structtype.3 addrspace(1)* @A, i64 0, i32 0, i64 2
21+
%0 = getelementptr inbounds %structtype.3, %structtype.3 addrspace(1)* @A, i64 0, i32 0, i64 2
22+
ret void
23+
}
24+
25+
attributes #0 = { nounwind }
26+
27+
!spirv.MemoryModel = !{!0}
28+
!spirv.Source = !{!1}
29+
!opencl.spir.version = !{!2}
30+
!opencl.ocl.version = !{!2}
31+
!opencl.used.extensions = !{!3}
32+
!opencl.used.optional.core.features = !{!4}
33+
!spirv.Generator = !{!5}
34+
35+
!0 = !{i32 2, i32 2}
36+
!1 = !{i32 4, i32 200000}
37+
!2 = !{i32 2, i32 0}
38+
!3 = !{!"cl_khr_int64_extended_atomics", !"cl_khr_subgroups"}
39+
!4 = !{!"cl_doubles"}
40+
!5 = !{i16 6, i16 14}

0 commit comments

Comments
 (0)