diff --git a/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs b/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs index 57fe340ad5..d4b6bf4763 100644 --- a/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs +++ b/crates/rustc_codegen_spirv/src/builder/spirv_asm.rs @@ -3,7 +3,7 @@ use crate::builder_spirv::{BuilderCursor, SpirvValue}; use crate::codegen_cx::CodegenCx; use crate::spirv_type::SpirvType; use rspirv::dr; -use rspirv::grammar::{LogicalOperand, OperandKind, OperandQuantifier}; +use rspirv::grammar::{reflect, LogicalOperand, OperandKind, OperandQuantifier}; use rspirv::spirv::{ FPFastMathMode, FragmentShadingRate, FunctionControl, ImageOperands, KernelProfilingInfo, LoopControl, MemoryAccess, MemorySemantics, Op, RayFlags, SelectionControl, StorageClass, Word, @@ -70,8 +70,13 @@ impl<'a, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'tcx> { options: InlineAsmOptions, _line_spans: &[Span], ) { - if !options.is_empty() { - self.err(&format!("asm flags not supported: {:?}", options)); + const SUPPORTED_OPTIONS: InlineAsmOptions = InlineAsmOptions::NORETURN; + let unsupported_options = options & !SUPPORTED_OPTIONS; + if !unsupported_options.is_empty() { + self.err(&format!( + "asm flags not supported: {:?}", + unsupported_options + )); } // vec of lines, and each line is vec of tokens let mut tokens = vec![vec![]]; @@ -328,10 +333,24 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> { } return; } - _ => { + + op => { self.emit() .insert_into_block(dr::InsertPoint::End, inst) .unwrap(); + + // Return or abort terminators will also end the current block and start a new one. + // The new block is transparent to the actual builder cursor. + if reflect::is_return_or_abort(op) { + let label = self.emit().id(); + self.emit() + .insert_into_block( + dr::InsertPoint::End, + dr::Instruction::new(Op::Label, None, Some(label), vec![]), + ) + .unwrap(); + } + return; } }; diff --git a/crates/spirv-std/src/arch.rs b/crates/spirv-std/src/arch.rs index 2e16c94cbf..00f0f28b84 100644 --- a/crates/spirv-std/src/arch.rs +++ b/crates/spirv-std/src/arch.rs @@ -148,8 +148,5 @@ pub unsafe fn vector_insert_dynamic, const N: usize>( #[doc(alias = "OpKill", alias = "discard")] #[allow(clippy::empty_loop)] pub fn kill() -> ! { - unsafe { - asm!("OpKill", "%unused = OpLabel"); - } - loop {} + unsafe { asm!("OpKill", options(noreturn)) } } diff --git a/crates/spirv-std/src/arch/ray_tracing.rs b/crates/spirv-std/src/arch/ray_tracing.rs index d8b432dd4c..b1933c1ab3 100644 --- a/crates/spirv-std/src/arch/ray_tracing.rs +++ b/crates/spirv-std/src/arch/ray_tracing.rs @@ -44,8 +44,7 @@ pub unsafe fn report_intersection(hit: f32, hit_kind: u32) -> bool { #[inline] #[allow(clippy::empty_loop)] pub unsafe fn ignore_intersection() -> ! { - asm!("OpIgnoreIntersectionKHR", "%unused = OpLabel"); - loop {} + asm!("OpIgnoreIntersectionKHR", options(noreturn)); } /// Terminates the invocation that executes it, stops the ray traversal, accepts @@ -57,8 +56,7 @@ pub unsafe fn ignore_intersection() -> ! { #[inline] #[allow(clippy::empty_loop)] pub unsafe fn terminate_ray() -> ! { - asm!("OpTerminateRayKHR", "%unused = OpLabel"); - loop {} + asm!("OpTerminateRayKHR", options(noreturn)); } /// Invoke a callable shader. diff --git a/crates/spirv-std/src/lib.rs b/crates/spirv-std/src/lib.rs index 8c4c2080c6..f104456f82 100644 --- a/crates/spirv-std/src/lib.rs +++ b/crates/spirv-std/src/lib.rs @@ -118,7 +118,7 @@ pub use glam; #[cfg(all(not(test), target_arch = "spirv"))] #[panic_handler] fn panic(_: &core::panic::PanicInfo<'_>) -> ! { - loop {} + unsafe { asm!("", options(noreturn)) } } #[cfg(all(not(test), target_arch = "spirv"))] diff --git a/crates/spirv-std/src/ray_tracing.rs b/crates/spirv-std/src/ray_tracing.rs index a73993013b..914290cdcc 100644 --- a/crates/spirv-std/src/ray_tracing.rs +++ b/crates/spirv-std/src/ray_tracing.rs @@ -25,10 +25,9 @@ impl AccelerationStructure { "%ret = OpTypeAccelerationStructureKHR", "%result = OpConvertUToAccelerationStructureKHR %ret {id}", "OpReturnValue %result", - "%blah = OpLabel", id = in(reg) id, + options(noreturn) } - loop {} } /// Converts a vector of two 32 bit integers into an [`AccelerationStructure`]. @@ -47,10 +46,9 @@ impl AccelerationStructure { "%id = OpLoad _ {id}", "%result = OpConvertUToAccelerationStructureKHR %ret %id", "OpReturnValue %result", - "%blah = OpLabel", id = in(reg) &id, + options(noreturn), } - loop {} } #[spirv_std_macros::gpu_only] diff --git a/crates/spirv-std/src/runtime_array.rs b/crates/spirv-std/src/runtime_array.rs index d5bddbeb1a..12861f8de7 100644 --- a/crates/spirv-std/src/runtime_array.rs +++ b/crates/spirv-std/src/runtime_array.rs @@ -17,11 +17,10 @@ impl RuntimeArray { asm! { "%result = OpAccessChain _ {arr} {index}", "OpReturnValue %result", - "%unused = OpLabel", arr = in(reg) self, index = in(reg) index, + options(noreturn), } - loop {} } #[spirv_std_macros::gpu_only] @@ -30,10 +29,9 @@ impl RuntimeArray { asm! { "%result = OpAccessChain _ {arr} {index}", "OpReturnValue %result", - "%unused = OpLabel", arr = in(reg) self, index = in(reg) index, + options(noreturn), } - loop {} } }