Skip to content

Conversation

@AlexVlx
Copy link
Contributor

@AlexVlx AlexVlx commented Dec 17, 2025

#166494 added support for using inttoptr in global initialisation, and lowering int into OpSpecConstantOp OpConvertUToPtr. Unfortunately, it slightly more subtle case / exposed an existing issue around the COPY pseudo-op. This patch ensures that we glance through a COPY when figuring out whether an OpConvertUToPtr is actually operating on a global. We also correctly handle the case where a G_PTR_ADD is used by an OpSpecConstantOp in the context of global initialisation, which would otherwise lead to broken SPIR-V wherein the latter would reference a non constant Op.

@llvmbot
Copy link
Member

llvmbot commented Dec 17, 2025

@llvm/pr-subscribers-backend-spir-v

Author: Alex Voicu (AlexVlx)

Changes

#166494 added support for using inttoptr in global initialisation, and lowering int into OpSpecConstantOp OpConvertUToPtr. Unfortunately, it slightly more subtle case / exposed an existing issue around the COPY pseudo-op. This patch ensures that we glance through a COPY when figuring out whether an OpConvertUToPtr is actually operating on a global. We also correctly handle the case where a G_PTR_ADD is used by an OpSpecConstantOp in the context of global initialisation, which would otherwise lead to broken SPIR-V wherein the latter would reference a non constant Op.


Full diff: https://github.com/llvm/llvm-project/pull/172584.diff

2 Files Affected:

  • (modified) llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp (+4-3)
  • (modified) llvm/test/CodeGen/SPIRV/transcoding/ConvertPtrInGlobalInit.ll (+2-1)
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 2e4563795e8f0..aae025602b763 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -1099,6 +1099,7 @@ bool SPIRVInstructionSelector::spvSelect(Register ResVReg,
              UseEnd = MRI->use_instr_end();
          UseIt != UseEnd; UseIt = std::next(UseIt)) {
       if ((*UseIt).getOpcode() == TargetOpcode::G_GLOBAL_VALUE ||
+          (*UseIt).getOpcode() == SPIRV::OpSpecConstantOp ||
           (*UseIt).getOpcode() == SPIRV::OpVariable) {
         IsGVInit = true;
         break;
@@ -1407,9 +1408,9 @@ bool SPIRVInstructionSelector::selectUnOp(Register ResVReg,
              MRI->def_instr_begin(SrcReg);
          DefIt != MRI->def_instr_end(); DefIt = std::next(DefIt)) {
       unsigned DefOpCode = DefIt->getOpcode();
-      if (DefOpCode == SPIRV::ASSIGN_TYPE) {
-        // We need special handling to look through the type assignment and see
-        // if this is a constant or a global
+      if (DefOpCode == SPIRV::ASSIGN_TYPE || DefOpCode == TargetOpcode::COPY) {
+        // We need special handling to look through the type assignment or the
+        // COPY pseudo-op and see if this is a constant or a global
         if (auto *VRD = getVRegDef(*MRI, DefIt->getOperand(1).getReg()))
           DefOpCode = VRD->getOpcode();
       }
diff --git a/llvm/test/CodeGen/SPIRV/transcoding/ConvertPtrInGlobalInit.ll b/llvm/test/CodeGen/SPIRV/transcoding/ConvertPtrInGlobalInit.ll
index f397030c7bdb1..23aaa5573a83c 100644
--- a/llvm/test/CodeGen/SPIRV/transcoding/ConvertPtrInGlobalInit.ll
+++ b/llvm/test/CodeGen/SPIRV/transcoding/ConvertPtrInGlobalInit.ll
@@ -12,11 +12,11 @@
 ; CHECK: %[[VtblTy:[0-9]+]] = OpTypeStruct %[[ArrTy]] %[[ArrTy]] %[[ArrTy]] %[[ArrTy]] %[[ArrTy]]
 ; CHECK: %[[Int64Ty:[0-9]+]] = OpTypeInt 64 0
 ; CHECK: %[[GlobVtblPtrTy:[0-9]+]] = OpTypePointer CrossWorkgroup %[[VtblTy]]
+; CHECK: %[[Const184:[0-9]+]] = OpConstant %[[Int64Ty]] 184
 ; CHECK: %[[ConstMinus184:[0-9]+]] = OpConstant %[[Int64Ty]] 18446744073709551432
 ; CHECK: %[[ConstMinus16:[0-9]+]] = OpConstant %[[Int64Ty]] 18446744073709551600
 ; CHECK: %[[Const168:[0-9]+]] = OpConstant %[[Int64Ty]] 168
 ; CHECK: %[[Nullptr:[0-9]+]] = OpConstantNull %[[GlobInt8PtrTy]]
-; CHECK: %[[Const184:[0-9]+]] = OpConstant %[[Int64Ty]] 184
 ; CHECK: %[[Const184toPtr:[0-9]+]] = OpSpecConstantOp %[[GlobInt8PtrTy]] ConvertUToPtr %[[Const184]]
 ; CHECK: %[[Const168toPtr:[0-9]+]] = OpSpecConstantOp %[[GlobInt8PtrTy]] ConvertUToPtr %[[Const168]]
 ; CHECK: %[[ConstMinus16toPtr:[0-9]+]] = OpSpecConstantOp %[[GlobInt8PtrTy]] ConvertUToPtr %[[ConstMinus16]]
@@ -33,6 +33,7 @@
                                                             [5 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 184 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null],
                                                             [5 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 168 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -16 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null],
                                                             [5 x ptr addrspace(1)] [ptr addrspace(1) inttoptr (i64 -184 to ptr addrspace(1)), ptr addrspace(1) inttoptr (i64 -184 to ptr addrspace(1)), ptr addrspace(1) null, ptr addrspace(1) null, ptr addrspace(1) null] }
+@VTT = linkonce_odr unnamed_addr addrspace(1) constant [1 x ptr addrspace(1)][ptr addrspace(1) getelementptr inbounds inrange(-24, 16) ({ [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)], [5 x ptr addrspace(1)] }, ptr addrspace(1) @vtable, i32 0, i32 4, i32 3)]
 
 define linkonce_odr spir_func void @foo(ptr addrspace(4) %this) {
 entry:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants