Improve handling of immediate mode arguments · Issue #248 · rust-lang/stdarch (original) (raw)

Many intrinsics take immediate more argument (that is, some arguments must be compile-time constants).

We currently implement them by taking these arguments as run-time values, and "converting" them to compile-time values using a match statement with a match arm for each particular case:

fn foo(imm8: u8) { match imm8 { 0 => foo_(0), 1 => foo_(1), ... 256 match arms later ... u8::MAX => foo_(u8::MAX), } }

If a user pass them a compile-time value the optimizer can select the appropriate match arm and remove the rest of the code.

Passing them a run-time value should generate an error, but with this approach the compiler silently accepts this code, and generates code for all match arms, potentially making binary sizes / compile-times explode.

Even when the user passes a compile-time constant to the immediate arguments, some intrinsics (AMD loves these) require match statements with >= 65k arms that destroy compile-times in all cases (from 2x to 3x increase in compile-times of the whole stdsimd test suite if one of this functions is used somewhere). The following intrinsics have such extremely large match arms:

This issue blocks completing SSE4a in #40 and fixing #26 . It was previously discussed in #190 but never got an issue of its own.

Amongst the proposed solutions were to either implement these in the compilers or wait till const generics + extensions arrive (e.g. foo(x: const i8) to require x to be a compile-time constant).