EmbarkStudios/rust-gpu

SPIR-V wishlist

Jasper-Bekkers opened this issue · 5 comments

Tracking issue for features we think are missing or useful in to have in SPIR-V

  • OpTrap: trigger a breakpoint

Noticed a few comments other things in the codebase yesterday:

  • Checked math as native SPIR-V ops could help slightly more optimized checked math routines
    fn checked_binop(
    &mut self,
    _oop: OverflowOp,
    _ty: Ty<'_>,
    _lhs: Self::Value,
    _rhs: Self::Value,
    ) -> (Self::Value, Self::Value) {
    panic!("TODO: Checked binary operations are not supported yet");
    }
  • Saturating math ops (already supported by some GPU ISAs - so should be easier to drive adoption for):
    sym::wrapping_add => math_intrinsic! {self, arg_tys, args, add, add, fadd},
    sym::wrapping_sub => math_intrinsic! {self, arg_tys, args, sub, sub, fsub},
    sym::wrapping_mul => math_intrinsic! {self, arg_tys, args, mul, mul, fmul},
    sym::saturating_add => math_intrinsic! {self, arg_tys, args, add, add, fadd},
    sym::saturating_sub => math_intrinsic! {self, arg_tys, args, sub, sub, fsub},
    sym::unchecked_add => math_intrinsic! {self, arg_tys, args, add, add, fadd},
    sym::unchecked_sub => math_intrinsic! {self, arg_tys, args, sub, sub, fsub},
    sym::unchecked_mul => math_intrinsic! {self, arg_tys, args, mul, mul, fmul},
    sym::unchecked_div => math_intrinsic! {self, arg_tys, args, sdiv, udiv, fdiv},
    sym::unchecked_rem => math_intrinsic! {self, arg_tys, args, srem, urem, frem},
    sym::unchecked_shl => math_intrinsic_int! {self, arg_tys, args, shl, shl},
  • Equivalent of llvm.expect:
    fn expect(&mut self, cond: Self::Value, _expected: bool) -> Self::Value {
    // TODO: llvm.expect
    cond
    }
  • Equivalent of llvm.sideeffects:
    fn sideeffect(&mut self) {
    // TODO: This is currently ignored.
    // It corresponds to the llvm.sideeffect intrinsic - does spir-v have an equivalent?
    }
  • Equivalent of llvm.assume:
    fn assume(&mut self, _val: Self::Value) {
    // TODO: llvm.assume
    }

For the "equivalent of llvm.*", there are a lot of these, those are just the ones that have been hit so far - I've just been JITting them into the codebase. For a reasonably full list, look at this file - for example, llvm.expect.i1 (sym::likely/sym::unlikely), llvm.debugtrap (sym::breakpoint), and so forth. (including llvm.trap (sym::abort), which was already mentioned at the start of this thread)

https://github.com/rust-lang/rust/blob/e88e908e66cd1e6e30d789b37bcd774951d01856/compiler/rustc_codegen_llvm/src/intrinsic.rs

  • Potentially request OpControlBarrier for non-uniform controlflow (useful for #29)
* Potentially request OpControlBarrier  for non-uniform controlflow (useful for #29)

To clarify, for #29 the thinking is that OpControlBarrier without undefined behavior may be useful. This would be done by making the behavior a guaranteed hang when it's not executed in uniform control flow...

@khyperia
not only is this legal spir-v, it is unspecified what the return value is (like, it's not specified as undefined, it's unspecified)

         %f_ = OpFunction %int None %7
          %9 = OpLabel
          %x = OpVariable %_ptr_Function_int Function
         %12 = OpLoad %int %x
               OpReturnValue %12
               OpFunctionEnd

can we get this fixed in the spec, please?
this is equivalent to the glsl

int f() {
    int x; // explicitly uninitialized
    return x;
}