[llvm] f6ee5bd - [SPIRV] Fix constant materialization for width > 64bit (#180182)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 9 06:05:27 PST 2026
Author: Dmitry Sidorov
Date: 2026-02-09T15:05:23+01:00
New Revision: f6ee5bd4dfea88604ac27c0cc11b48ec1500e325
URL: https://github.com/llvm/llvm-project/commit/f6ee5bd4dfea88604ac27c0cc11b48ec1500e325
DIFF: https://github.com/llvm/llvm-project/commit/f6ee5bd4dfea88604ac27c0cc11b48ec1500e325.diff
LOG: [SPIRV] Fix constant materialization for width > 64bit (#180182)
selectConst() was asserting for constants wider than 64 bits. Add APInt
overloads of getOrCreateConstInt and getOrCreateConstVector that avoid
the uint64_t truncation.
Added:
llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/apint-constant.ll
Modified:
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
index 7cb7c0761da68..14f1c97741ccc 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.cpp
@@ -378,8 +378,17 @@ Register SPIRVGlobalRegistry::getOrCreateConstInt(uint64_t Val, MachineInstr &I,
SPIRVType *SpvType,
const SPIRVInstrInfo &TII,
bool ZeroAsNull) {
- const IntegerType *Ty = cast<IntegerType>(getTypeForSPIRVType(SpvType));
- auto *const CI = ConstantInt::get(const_cast<IntegerType *>(Ty), Val);
+ return getOrCreateConstInt(APInt(getScalarOrVectorBitWidth(SpvType), Val), I,
+ SpvType, TII, ZeroAsNull);
+}
+
+Register SPIRVGlobalRegistry::getOrCreateConstInt(const APInt &Val,
+ MachineInstr &I,
+ const SPIRVType *SpvType,
+ const SPIRVInstrInfo &TII,
+ bool ZeroAsNull) {
+ auto *const CI = ConstantInt::get(
+ cast<IntegerType>(getTypeForSPIRVType(SpvType))->getContext(), Val);
const MachineInstr *MI = findMI(CI, CurMF);
if (MI && (MI->getOpcode() == SPIRV::OpConstantNull ||
MI->getOpcode() == SPIRV::OpConstantI))
@@ -525,8 +534,8 @@ Register SPIRVGlobalRegistry::getOrCreateBaseRegister(
}
assert(Type->getOpcode() == SPIRV::OpTypeInt);
SPIRVType *SpvBaseType = getOrCreateSPIRVIntegerType(BitWidth, I, TII);
- return getOrCreateConstInt(Val->getUniqueInteger().getZExtValue(), I,
- SpvBaseType, TII, ZeroAsNull);
+ return getOrCreateConstInt(Val->getUniqueInteger(), I, SpvBaseType, TII,
+ ZeroAsNull);
}
Register SPIRVGlobalRegistry::getOrCreateCompositeOrNull(
@@ -578,12 +587,23 @@ Register SPIRVGlobalRegistry::getOrCreateConstVector(uint64_t Val,
SPIRVType *SpvType,
const SPIRVInstrInfo &TII,
bool ZeroAsNull) {
+ return getOrCreateConstVector(APInt(getScalarOrVectorBitWidth(SpvType), Val),
+ I, SpvType, TII, ZeroAsNull);
+}
+
+Register SPIRVGlobalRegistry::getOrCreateConstVector(const APInt &Val,
+ MachineInstr &I,
+ const SPIRVType *SpvType,
+ const SPIRVInstrInfo &TII,
+ bool ZeroAsNull) {
const Type *LLVMTy = getTypeForSPIRVType(SpvType);
- assert(LLVMTy->isVectorTy());
+ assert(LLVMTy->isVectorTy() &&
+ "Expected vector type for constant vector creation");
const FixedVectorType *LLVMVecTy = cast<FixedVectorType>(LLVMTy);
Type *LLVMBaseTy = LLVMVecTy->getElementType();
- assert(LLVMBaseTy->isIntegerTy());
- auto *ConstVal = ConstantInt::get(LLVMBaseTy, Val);
+ assert(LLVMBaseTy->isIntegerTy() &&
+ "Expected integer element type for APInt constant vector");
+ auto *ConstVal = cast<ConstantInt>(ConstantInt::get(LLVMBaseTy, Val));
auto *ConstVec =
ConstantVector::getSplat(LLVMVecTy->getElementCount(), ConstVal);
unsigned BW = getScalarOrVectorBitWidth(SpvType);
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index fa45f169f8561..b7cfa4f6f2ac1 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -520,6 +520,10 @@ class SPIRVGlobalRegistry : public SPIRVIRMapping {
Register getOrCreateConstInt(uint64_t Val, MachineInstr &I,
SPIRVType *SpvType, const SPIRVInstrInfo &TII,
bool ZeroAsNull = true);
+ Register getOrCreateConstInt(const APInt &Val, MachineInstr &I,
+ const SPIRVType *SpvType,
+ const SPIRVInstrInfo &TII,
+ bool ZeroAsNull = true);
Register createConstInt(const ConstantInt *CI, MachineInstr &I,
SPIRVType *SpvType, const SPIRVInstrInfo &TII,
bool ZeroAsNull);
@@ -535,6 +539,10 @@ class SPIRVGlobalRegistry : public SPIRVIRMapping {
Register getOrCreateConstVector(uint64_t Val, MachineInstr &I,
SPIRVType *SpvType, const SPIRVInstrInfo &TII,
bool ZeroAsNull = true);
+ Register getOrCreateConstVector(const APInt &Val, MachineInstr &I,
+ const SPIRVType *SpvType,
+ const SPIRVInstrInfo &TII,
+ bool ZeroAsNull = true);
Register getOrCreateConstVector(APFloat Val, MachineInstr &I,
SPIRVType *SpvType, const SPIRVInstrInfo &TII,
bool ZeroAsNull = true);
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 2c3d7e9c0db44..8c0bf64e8fcd0 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -3261,8 +3261,8 @@ Register SPIRVInstructionSelector::buildOnesVal(bool AllOnes,
APInt One =
AllOnes ? APInt::getAllOnes(BitWidth) : APInt::getOneBitSet(BitWidth, 0);
if (ResType->getOpcode() == SPIRV::OpTypeVector)
- return GR.getOrCreateConstVector(One.getZExtValue(), I, ResType, TII);
- return GR.getOrCreateConstInt(One.getZExtValue(), I, ResType, TII);
+ return GR.getOrCreateConstVector(One, I, ResType, TII);
+ return GR.getOrCreateConstInt(One, I, ResType, TII);
}
bool SPIRVInstructionSelector::selectSelect(Register ResVReg,
@@ -3484,7 +3484,7 @@ bool SPIRVInstructionSelector::selectConst(Register ResVReg,
Reg = GR.getOrCreateConstFP(I.getOperand(1).getFPImm()->getValue(), I,
ResType, TII, !STI.isShader());
} else {
- Reg = GR.getOrCreateConstInt(I.getOperand(1).getCImm()->getZExtValue(), I,
+ Reg = GR.getOrCreateConstInt(I.getOperand(1).getCImm()->getValue(), I,
ResType, TII, !STI.isShader());
}
return Reg == ResVReg ? true : BuildCOPY(ResVReg, Reg, I);
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
new file mode 100644
index 0000000000000..97facdb8e5cc0
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/extensions/SPV_ALTERA_arbitrary_precision_integers/apint-constant.ll
@@ -0,0 +1,23 @@
+; RUN: llc -O0 -mtriple=spirv64-unknown-unknown --spirv-ext=+SPV_ALTERA_arbitrary_precision_integers %s -o - | FileCheck %s
+
+; Verify that wide integer constants (>64 bits) are correctly encoded as
+; OpConstant with multi-word literals.
+
+; CHECK-DAG: %[[#INT128:]] = OpTypeInt 128 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: %[[#ZERO128:]] = OpConstantNull %[[#INT128]]
+; CHECK: OpStore %[[#]] %[[#NEG128]] Aligned 16
+; CHECK: OpStore %[[#]] %[[#ONE128]] Aligned 16
+; CHECK: OpStore %[[#]] %[[#BOUNDARY]] Aligned 16
+; CHECK: OpStore %[[#]] %[[#ZERO128]] Aligned 16
+
+define spir_func void @test_i128_const(ptr addrspace(4) %p) addrspace(4) {
+entry:
+ store i128 -2049, ptr addrspace(4) %p, align 16
+ store i128 1, ptr addrspace(4) %p, align 16
+ store i128 18446744073709551615, ptr addrspace(4) %p, align 16
+ store i128 0, ptr addrspace(4) %p, align 16
+ ret void
+}
More information about the llvm-commits
mailing list