Many ARM64 AdvSimd intrinsics encode immediate arguments directly into the instruction, and thus require them to be in-range and constant. If the immediate is not constant, the JIT may emit a jump table to handle every valid value, and if the immediate is not in-range, we expect an ArgumentOutOfRangeException to be thrown at runtime. Some intrinsics can be trivially re-implemented such that the immediate does not need to be constant or within a relatively narrow range; some AdvSimd.Shift* intrinsics already have such fallbacks in Compiler::impNonConstFallback.
An intrinsic that is given a range check in unoptimized codegen might be trivially foldable in optimized codegen; we've run into multiple Debug/Release behavioral diff bugs during the .NET 9 dev cycle due to this. The .NET 9 solution is to always insert a range check if the immediate is not constant, or out-of-range. For .NET 10, it would be more performant to implement fallbacks for intrinsics that have clear alternatives. See #106546 (comment) for motivating discussion.
Before tackling this, it might be a good idea to triage the 700+ AdvSimd intrinsics with the ConstantExpected attribute to build a list of intrinsics with fallback implementations worth pursuing.
Many ARM64
AdvSimd
intrinsics encode immediate arguments directly into the instruction, and thus require them to be in-range and constant. If the immediate is not constant, the JIT may emit a jump table to handle every valid value, and if the immediate is not in-range, we expect anArgumentOutOfRangeException
to be thrown at runtime. Some intrinsics can be trivially re-implemented such that the immediate does not need to be constant or within a relatively narrow range; someAdvSimd.Shift*
intrinsics already have such fallbacks inCompiler::impNonConstFallback
.An intrinsic that is given a range check in unoptimized codegen might be trivially foldable in optimized codegen; we've run into multiple Debug/Release behavioral diff bugs during the .NET 9 dev cycle due to this. The .NET 9 solution is to always insert a range check if the immediate is not constant, or out-of-range. For .NET 10, it would be more performant to implement fallbacks for intrinsics that have clear alternatives. See #106546 (comment) for motivating discussion.
Before tackling this, it might be a good idea to triage the 700+
AdvSimd
intrinsics with theConstantExpected
attribute to build a list of intrinsics with fallback implementations worth pursuing.cc @dotnet/jit-contrib