[llvm] 2b8ca25 - [SPIRV] Fix failure on the `llvm.trap` test (#195996)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 6 03:19:20 PDT 2026
Author: Victor Mustya
Date: 2026-05-06T03:19:15-07:00
New Revision: 2b8ca25d950ab6b0b664cf340cdf9a2edc7944fa
URL: https://github.com/llvm/llvm-project/commit/2b8ca25d950ab6b0b664cf340cdf9a2edc7944fa
DIFF: https://github.com/llvm/llvm-project/commit/2b8ca25d950ab6b0b664cf340cdf9a2edc7944fa.diff
LOG: [SPIRV] Fix failure on the `llvm.trap` test (#195996)
The `llvm.trap` test was failing with the expensive checks enabled,
because the backend incorrectly created the `OpConstant` and
`OpConstantNull` instructions for the operand of `OpAbortKHR` in the
same basic block. When there are multiple `llvm.trap` intrinsics, they
reuse the same operand, which doesn't dominate all the users. This
commit moves the constant into the function entry block to ensure it
dominates all the users.
Assisted-by: Claude Opus 4.6 <noreply at anthropic.com>
Added:
Modified:
llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
index 6dd3dd44e21d3..5f71069b6b1dd 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstructionSelector.cpp
@@ -459,6 +459,8 @@ class SPIRVInstructionSelector : public InstructionSelector {
// Utilities
Register buildI32Constant(uint32_t Val, MachineInstr &I,
SPIRVTypeInst ResType = nullptr) const;
+ Register buildI32ConstantInEntryBlock(uint32_t Val, MachineInstr &I,
+ SPIRVTypeInst ResType = nullptr) const;
Register buildZerosVal(SPIRVTypeInst ResType, MachineInstr &I) const;
bool isScalarOrVectorIntConstantZero(Register Reg) const;
@@ -4002,6 +4004,39 @@ SPIRVInstructionSelector::buildI32Constant(uint32_t Val, MachineInstr &I,
return NewReg;
}
+// Like buildI32Constant, but always inserts the constant definition in the
+// entry block so it dominates all uses regardless of block ordering.
+Register SPIRVInstructionSelector::buildI32ConstantInEntryBlock(
+ uint32_t Val, MachineInstr &I, SPIRVTypeInst ResType) const {
+ Type *LLVMTy = IntegerType::get(GR.CurMF->getFunction().getContext(), 32);
+ SPIRVTypeInst SpvI32Ty =
+ ResType ? ResType : GR.getOrCreateSPIRVIntegerType(32, I, TII);
+ auto *ConstInt = ConstantInt::get(LLVMTy, Val);
+ Register NewReg = GR.find(ConstInt, GR.CurMF);
+ if (!NewReg.isValid()) {
+ NewReg = MRI->createGenericVirtualRegister(LLT::scalar(64));
+ auto InsertIt = getOpVariableMBBIt(*I.getMF());
+ MachineBasicBlock &EntryBB = *InsertIt->getParent();
+ MachineInstr *MI = nullptr;
+ Register TypeReg = GR.getSPIRVTypeID(SpvI32Ty);
+ DebugLoc DbgLoc = I.getDebugLoc();
+ if (Val == 0) {
+ MI = BuildMI(EntryBB, InsertIt, DbgLoc, TII.get(SPIRV::OpConstantNull))
+ .addDef(NewReg)
+ .addUse(TypeReg);
+ } else {
+ uint64_t ImmVal = APInt(32, Val).getZExtValue();
+ MI = BuildMI(EntryBB, InsertIt, DbgLoc, TII.get(SPIRV::OpConstantI))
+ .addDef(NewReg)
+ .addUse(TypeReg)
+ .addImm(ImmVal);
+ }
+ constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
+ GR.add(ConstInt, MI);
+ }
+ return NewReg;
+}
+
bool SPIRVInstructionSelector::selectFCmp(Register ResVReg,
SPIRVTypeInst ResType,
MachineInstr &I) const {
@@ -6412,7 +6447,8 @@ bool SPIRVInstructionSelector::selectTrap(MachineInstr &I) const {
MsgVal = static_cast<uint32_t>(I.getOperand(0).getImm());
SPIRVTypeInst MsgType = GR.getOrCreateSPIRVIntegerType(32, I, TII);
- Register MsgReg = buildI32Constant(MsgVal, I, MsgType);
+ Register MsgReg = buildI32ConstantInEntryBlock(MsgVal, I, MsgType);
+
MachineBasicBlock &BB = *I.getParent();
BuildMI(BB, I, I.getDebugLoc(), TII.get(SPIRV::OpAbortKHR))
.addUse(GR.getSPIRVTypeID(MsgType))
More information about the llvm-commits
mailing list