[release/9.0] JIT: Preserve range check for HW intrinsics with non-const/out-of-range immediates#107006
Merged
Merged
Conversation
Contributor
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
Contributor
Author
|
@tannergooding PTAL. I had to manually open this PR due to a merge conflict caused by the new flag in |
jeffschwMSFT
approved these changes
Aug 27, 2024
jeffschwMSFT
left a comment
Member
There was a problem hiding this comment.
approved. please get a code review. once ready we can merge
tannergooding
approved these changes
Aug 27, 2024
Contributor
Author
|
@jeffschwMSFT thank you for the review! Could you merge this when you have a moment, please? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Manual backport of #106765 to release/9.0
Customer Impact
Internal fuzz testing exposed multiple cases (#106608, #106546, etc) where the usage of a hardware intrinsic with an out-of-range, non-const immediate would throw an exception in Debug builds, but not in Release builds. In Debug builds, if the immediate is non-const, the JIT would convert the intrinsic into a user call with a range check. In Release, the JIT might be able to convert the immediate into a constant via later optimizations like forward substitution, so it wouldn't pessimistically convert the intrinsic into a user call during importation. However, the JIT wouldn't always emit a range check to represent the exceptional path in IR, so even if IR rationalization would eventually convert an intrinsic with an unknown immediate into a user call, earlier optimizations could optimize away the intrinsic completely, hence the Debug/Release diffs.
In .NET 10, we would like to add fallback intrinsic implementations for cases where the immediate is out-of-range or non-const, not only to eliminate Debug/Release diffs, but to also improve the usability and performance of these intrinsics in non-const immediate scenarios. However, the scope of this work is too large to target .NET 9. For now, this PR adjusts the JIT's importation logic for HW intrinsics to always emit a range check for non-const immediates, and to always convert to a user call if the immediate is known to be out-of-range.
While working on this, we noticed the JIT was calculating the vector count for some variants of
AdvSimd.StoreSelectedScalarincorrectly. The variants in question operate onValueTuplesofVectors, rather thanVectorsdirectly, so we had to add a special case to the importer to parse the intrinsic's SIMD size from theValueTupleargument.Regression
I'm not sure how long the potential for Debug/Release diffs for intrinsics with immediates has been possible. We found this problem after updating one of our fuzzing tools to generate tests with vectorized code. Since Roslyn already warns users to not use non-const immediates with intrinsics marked with
ConstantExpected, the code pattern required to trigger this issue is explicitly discouraged, thus decreasing the odds of encountering this. However,AdvSimd.StoreSelectedScalar's SIMD size calculation was regressed during the .NET 9 cycle when itsValueTupleoverloads were added in #93223.Testing
This fix includes regression tests picked from the generated programs that exposed this issue.
Risk
Low. The
StoreSelectedScalarfix is quite targeted; while there are other intrinsics withValueTuplearguments, their SIMD sizes are hard-coded, so the JIT doesn't need to go down the newly-addedValueTuplepath to parse the SIMD size at runtime. As for the range check fix, while this touches the common path for importing HW intrinsics across all supported platforms, the range check can be trivially optimized away by the JIT if the immediate is later known to be in-range, so code quality is not impacted. And as mentioned above, the usage of non-const immediates is likely uncommon in users' programs to begin with.