Skip to content

[SPIR-V] Fix pre-legalizer pass in SPIR-V Backend to support more gMIR opcode inserted by IRTranslator #89890

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,37 @@ bool SPIRVInstructionSelector::selectUnOp(Register ResVReg,
const SPIRVType *ResType,
MachineInstr &I,
unsigned Opcode) const {
if (STI.isOpenCLEnv() && I.getOperand(1).isReg()) {
Register SrcReg = I.getOperand(1).getReg();
bool IsGV = false;
for (MachineRegisterInfo::def_instr_iterator DefIt =
MRI->def_instr_begin(SrcReg);
DefIt != MRI->def_instr_end(); DefIt = std::next(DefIt)) {
if ((*DefIt).getOpcode() == TargetOpcode::G_GLOBAL_VALUE) {
IsGV = true;
break;
}
}
if (IsGV) {
uint32_t SpecOpcode = 0;
switch (Opcode) {
case SPIRV::OpConvertPtrToU:
SpecOpcode = static_cast<uint32_t>(SPIRV::Opcode::ConvertPtrToU);
break;
case SPIRV::OpConvertUToPtr:
SpecOpcode = static_cast<uint32_t>(SPIRV::Opcode::ConvertUToPtr);
break;
}
if (SpecOpcode)
return BuildMI(*I.getParent(), I, I.getDebugLoc(),
TII.get(SPIRV::OpSpecConstantOp))
.addDef(ResVReg)
.addUse(GR.getSPIRVTypeID(ResType))
.addImm(SpecOpcode)
.addUse(SrcReg)
.constrainAllUses(TII, TRI, RBI);
}
}
return selectUnOpWithSrc(ResVReg, ResType, I, I.getOperand(1).getReg(),
Opcode);
}
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,10 @@ static SPIRVType *propagateSPIRVType(MachineInstr *MI, SPIRVGlobalRegistry *GR,
}
break;
}
case TargetOpcode::G_PTRTOINT:
SpirvTy = GR->getOrCreateSPIRVIntegerType(
MRI.getType(Reg).getScalarSizeInBits(), MIB);
break;
case TargetOpcode::G_TRUNC:
case TargetOpcode::G_ADDRSPACE_CAST:
case TargetOpcode::G_PTR_ADD:
Expand Down Expand Up @@ -440,6 +444,7 @@ static void generateAssignInstrs(MachineFunction &MF, SPIRVGlobalRegistry *GR,
insertAssignInstr(Reg, Ty, nullptr, GR, MIB, MRI);
} else if (MI.getOpcode() == TargetOpcode::G_TRUNC ||
MI.getOpcode() == TargetOpcode::G_ZEXT ||
MI.getOpcode() == TargetOpcode::G_PTRTOINT ||
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
MI.getOpcode() == TargetOpcode::COPY ||
MI.getOpcode() == TargetOpcode::G_ADDRSPACE_CAST) {
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVSymbolicOperands.td
Original file line number Diff line number Diff line change
Expand Up @@ -1612,3 +1612,5 @@ multiclass OpcodeOperand<bits<32> value> {
defm InBoundsPtrAccessChain : OpcodeOperand<70>;
defm PtrCastToGeneric : OpcodeOperand<121>;
defm Bitcast : OpcodeOperand<124>;
defm ConvertPtrToU : OpcodeOperand<117>;
defm ConvertUToPtr : OpcodeOperand<120>;
28 changes: 28 additions & 0 deletions llvm/test/CodeGen/SPIRV/pointers/global-ptrtoint.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
; This test is to check that correct virtual register type is created after ptrtoint.

; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}

; RUN: llc -O0 -mtriple=spirv32-unknown-unknown %s -o - | FileCheck %s
; RUN: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}

; CHECK: OpName %[[GlobalValue:.*]] "dev_global"
; CHECK-DAG: %[[TyI64:.*]] = OpTypeInt 64 0
; CHECK-DAG: %[[TyStruct:.*]] = OpTypeStruct %[[TyI64]] %[[TyI64]]
; CHECK-DAG: %[[Const128:.*]] = OpConstant %[[TyI64]] 128
; CHECK-DAG: %[[GlobalValue]] = OpVariable
; CHECK-DAG: %[[PtrToInt:.*]] = OpSpecConstantOp %[[TyI64]] 117 %12
; TODO: The following bitcast line looks unneeded and we may expect it to be removed in future
; CHECK-DAG: %[[UseGlobalValue:.*]] = OpSpecConstantOp %[[TyI64]] 124 %[[PtrToInt]]
; CHECK-DAG: %[[ConstComposite:.*]] = OpConstantComposite %[[TyStruct]] %[[Const128]] %[[UseGlobalValue]]
; CHECK-DAG: %[[TyPtrStruct:.*]] = OpTypePointer CrossWorkgroup %[[TyStruct]]
; CHECK: OpVariable %[[TyPtrStruct]] CrossWorkgroup %[[ConstComposite]]
; CHECK: OpFunction

@dev_global = addrspace(1) global [2 x i32] zeroinitializer
@__AsanDeviceGlobalMetadata = addrspace(1) global { i64, i64 } { i64 128, i64 ptrtoint (ptr addrspace(1) @dev_global to i64) }

define void @foo() {
entry:
ret void
}