-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
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 ,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
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
|
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 (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 ,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
InstructionSetDesc
implications are correct. In particular it ensures thatAvx512F
is dependent on bothAVX2
andFMA
. It likewise ensures that the nestedVL
classes are dependent on both the baseVL
class and the containing class (e.g.Avx512BW.VL
is dependent on bothAvx512BW
andAvx512F.BW
).It also adds a recursive implication that ensures that
F + BW + CD + DQ + VL
are 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-vnni
was marked as opportunistic which in turn markedavx2
as opportunistic. This is problematic if the user decides to targetavx
but notavx2
and was causingVector<T>
andVector256<T>
to behave incorrectly. This was handled by ensuringavx-vnni
is only marked as opportunistic ifavx2
is explicitly supported and ensuring that theNI_IsSupported_Dynamic
is 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.