-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Fixing the InstructionSetDesc implications #86486
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
Fixing the InstructionSetDesc implications #86486
Conversation
|
CC. @jkotas, @davidwrighton This is the last bit to break apart from #85551 and will leave that as just the |
be5596a to
381f759
Compare
381f759 to
89b5aff
Compare
src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt
Outdated
Show resolved
Hide resolved
| implication ,X86 ,AVX512VBMI_VL ,AVX512VBMI | ||
| implication ,X86 ,AVX512VBMI_VL ,AVX512BW_VL | ||
|
|
||
| ; While the AVX-512 ISAs can be individually lit-up, they really |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davidwrighton Could you please review these new implications?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These implications don't entirely make sense to me. What they indicate is that if any of avx512cd, bw, f, bmi, or the vl variants are enabled, then all the various instruction sets will be considered to be enabled. If that's the case, then why do we need so many flags? I don't understand. In addition, if you're making the implications have this circular flow that isn't actually required by the flags the processor specifies, we need to treat them similarly in the avx512 detection logic in codeman.cpp. Thus, we can't enable ANY of the AVX512 support in the runtime unless all of the associated cpu flags are enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What they indicate is that if any of avx512cd, bw, f, bmi, or the vl variants are enabled, then all the various instruction sets will be considered to be enabled
Yes and the comment is meant to explain that, if you have any ideas on how to reword it then please feel free to suggest them.
If that's the case, then why do we need so many flags
We have an actual split in CPUID checks and in other corresponding logic that ties class names to flag names. We may also want to actually allow splitting this in the future, such as if we decide to support Knight's Landing or if some future hardware decides to only support a subset of AVX512.
In addition, if you're making the implications have this circular flow that isn't actually required by the flags the processor specifies, we need to treat them similarly in the avx512 detection logic in codeman.cpp
This is already handled in codeman by virtue of the:
CPUCompileFlags.Set64BitInstructionSetVariants();
CPUCompileFlags.EnsureValidInstructionSetSupport();
If Avx512F was supported but Avx512BW was not, then Avx512F would be turned off by the EnsureValidInstructionSetSupport call.
… work correctly for Vector128/256/512.IsHardwareAccelerated
MichalStrehovsky
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The NativeAOT smoke test change looks good. Thanks for extending the coverage!
src/tests/nativeaot/SmokeTests/HardwareIntrinsics/X64Avx512.csproj
Outdated
Show resolved
Hide resolved
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsExtracted from #85551
|
davidwrighton
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need a better explanation for what we're doing here. See my comments.
| optimisticInstructionSetSupportBuilder.AddSupportedInstructionSet("avxvnni"); | ||
| } | ||
|
|
||
| if (supportedInstructionSet.HasInstructionSet(InstructionSet.X64_AVX2)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoiding having avx2 be opportunistic because there are some potentially deeper problems and involvement with how it impacts Vector<T>, as you called out on the other PR.
AvxVnni inherits Avx2 and so it being opportunistic means that Avx2 is also opportunistic. This shipped that way in .NET 7 and so its possible there is some R2R issue there.
| if (isIsaSupported && comp->compSupportsHWIntrinsic(isa)) | ||
| { | ||
| if (comp->compExactlyDependsOn(isa)) | ||
| if (!comp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) || comp->compExactlyDependsOn(isa)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you explain what change is happening here? I don't see a description of what we're changing around NativeAOT behavior in the change description.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was an existing bug here that was surfaced if crossgen/naot targeted avx but not avx2
For most cases, the ISA initially checked and tracked as part of isIsaSupported is the same as what is tracked by the InstructionSetDesc
However, for Vector256 in particular we have the case where the implication is on Avx and we will accelerate some APIs when only Avx is supported. But, we only want IsHardwareAccelerated to report true when Avx2 is also supported.
We were then ending up in a scenario where we'd end up failing to handle IsHardwareAccelerated for the recursive case when avx was supported but avx2 was not because isIsaSupported (AVX) would be true and then we'd fail the compExactlyDependsOn check for AVX2 and then return NI_IsSupported_Dynamic, which was incorrect since avx2 was not opportunistic.
This fixes that so we now ensure that we only go down the true/dynamic path if the compiler could support AVX2 at all.
| implication ,X86 ,AVX512VBMI_VL ,AVX512VBMI | ||
| implication ,X86 ,AVX512VBMI_VL ,AVX512BW_VL | ||
|
|
||
| ; While the AVX-512 ISAs can be individually lit-up, they really |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These implications don't entirely make sense to me. What they indicate is that if any of avx512cd, bw, f, bmi, or the vl variants are enabled, then all the various instruction sets will be considered to be enabled. If that's the case, then why do we need so many flags? I don't understand. In addition, if you're making the implications have this circular flow that isn't actually required by the flags the processor specifies, we need to treat them similarly in the avx512 detection logic in codeman.cpp. Thus, we can't enable ANY of the AVX512 support in the runtime unless all of the associated cpu flags are enabled.
Extracted from #85551
This primarily handles ensuring the
InstructionSetDescimplications are correct. In particular it ensures thatAvx512Fis dependent on bothAVX2andFMA. It likewise ensures that the nestedVLclasses are dependent on both the baseVLclass and the containing class (e.g.Avx512BW.VLis dependent on bothAvx512BWandAvx512F.BW).It also adds a recursive implication that ensures that
F + BW + CD + DQ + VLare only ever enabled as a set. This is done to simplify the current implementation of the JIT without tying us to that behavior permanently. It would be non-trivial work and not "pay for play" to allow this to be represented as a single R2R flag instead.Finally, as part of fixing this there were a couple minor bugs surfaced. In particular,
avx-vnniwas marked as opportunistic which in turn markedavx2as opportunistic. This is problematic if the user decides to targetavxbut notavx2and was causingVector<T>andVector256<T>to behave incorrectly. This was handled by ensuringavx-vnniis only marked as opportunistic ifavx2is explicitly supported and ensuring that theNI_IsSupported_Dynamicis only returned for opportunistic APIs.Tests were added covering NAOT, CG2, and JIT validating that the full set of currently exposed ISAs behave correctly. This includes when users explicitly opt into or out-of a given ISA.