-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Move GetMethodTable and IsReference to JIT #88860
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsMoves the simple and most important RuntimeHelpers intrinsics to the JIT. Extracted from #88543.
|
src/coreclr/jit/assertionprop.cpp
Outdated
@@ -4699,6 +4699,17 @@ GenTree* Compiler::optAssertionProp_Update(GenTree* newTree, GenTree* tree, Stat | |||
if (parent != nullptr) | |||
{ | |||
parent->ReplaceOperand(useEdge, newTree); | |||
if ((parent->gtOper == GT_IND) && newTree->IsIconHandle()) |
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 has changed that requires modifying assertion prop?
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.
VN can fold the method table indir to a constant handle which this place then replaces indirs on such method table with. This causes an assert in fgdiagnostic
to fire complaining about the indir missing the invariant and nonfaulting flags.
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.
But why couldn't this also happen without your changes? Is VN able to recognize something in your expansions but not the inlined IL intrinsics?
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.
Yes, so basically we had IND(IND(knownObj))
and the inner IND(knonwObj)
was folded by assertprop (with help of VN) to a CLASS_HANDLE
so now we have IND(CLASS_HANDLE)
but without proper flags (it's not really a correctness issue, more like annoying requirement from the fgdiagnostic)
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.
Is VN able to recognize something in your expansions but not the inlined IL intrinsics?
I'd assume it's not able to recognize the field address + subtract magic there.
But why couldn't this also happen without your changes?
I think this should reproduce with any indir over the method table returned from gtNewMethodTableLookup
, seems like nothing does that today though.
crossgen crashing during the build with:
|
parent->ReplaceOperand(useEdge, newTree); | ||
parent->gtFlags |= gtGetFlagsForOperand(parent->gtOper, newTree); |
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.
This flag updating call should be moved to this place in morph:
runtime/src/coreclr/jit/morph.cpp
Lines 9568 to 9571 in 7980417
if (op1->IsIconHandle(GTF_ICON_OBJ_HDL)) | |
{ | |
tree->gtFlags |= (GTF_IND_INVARIANT | GTF_IND_NONFAULTING | GTF_IND_NONNULL); | |
} |
GenTreeFlags flags = GTF_EMPTY; | ||
if ((oper == GT_IND) && op->IsIconHandle()) | ||
{ | ||
flags |= GTF_IND_NONFAULTING; | ||
|
||
GenTreeFlags handleKind = op->GetIconHandleFlag(); | ||
if ((handleKind != GTF_ICON_STATIC_HDL) && (handleKind != GTF_ICON_BBC_PTR) && | ||
(handleKind != GTF_ICON_GLOBAL_PTR)) | ||
{ | ||
flags |= GTF_IND_INVARIANT; | ||
} | ||
} |
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.
This invariantness setting is fragile; it does not check what type is being loaded.
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.
Yes, I had the same concern - like why do we expect invariantess if we acess a byte location with long type
@@ -8214,6 +8240,7 @@ GenTreeBlk* Compiler::gtNewBlkIndir(ClassLayout* layout, GenTree* addr, GenTreeF | |||
// | |||
GenTreeIndir* Compiler::gtNewIndir(var_types typ, GenTree* addr, GenTreeFlags indirFlags) | |||
{ | |||
indirFlags |= gtGetFlagsForOperand(GT_IND, addr); |
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.
Why is this needed here? The caller is expected to pass the right indirFlags
.
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 bet it's not needed it's just how @MichalPetryka was trying to find the case where it's not set (turned out be assertprop)
Hi @MichalPetryka, this is a kindly reminder. The .NET 8 RC1 snap is one week away. |
@MichalPetryka, I am moving this to .NET 9 because it is too late for .NET 8. |
@MichalPetryka Can you mark this "Draft" until it is ready for review again? |
This pull request has been automatically marked |
This pull request will now be closed since it had been marked |
Moves the simple and most important RuntimeHelpers intrinsics to the JIT.
Extracted from #88543.