[llvm] [SPIRV] Add support for SPV_KHR_abort extension (PR #193037)
Juan Manuel Martinez CaamaƱo via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 23 05:12:20 PDT 2026
================
@@ -2253,6 +2253,29 @@ Instruction *SPIRVEmitIntrinsics::visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
Instruction *SPIRVEmitIntrinsics::visitUnreachableInst(UnreachableInst &I) {
IRBuilder<> B(I.getParent());
B.SetInsertPoint(&I);
+ // OpAbortKHR is itself a SPIR-V block terminator. If the immediately
+ // preceding instruction is a call to llvm.spv.abort, do not emit an
+ // additional OpUnreachable, which would leave the SPIR-V block with two
+ // terminators and produce invalid SPIR-V. The check is intentionally limited
+ // to the directly-preceding non-debug instruction: any real instruction
+ // sitting between `llvm.spv.abort` and `unreachable` would also be invalid
+ // SPIR-V (nothing can follow OpAbortKHR in the same block), so assert that
+ // shape if we see an `spv_abort` anywhere earlier in the block.
+ Instruction *Prev = I.getPrevNode();
+ while (Prev && Prev->isDebugOrPseudoInst())
+ Prev = Prev->getPrevNode();
+ if (auto *CI = dyn_cast_or_null<CallInst>(Prev);
+ CI && CI->getIntrinsicID() == Intrinsic::spv_abort)
+ return &I;
+#ifndef NDEBUG
+ for (Instruction *P = I.getPrevNode(); P; P = P->getPrevNode()) {
+ auto *CI = dyn_cast<CallInst>(P);
+ if (CI && CI->getIntrinsicID() == Intrinsic::spv_abort)
+ llvm_unreachable("llvm.spv.abort must be the last non-debug instruction "
+ "before its block's `unreachable`; OpAbortKHR is itself "
+ "a SPIR-V block terminator");
+ }
+#endif
----------------
jmmartinez wrote:
This kind of check is for the verifier and should not be in here. You should be able to assume that the IR is well formed.
Otherwise, instead of iteration backwards, you can iterate from the beginning of the block until `I` and make the code easier to read.
https://github.com/llvm/llvm-project/pull/193037
More information about the llvm-commits
mailing list