Skip to content

Commit b9d6231

Browse files
generate a name of an unnamed global variable for Instruction Selection (llvm#78293)
The goal of this PR is to fix the issue of global unnamed variables causing SPIR-V Backend code generation to crash: llvm#78278 The reason for the crash is that GlobalValue's getGlobalIdentifier() would fail for unnamed global variable when trying to access the first character of the name (see lib/IR/Globals.cpp:150). This leads to assert in Debug and undefined behaviour in Release builds. The proposed fix generates a name of an unnamed global variable as __unnamed_<unsigned number>, in a style of similar existing LLVM implementation (see lib/IR/Mangler.cpp:131). A new class member variable is added into `SPIRVInstructionSelector` class to keep track of the number we give to anonymous global values to generate the same name every time when this is needed. The patch adds a new LIT test with the smallest implementation of reproducer ll code.
1 parent fe0d16f commit b9d6231

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ class SPIRVInstructionSelector : public InstructionSelector {
5353
SPIRVGlobalRegistry &GR;
5454
MachineRegisterInfo *MRI;
5555

56+
/// We need to keep track of the number we give to anonymous global values to
57+
/// generate the same name every time when this is needed.
58+
mutable DenseMap<const GlobalValue *, unsigned> UnnamedGlobalIDs;
59+
5660
public:
5761
SPIRVInstructionSelector(const SPIRVTargetMachine &TM,
5862
const SPIRVSubtarget &ST,
@@ -1519,7 +1523,17 @@ bool SPIRVInstructionSelector::selectGlobalValue(
15191523
SPIRVType *ResType = GR.getOrCreateSPIRVPointerType(
15201524
PointerBaseType, I, TII,
15211525
addressSpaceToStorageClass(GV->getAddressSpace()));
1522-
std::string GlobalIdent = GV->getGlobalIdentifier();
1526+
1527+
std::string GlobalIdent;
1528+
if (!GV->hasName()) {
1529+
unsigned &ID = UnnamedGlobalIDs[GV];
1530+
if (ID == 0)
1531+
ID = UnnamedGlobalIDs.size();
1532+
GlobalIdent = "__unnamed_" + Twine(ID).str();
1533+
} else {
1534+
GlobalIdent = GV->getGlobalIdentifier();
1535+
}
1536+
15231537
// We have functions as operands in tests with blocks of instruction e.g. in
15241538
// transcoding/global_block.ll. These operands are not used and should be
15251539
// substituted by zero constants. Their type is expected to be always
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
2+
; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
3+
4+
; CHECK: %[[TyInt:.*]] = OpTypeInt 8 0
5+
; CHECK: %[[ConstInt:.*]] = OpConstant %[[TyInt]] 123
6+
; CHECK: %[[TyPtr:.*]] = OpTypePointer {{[a-zA-Z]+}} %[[TyInt]]
7+
; CHECK: %[[VarId:.*]] = OpVariable %[[TyPtr]] {{[a-zA-Z]+}} %[[ConstInt]]
8+
9+
@0 = addrspace(1) global i8 123
10+
11+
; Function Attrs: nounwind
12+
define spir_kernel void @foo() #0 {
13+
ret void
14+
}
15+
16+
attributes #0 = { nounwind }

0 commit comments

Comments
 (0)