[llvm] [SPIR-V] Add support for arbitrary precision integer constants in instruction printer (PR #185306)

via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 8 11:47:33 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

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

Author: None (YixingZhang007)

<details>
<summary>Changes</summary>

This PR improves the SPIR-V instruction printer output for integer constants using `SPV_ALTERA_arbitrary_precision_integers` extension. 

Previously, when `OpConstantI` was encoded with multiple 32-bit words (for integer widths > 64), the inst printer printed the raw per-word immediates. This was hard to read and did not reflect the actual value at the declared integer bitwidth.

Now, with the change in this patch, the instruction printer reconstructs the multi-word literal into a single `APInt`, truncates it to the bitwidth declared by the corresponding `OpTypeInt`, and prints the resulting value as one readable integer (including correct negative values where applicable).


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


5 Files Affected:

- (modified) llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp (+26-2) 
- (modified) llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h (+2) 
- (modified) llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/SPV_ALTERA_arbitrary_precision_integers.ll (+22) 
- (modified) llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/apint-constant.ll (+9-9) 
- (modified) llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/i128-addsub.ll (+1-1) 


``````````diff
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
index 66500f5626fd1..d0e6750c934c2 100644
--- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.cpp
@@ -51,10 +51,25 @@ void SPIRVInstPrinter::printOpConstantVarOps(const MCInst *MI,
   const unsigned NumVarOps = MI->getNumOperands() - StartIndex;
 
   if (MI->getOpcode() == SPIRV::OpConstantI && NumVarOps > 2) {
+    // Look up the bitwidth of this int type register from
+    // IntTypeBitwidths map.
+    unsigned IntTypeRegId = getIDFromRegister(MI->getOperand(1).getReg().id());
+    auto IntTypeRegIt = IntTypeBitwidths.find(IntTypeRegId);
+    if (IntTypeRegIt == IntTypeBitwidths.end()) {
+      llvm_unreachable("Int type register used before defined in OpTypeInt");
+    }
+    int Bitwidth = IntTypeRegIt->second;
+
     // SPV_ALTERA_arbitrary_precision_integers allows for integer widths greater
     // than 64, which will be encoded via multiple operands.
-    for (unsigned I = StartIndex; I != MI->getNumOperands(); ++I)
-      O << ' ' << MI->getOperand(I).getImm();
+    const unsigned TotalBits = NumVarOps * 32;
+    APInt Val(TotalBits, 0);
+    for (unsigned i = 0; i < NumVarOps; ++i) {
+      uint64_t Word = MI->getOperand(StartIndex + i).getImm();
+      Val |= APInt(TotalBits, Word) << (i * 32);
+    }
+    APInt ActualVal = Val.trunc(Bitwidth);
+    O << ' ' << ActualVal;
     return;
   }
 
@@ -101,6 +116,12 @@ void SPIRVInstPrinter::printOpConstantVarOps(const MCInst *MI,
   O << Imm;
 }
 
+void SPIRVInstPrinter::recordIntType(const MCInst *MI) {
+  unsigned IntTypeRegId = getIDFromRegister(MI->getOperand(0).getReg().id());
+  unsigned Bitwidth = MI->getOperand(1).getImm();
+  IntTypeBitwidths[IntTypeRegId] = Bitwidth;
+}
+
 void SPIRVInstPrinter::recordOpExtInstImport(const MCInst *MI) {
   MCRegister Reg = MI->getOperand(0).getReg();
   auto Name = getSPIRVStringOperand(*MI, 1);
@@ -113,6 +134,9 @@ void SPIRVInstPrinter::printInst(const MCInst *MI, uint64_t Address,
                                  raw_ostream &OS) {
   const unsigned OpCode = MI->getOpcode();
   printInstruction(MI, Address, OS);
+  if (OpCode == SPIRV::OpTypeInt) {
+    recordIntType(MI);
+  }
 
   if (OpCode == SPIRV::OpDecorate) {
     printOpDecorate(MI, OS);
diff --git a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h
index 8f2ad48efa9d7..f90af3bbcdc3f 100644
--- a/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h
+++ b/llvm/lib/Target/SPIRV/MCTargetDesc/SPIRVInstPrinter.h
@@ -22,7 +22,9 @@ namespace llvm {
 class SPIRVInstPrinter : public MCInstPrinter {
 private:
   SmallDenseMap<MCRegister, SPIRV::InstructionSet::InstructionSet> ExtInstSetIDs;
+  SmallDenseMap<unsigned, unsigned> IntTypeBitwidths;
   void recordOpExtInstImport(const MCInst *MI);
+  void recordIntType(const MCInst *MI);
 
 public:
   using MCInstPrinter::MCInstPrinter;
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/SPV_ALTERA_arbitrary_precision_integers.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/SPV_ALTERA_arbitrary_precision_integers.ll
index 9ea8a5709154c..a0451278f82cd 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/SPV_ALTERA_arbitrary_precision_integers.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/SPV_ALTERA_arbitrary_precision_integers.ll
@@ -8,6 +8,14 @@ define i13 @getConstantI13() {
   ret i13 42
 }
 
+define i96 @getConstantI96() {
+  ret i96 18446744073709551620
+}
+
+define i160 @getConstantI160() {
+  ret i160 3363637389930338837376336738763689377839373638
+}
+
 ;; Capabilities:
 ; CHECK-DAG: OpExtension "SPV_ALTERA_arbitrary_precision_integers"
 ; CHECK-DAG: OpCapability ArbitraryPrecisionIntegersALTERA
@@ -17,14 +25,20 @@ define i13 @getConstantI13() {
 ;; Names:
 ; CHECK-DAG: OpName %[[#GET_I6:]] "getConstantI6"
 ; CHECK-DAG: OpName %[[#GET_I13:]] "getConstantI13"
+; CHECK-DAG: OpName %[[#GET_I96:]] "getConstantI96"
+; CHECK-DAG: OpName %[[#GET_I160:]] "getConstantI160"
 
 ; CHECK-NOT: DAG-FENCE
 
 ;; Types and Constants:
 ; CHECK-DAG: %[[#I6:]] = OpTypeInt 6 0
 ; CHECK-DAG: %[[#I13:]] = OpTypeInt 13 0
+; CHECK-DAG: %[[#I96:]] = OpTypeInt 96 0
+; CHECK-DAG: %[[#I160:]] = OpTypeInt 160 0
 ; CHECK-DAG: %[[#CST_I6:]] = OpConstant %[[#I6]] 2
 ; CHECK-DAG: %[[#CST_I13:]] = OpConstant %[[#I13]] 42
+; CHECK-DAG: %[[#CST_I96:]] = OpConstant %[[#I96]] 18446744073709551620
+; CHECK-DAG: %[[#CST_I160:]] = OpConstant %[[#I160]] 3363637389930338837376336738763689377839373638
 
 ; CHECK: %[[#GET_I6]] = OpFunction %[[#I6]]
 ; CHECK: OpReturnValue %[[#CST_I6]]
@@ -33,3 +47,11 @@ define i13 @getConstantI13() {
 ; CHECK: %[[#GET_I13]] = OpFunction %[[#I13]]
 ; CHECK: OpReturnValue %[[#CST_I13]]
 ; CHECK: OpFunctionEnd
+
+; CHECK: %[[#GET_I96]] = OpFunction %[[#I96]]
+; CHECK: OpReturnValue %[[#CST_I96]]
+; CHECK: OpFunctionEnd
+
+; CHECK: %[[#GET_I160]] = OpFunction %[[#I160]]
+; CHECK: OpReturnValue %[[#CST_I160]]
+; CHECK: OpFunctionEnd
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/apint-constant.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/apint-constant.ll
index 6ed6228653ff5..3a5c4f02fa879 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/apint-constant.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/apint-constant.ll
@@ -6,15 +6,15 @@
 ; CHECK-DAG: %[[#INT128:]] = OpTypeInt 128 0
 ; CHECK-DAG: %[[#INT96:]] = OpTypeInt 96 0
 ; CHECK-DAG: %[[#INT97:]] = OpTypeInt 97 0
-; CHECK-DAG: %[[#NEG128:]] = OpConstant %[[#INT128]] 4294965247 4294967295 4294967295 4294967295
-; CHECK-DAG: %[[#ONE128:]] = OpConstant %[[#INT128]] 1 0 0 0
-; CHECK-DAG: %[[#BOUNDARY:]] = OpConstant %[[#INT128]] 4294967295 4294967295 0 0
+; CHECK-DAG: %[[#BOUNDARY:]] = OpConstant %[[#INT128]] 18446744073709551615
+; CHECK-DAG: %[[#ONE128:]] = OpConstant %[[#INT128]] 1
+; CHECK-DAG: %[[#NEG128:]] = OpConstant %[[#INT128]] -2049
 ; CHECK-DAG: %[[#ZERO128:]] = OpConstantNull %[[#INT128]]
-; CHECK-DAG: %[[#NEG96:]] = OpConstant %[[#INT96]] 4294967295 4294967295 4294967295
-; CHECK-DAG: %[[#OVER64:]] = OpConstant %[[#INT96]] 1 0 1
-; CHECK-DAG: %[[#NEG97:]] = OpConstant %[[#INT97]] 4294967295 4294967295 4294967295 1
-; CHECK-DAG: %[[#OVER64_I97:]] = OpConstant %[[#INT97]] 1 0 1 0
-; CHECK-DAG: %[[#I97_MAX:]] = OpConstant %[[#INT97]] 0 0 0 1
+; CHECK-DAG: %[[#OVER64:]] = OpConstant %[[#INT96]] 18446744073709551617
+; CHECK-DAG: %[[#NEG96:]] = OpConstant %[[#INT96]] -1
+; CHECK-DAG: %[[#I97_MAX:]] = OpConstant %[[#INT97]] 79228162514264337593543950335
+; CHECK-DAG: %[[#OVER64_I97:]] = OpConstant %[[#INT97]] 18446744073709551617
+; CHECK-DAG: %[[#NEG97:]] = OpConstant %[[#INT97]] -1
 
 ; CHECK: OpStore %[[#]] %[[#NEG128]] Aligned 16
 ; CHECK: OpStore %[[#]] %[[#ONE128]] Aligned 16
@@ -48,6 +48,6 @@ define spir_func void @test_i97_const(ptr addrspace(4) %p) addrspace(4) {
 entry:
   store i97 -1, ptr addrspace(4) %p, align 16
   store i97 18446744073709551617, ptr addrspace(4) %p, align 16
-  store i97 79228162514264337593543950336, ptr addrspace(4) %p, align 16
+  store i97 79228162514264337593543950335, ptr addrspace(4) %p, align 16
   ret void
 }
diff --git a/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/i128-addsub.ll b/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/i128-addsub.ll
index c90ffdd17996c..f733c8f9ce09b 100644
--- a/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/i128-addsub.ll
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/i128-addsub.ll
@@ -10,7 +10,7 @@
 ; CHECK: OpName %[[#TestAdd:]] "test_add"
 ; CHECK: OpName %[[#TestSub:]] "test_sub"
 ; CHECK: %[[#Int128Ty:]] = OpTypeInt 128 0
-; CHECK: %[[#Const64Int128:]] = OpConstant %[[#Int128Ty]] 64 0 0 0
+; CHECK: %[[#Const64Int128:]] = OpConstant %[[#Int128Ty]] 64
 
 ; CHECK: %[[#TestAdd]] = OpFunction
 define spir_func void @test_add(i64 %AL, i64 %AH, i64 %BL, i64 %BH, ptr %RL, ptr %RH) {

``````````

</details>


https://github.com/llvm/llvm-project/pull/185306


More information about the llvm-commits mailing list