-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[CPAOT] Generating code for hardware intrinsic #26772
[CPAOT] Generating code for hardware intrinsic #26772
Conversation
63a56b7
to
a035d0a
Compare
src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs
Outdated
Show resolved
Hide resolved
src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
Outdated
Show resolved
Hide resolved
src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
Outdated
Show resolved
Hide resolved
Just to make sure we're talking about the same thing: are you porting #24689, #24917, ideally also #25365? Hardware intrinsics are not actually enabled unless all the We're stripping the intrinsic bit and marking them as non-inlineable in a single place. The non-inlinineability is just a precaution - since IsSupported calls are currently implemented to recursively call themselves, they won't get inlined. But this shouldn't inline even if that definition changes for some reason or if RyuJIT becomes smart and turns it into |
I wasn't aware of #25365, now I am.
Thanks for the catch, it was there when I did it on the CoreRT repo, and got drop accidentally when I port it over here. I will put it back and test again.
That is what I worried and not sure about. I just can't find that one place. Whatever that place is, it should be using
Here is my simple detector to check whether or not the JIT attempts to inline it or not. Adding this line right before here:
I believe any function that is compiled or inlined by the JIT must go through there, and if I spot any |
ed695fc
to
018fcbd
Compare
I'm referring to code that needs to be ported over. They should be ported from the crossgen codebase - look at the referenced pull requests.
You might be looking at a cross-version bubble inline (we block those, you need to run with large version bubble enabled etc.). Do not spend time on it, please just port over what crossgen does. |
Gotcha, I was confused earlier because I didn't know you were referring code that doesn't exist yet. Am I correct that you are suggesting the logic should be written here? In general, not being able to tell what I was doing is right or wrong is painful. I was trying all sort of ways to make the code reports whether or not I am doing the right thing or not. Even when I missed a bunch of flags, a whole collection of hardware intrinsics are compiled, compared to the version without change. (Maybe adding the flags will add even more, I will have to experiment tomorrow). |
Yep, it was painful when I was doing this for crossgen too. I ended up identifying a several methods of interest in CoreLib that use HW intrinsics, dumped them with r2r dump and validated that:
So overall you need to inspect:
Then also have another test where you inspect it does the expected thing outside CoreLib. |
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.
Looks great, modulo the 4 questions.
Maybe let's do the remaining two things in a separate pull request:
- Not generate these into non-CoreLib modules: a check that grabs
MethodBeingCompiled
, extracts the owning types' module, and compares it with_compilation.TypeSystemContext.SystemModule
might be enough (throw aRequiresRuntimeJitException
to abort compilation of the method). - Making sure Vector64/128/256 are not generated (unless CoreLib is part of the version bubble). This should be just a small shuffle in ReadyToRunCompilerContext.cs around line
VectorIntrinsicFieldLayoutAlgorithm.IsVectorType(type)
- we want to only return_vectorIntrinsicFieldLayoutAlgorithm
if CoreLib is in the version bubble. Otherwise we should return_vectorFieldLayoutAlgorithm
(which is the thing we use forVector<T>
and will conveniently throw RequiresRuntimeJit whenever the layout is needed).
src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
Show resolved
Hide resolved
src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
Outdated
Show resolved
Hide resolved
src/tools/crossgen2/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs
Show resolved
Hide resolved
…fo.cpp to CorInfoImpl.ReadyToRun.cs
5c15f2b
to
2899786
Compare
Some testing is in progress for validating this change:
Compiling
System.Private.CoreLib
with the assert causing failure in #12093 commented out. The compilation succeeded.R2RDump
verification of the generated binary.get_IsSupported
for x86/x64 hardware intrinsics are not pre-compiled (the ARM64 ones are generated, which is weird but doesn't hurt)get_IsSupported
.Below is a snippet showing the case where the hardware intrinsic instruction is generated and guarded by IsSupported with the fallback path generated as well:
test.cmd
- following the standard procedure, the test binaries are built. I replaced all copies ofSystem.Private.CoreLib.dll
compiled with crossgen with the one compiled with crossgen2 and ran all the tests, 3 tests out of 2600+ tests failed, and they were failing before my changes.CI passes
@dotnet/crossgen-contrib