Implement SPV_KHR_abort extension#3691
Conversation
The SPV_KHR_abort extension introduces the `OpAbortKHR` instruction, allowing shaders to terminate execution early. Assisted-by: Claude Opus 4.7 <noreply@anthropic.com>
The clang-tidy fails as follows: The reported issue is that the I don't really want to deviate the style other instructions are implemented. So, I believe, that either all the instructions should be changed by a separate commit, or the clang-tidy error should be suppressed. @vmaksimo, what would you suggest? |
| // llvm.trap and llvm.debugtrap intrinsics are not implemented. But for now | ||
| // don't crash. This change is pending the trap/abort intrinsic | ||
| // implementation. | ||
| // TODO: lower llvm.trap / llvm.ubsantrap / llvm.debugtrap to OpAbortKHR |
There was a problem hiding this comment.
Could we do this in this patch too? Seems very related.
There was a problem hiding this comment.
@maarquitos14 Maybe not to overload this PR, we can follow-up in a separate one (together with Reader part update for default/non-friendly IR path). What do you think?
There was a problem hiding this comment.
I won't block this PR for this. If you want to follow-up in a separate PR, go for it.
| if (isa<UnreachableInst>(V)) { | ||
| // SPV_KHR_abort: OpAbortKHR is itself a block terminator. If the LLVM IR | ||
| // appends a trailing 'unreachable' after the abort call (the canonical | ||
| // pattern for noreturn calls), do not emit a second SPIR-V terminator. | ||
| if (auto *Last = BB->getTerminateInstr()) | ||
| if (Last->getOpCode() == OpAbortKHR) | ||
| return mapValue(V, const_cast<SPIRVInstruction *>(Last)); | ||
| return mapValue(V, BM->addUnreachableInst(BB)); | ||
| } | ||
|
|
||
| if (auto *RI = dyn_cast<ReturnInst>(V)) { | ||
| // SPV_KHR_abort: OpAbortKHR is itself a SPIR-V block terminator. If the | ||
| // LLVM IR appends a trailing `ret void` after the abort call, do not emit | ||
| // a second SPIR-V terminator. We deliberately limit this suppression to | ||
| // `ret void`: if a non-void function ends with `ret <value>` after | ||
| // OpAbortKHR, fall through so that the value is still translated and the | ||
| // user sees a normal SPIR-V validation error rather than silently | ||
| // dropping the return value. | ||
| if (auto *Last = BB->getTerminateInstr(); | ||
| !RI->getReturnValue() && Last && Last->getOpCode() == OpAbortKHR) | ||
| return mapValue(V, const_cast<SPIRVInstruction *>(Last)); |
There was a problem hiding this comment.
I am not sure this is enough to handle all the cases. For example:
call void @llvm.trap()/__spirv_AbortKHR
cal void @llvm.lifetime.end()
ret void
This would be invalid, because we would have an instruction after a terminator. As far as I can tell, nothing would prevent translating the call to @llvm.lifetime.end() after the OpAbortKHR, which is a terminator. Am I right?
There was a problem hiding this comment.
@maarquitos14, I've moved the tests you've shared from the llvm.trap intrinsic to the SPIR-V friendly IR, and adjusted the writer code. Now all the instructions in the basic block, that follow the __spirv_AbortKHR function call, are ignored by the writer. Could you please provide your feedback?
| } | ||
|
|
||
| case OpAbortKHR: { | ||
| // OpAbortKHR is a SPIR-V block terminator. In LLVM IR, model it as a call |
There was a problem hiding this comment.
Should we split in two paths? This one for spirv-friendly IR, and another one for non-friendly which would translate into... llvm.trap maybe?
@maarquitos14, sure! I'd really appreciate that. |
You can find them in maarquitos14@fe51642. I think all of them assume llvm.trap gets translated to OpAbortKHR and back, but still I think they can be useful. |
@vmustya If can - we should not introduce new errors, and I believe this is the case. So please just put encode/decode to public - we'll take a look at other instructions separately. |
The CI environment does not provide the split-file utility, causing the abort-invalid-arg-count.ll test to fail. Split it into two standalone tests that exercise the no-args and two-args negative cases independently, removing the split-file requirement.
vmaksimo
left a comment
There was a problem hiding this comment.
The change with the test coverege looks great, thanks for the work done!
I have the nits about the tests that'd better to be addressed, after that I guess we're perfectly good to go 🙂
|
@svenvh would you like to review this one prior merging? |
|
/backport llvm_release_220 |
|
Attempting to create backport to |
|
Success. Backport PR created: #3730 |
|
/backport llvm_release_210 |
|
Attempting to create backport to |
|
Success. Backport PR created: #3733 |
|
/backport llvm_release_200 |
|
Attempting to create backport to |
|
Backport to |
The SPV_KHR_abort extension introduces the
OpAbortKHRinstruction,allowing shaders to terminate execution early.
Assisted-by: Claude Opus 4.7 noreply@anthropic.com