Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SPIR-V] All attempts at decorating an instruction with Inline-SPIRV fail. #7064

Open
devshgraphicsprogramming opened this issue Jan 13, 2025 · 3 comments
Labels
bug Bug, regression, crash spirv Work related to SPIR-V

Comments

@devshgraphicsprogramming
Copy link

devshgraphicsprogramming commented Jan 13, 2025

Description

I'm trying to make a proof-of-concept interval arithmetic library in HLSL.

This requires me to leverage the float_controls2 extension and set rounding modes per instruction.

I can't figure out the syntax to OpDecorate an isntruction.

Steps to Reproduce

Attempt 1, take an intermediate of the OpFAdd and attempt to `OpDecorate that.

template<typename T>
[[vk::ext_instruction(spv::OpFAdd)]]
T fAdd(T lhs, T rhs);

template<typename T>
[[vk::ext_instruction(spv::OpDecorate)]]
void decorateInstruction(T res, [[vk::ext_literal]] int32_t decoration, [[vk::ext_literal]] int32_t op0);

...

decorateInstruction(fAdd(lo,rhs.lo),spv::DecorationFPRoundingMode,spv::FPRoundingModeRTN);

Attempt 2, try and use your vk::ext_decorate on an intrinsic

template<typename T>
[[vk::ext_decorate(spv::DecorationFPRoundingMode,spv::FPRoundingModeRTN)]]
[[vk::ext_instruction(spv::OpFAdd)]]
T fAddRTN(T lhs, T rhs);

...

result.lo = fAddRTN(lo,rhs.lo);

Actual Behavior

Attempt 1 kind-of-works but only with -O0 and kind-of because OpDecorate can't return anything so while I can annotate an immediate, I can't get it out and use it meaningfully
https://godbolt.org/z/9E346eazG

         %54 = OpAccessChain %_ptr_Function_float %param_this %int_0
         %55 = OpLoad %float %54
               OpLine %2 43 37
         %56 = OpAccessChain %_ptr_Function_float %rhs %int_0
               OpLine %2 43 41
         %57 = OpLoad %float %56
               OpLine %2 43 29
         %58 = OpFAdd %float %55 %57
               OpDecorate %58 FPRoundingMode RTN

However if I progress onto -O1 the optimizer breaks the code altogether (goes from valid but dead to invalid), moving the decoration on the immediate result to a constant it optimized to
https://godbolt.org/z/5TYr85Kvf

   %float_12 = OpConstant %float 12
...
               OpDecorate %float_12 FPRoundingMode RTN

Attempt 2 doesn't emit any OpDecorate at all, even in -O0, its just ignored
https://godbolt.org/z/xnK6azeqM

Environment

  • DXC version
  • Host Operating System <!--- Host operating system and version --->
@devshgraphicsprogramming devshgraphicsprogramming added bug Bug, regression, crash needs-triage Awaiting triage spirv Work related to SPIR-V labels Jan 13, 2025
@eddyb
Copy link

eddyb commented Jan 13, 2025

Attempt 1 couldn't possibly work, you just disabled validation so you didn't see the fundamental issue with it: https://godbolt.org/z/7nqeMr17K

fatal error: generated SPIR-V is invalid: Decorate cannot appear in a function declaration
  OpDecorate %58 FPRoundingMode RTN

(all OpDecorate must go in a certain position in the file, before any instruction that can define any of the decorated IDs, i.e. before even all types/constants/global-variables etc.)

@eddyb
Copy link

eddyb commented Jan 13, 2025

The ext_decorate test has the example you want:

// spv::Decoration::FPRoundingMode = 39, RTZ=0
[[vk::ext_decorate(39, 0), vk::ext_decorate_string(5635, "return variable")]] float4 ret = 1.0;

I wish there was a better documentation, but at least that seems to work: https://godbolt.org/z/xqTMnroqn

Well, except it decorates the variable, so maybe that test is doing something useless all along (and the decoration disappears with optimizations.

The exact needed thing is [[vk::ext_decorate(...)]] on an expression but I don't know if that's syntactically allowed?


EDIT: C++ attributes on expressions have been proposed but AFAICT not accepted yet into any future C++ standard:
https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3093r0.html

With that proposal, your code would look like this:

result.lo = (
  [[vk::ext_decorate(
      spv::DecorationFPRoundingMode,
      spv::FPRoundingModeRTN,
  )]]
  lo + rhs.lo
);

(the extra parens are necessary for syntactic disambiguation)

You could then define fAddRTN(a, b) as a regular function whose body is just return ([[...]] a + b);, and there might be different ways to make this more ergonomic etc.

@devshgraphicsprogramming
Copy link
Author

Well, except it decorates the variable, so maybe that test is doing something useless all along (and the decoration disappears with optimizations.

        [[vk::ext_decorate(39, 0)]] fAdd(lo,rhs.lo);

fails with

<source>:43:11: error: 'ext_decorate' attribute cannot be applied to a statement
        [[vk::ext_decorate(39, 0)]] fAdd(lo,rhs.lo);
          ^                         ~~~~

btw if just my last example

template<typename T>
[[vk::ext_decorate(spv::DecorationFPRoundingMode,spv::FPRoundingModeRTN)]]
[[vk::ext_instruction(spv::OpFAdd)]]
T fAddRTN(T lhs, T rhs);

worked no "yet unapproved C++ standard addition" would have to be implemented.

@damyanp damyanp removed the needs-triage Awaiting triage label Jan 14, 2025
@damyanp damyanp moved this to For Google in HLSL Triage Jan 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug, regression, crash spirv Work related to SPIR-V
Projects
Status: For Google
Development

No branches or pull requests

3 participants