Skip to content

Commit 486ea1e

Browse files
[SPIR-V] Fix pre-legalizer pass in SPIR-V Backend to support more gMIR opcode inserted by IRTranslator (#89890)
Translating global values, IRTranslator pass can sometimes generates code patterns that require additional efforts during pre-legalization. This PR addresses this problem to support G_PTRTOINT instruction used in initialization of GV.
1 parent 89d1255 commit 486ea1e

File tree

4 files changed

+66
-0
lines changed

4 files changed

+66
-0
lines changed

llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,37 @@ bool SPIRVInstructionSelector::selectUnOp(Register ResVReg,
646646
const SPIRVType *ResType,
647647
MachineInstr &I,
648648
unsigned Opcode) const {
649+
if (STI.isOpenCLEnv() && I.getOperand(1).isReg()) {
650+
Register SrcReg = I.getOperand(1).getReg();
651+
bool IsGV = false;
652+
for (MachineRegisterInfo::def_instr_iterator DefIt =
653+
MRI->def_instr_begin(SrcReg);
654+
DefIt != MRI->def_instr_end(); DefIt = std::next(DefIt)) {
655+
if ((*DefIt).getOpcode() == TargetOpcode::G_GLOBAL_VALUE) {
656+
IsGV = true;
657+
break;
658+
}
659+
}
660+
if (IsGV) {
661+
uint32_t SpecOpcode = 0;
662+
switch (Opcode) {
663+
case SPIRV::OpConvertPtrToU:
664+
SpecOpcode = static_cast<uint32_t>(SPIRV::Opcode::ConvertPtrToU);
665+
break;
666+
case SPIRV::OpConvertUToPtr:
667+
SpecOpcode = static_cast<uint32_t>(SPIRV::Opcode::ConvertUToPtr);
668+
break;
669+
}
670+
if (SpecOpcode)
671+
return BuildMI(*I.getParent(), I, I.getDebugLoc(),
672+
TII.get(SPIRV::OpSpecConstantOp))
673+
.addDef(ResVReg)
674+
.addUse(GR.getSPIRVTypeID(ResType))
675+
.addImm(SpecOpcode)
676+
.addUse(SrcReg)
677+
.constrainAllUses(TII, TRI, RBI);
678+
}
679+
}
649680
return selectUnOpWithSrc(ResVReg, ResType, I, I.getOperand(1).getReg(),
650681
Opcode);
651682
}

llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ static SPIRVType *propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR,
224224
}
225225
break;
226226
}
227+
case TargetOpcode::G_PTRTOINT:
228+
SpirvTy = GR->getOrCreateSPIRVIntegerType(
229+
MRI.getType(Reg).getScalarSizeInBits(), MIB);
230+
break;
227231
case TargetOpcode::G_TRUNC:
228232
case TargetOpcode::G_ADDRSPACE_CAST:
229233
case TargetOpcode::G_PTR_ADD:
@@ -441,6 +445,7 @@ static void generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
441445
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MRI);
442446
} else if (MI.getOpcode() == TargetOpcode::G_TRUNC ||
443447
MI.getOpcode() == TargetOpcode::G_ZEXT ||
448+
MI.getOpcode() == TargetOpcode::G_PTRTOINT ||
444449
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
445450
MI.getOpcode() == TargetOpcode::COPY ||
446451
MI.getOpcode() == TargetOpcode::G_ADDRSPACE_CAST) {

llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,3 +1612,5 @@ multiclass OpcodeOperand<bits<32> value> {
16121612
defm InBoundsPtrAccessChain : OpcodeOperand<70>;
16131613
defm PtrCastToGeneric : OpcodeOperand<121>;
16141614
defm Bitcast : OpcodeOperand<124>;
1615+
defm ConvertPtrToU : OpcodeOperand<117>;
1616+
defm ConvertUToPtr : OpcodeOperand<120>;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; This test is to check that correct virtual register type is created after ptrtoint.
2+
3+
; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
4+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
5+
6+
; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
7+
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
8+
9+
; CHECK: OpName %[[GlobalValue:.*]] "dev_global"
10+
; CHECK-DAG: %[[TyI64:.*]] = OpTypeInt 64 0
11+
; CHECK-DAG: %[[TyStruct:.*]] = OpTypeStruct %[[TyI64]] %[[TyI64]]
12+
; CHECK-DAG: %[[Const128:.*]] = OpConstant %[[TyI64]] 128
13+
; CHECK-DAG: %[[GlobalValue]] = OpVariable
14+
; CHECK-DAG: %[[PtrToInt:.*]] = OpSpecConstantOp %[[TyI64]] 117 %12
15+
; TODO: The following bitcast line looks unneeded and we may expect it to be removed in future
16+
; CHECK-DAG: %[[UseGlobalValue:.*]] = OpSpecConstantOp %[[TyI64]] 124 %[[PtrToInt]]
17+
; CHECK-DAG: %[[ConstComposite:.*]] = OpConstantComposite %[[TyStruct]] %[[Const128]] %[[UseGlobalValue]]
18+
; CHECK-DAG: %[[TyPtrStruct:.*]] = OpTypePointer CrossWorkgroup %[[TyStruct]]
19+
; CHECK: OpVariable %[[TyPtrStruct]] CrossWorkgroup %[[ConstComposite]]
20+
; CHECK: OpFunction
21+
22+
@dev_global = addrspace(1) global [2 x i32] zeroinitializer
23+
@__AsanDeviceGlobalMetadata = addrspace(1) global { i64, i64 } { i64 128, i64 ptrtoint (ptr addrspace(1) @dev_global to i64) }
24+
25+
define void @foo() {
26+
entry:
27+
ret void
28+
}

0 commit comments

Comments
 (0)