Skip to content
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

JIT: Support GT_SELECT on xarch #78879

Merged
merged 14 commits into from
Dec 1, 2022
Merged

Conversation

jakobbotsch
Copy link
Member

@jakobbotsch jakobbotsch commented Nov 26, 2022

Add support for conditional select to the xarch backend. Contained relops are not supported yet, so for now if-conversion will only produce these nodes under stress on xarch.

Add support for conditional select to the xarch backend. Contained
relops are not supported yet, so for now if-conversion will only produce
these nodes under stress on xarch.
@ghost ghost assigned jakobbotsch Nov 26, 2022
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Nov 26, 2022
@ghost
Copy link

ghost commented Nov 26, 2022

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Issue Details

Add support for conditional select to the xarch backend. Contained relops are not supported yet, so for now if-conversion will only produce these nodes under stress on xarch.

Author: jakobbotsch
Assignees: jakobbotsch
Labels:

area-CodeGen-coreclr

Milestone: -

@jakobbotsch
Copy link
Member Author

/azp run runtime-coreclr jitstress, runtime-coreclr libraries-jitstress

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@jakobbotsch
Copy link
Member Author

/azp run runtime-coreclr superpmi-diffs, runtime-coreclr jitstress, runtime-coreclr libraries-jitstress, runtime-coreclr jitstressregs, Fuzzlyn

@azure-pipelines
Copy link

Azure Pipelines successfully started running 5 pipeline(s).

Hit this in a test that uses DOTNET_JitOptRepeat=*.
This reverts commit c0e9751.
@jakobbotsch
Copy link
Member Author

This passed jitstress, libraries-jitstress, jitstressregs and Fuzzlyn with all the heuristics commented out from if-conversion (diffs). The failures were #78898, #78912, #78909 and a VN failure in a test using JitOptRepeat that is fixed.

cc @dotnet/jit-contrib PTAL @BruceForstall

@jakobbotsch jakobbotsch marked this pull request as ready for review November 28, 2022 20:20
// Arguments:
// select - the node
//
void CodeGen::genCodeForSelect(GenTreeOp* select)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preexisting, no change required here: wait, so GT_SELECT is a descendant of GenTreeOp, but the added gtCond operand comes first in the operand order? That does not seem like an exception worth making...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's a little odd. Probably we should just rename it to GenTreeSelect and have its operands inline. Or add GenTreeTernary and shift the operands.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, 'GenTreeTernary' with condition as op1, true path as op2 and false path as op3? That would probably make more sense, but it'll be annoying to fix them all up

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that would be the idea. Alternatively we make GenTreeTernary -> GenTreeSelect with gtCond, gtTrueVal and gtFalseVal fields.

@@ -4858,7 +4862,7 @@ bool Compiler::optIfConvert(BasicBlock* block)

// Create a select node.
GenTreeConditional* select =
gtNewConditionalNode(GT_SELECT, cond, asgNode->gtGetOp2(), falseInput, asgNode->TypeGet());
gtNewConditionalNode(GT_SELECT, cond, asgNode->gtGetOp2(), falseInput, genActualType(destination));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @a74nh, small bug fix here -- if the assignment is going to a small typed local it may have a small type, but this is not actually an allowed type on GT_SELECT. Instead this uses the type of the local itself (or TYP_INT if small), which should be compatible in the cases there is an implicit conversion (e.g. TYP_I_IMPL <-> TYP_BYREF).

Copy link
Contributor

@a74nh a74nh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the X64 specifics are a little opaque to me, but everything else reviewed.

#endif
void genCodeForSelect(GenTreeOp* select);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the switch to using GenTreeOp instead of GenTreeConditional ? Surely you'll always be passing a GenTreeConditional into it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GT_SELECT_HI node is just a GenTreeOp since it only has two operands. We could make it a GenTreeConditional with a null gtCond as an alternative, but it would require changing the visitor code also. I don't have a super strong opinion on it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine - leave it as is.

// Return Value:
// The next node to process.
//
GenTree* DecomposeLongs::DecomposeSelect(LIR::Use& use)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I right in thinking this will only happen on X64 (and not Arm64) ?

Copy link
Member Author

@jakobbotsch jakobbotsch Nov 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decomposition is only for 32-bit targets, so only on x86 (and arm32 if it supported GT_SELECT).

// other flag producing nodes and reuse them. GT_SELECT_HI is the variant
// that uses existing flags and has no condition as part of it.
select->gtFlags |= GTF_SET_FLAGS;
GenTree* hiSelect = m_compiler->gtNewOperNode(GT_SELECT_HI, TYP_INT, hiOp1, hiOp2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there something to ensure that the GT_SELECT_HI is contained within the GT_SELECT ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no containment here, decomposition has the implicit assumption that nothing after it introduces nodes that clobber flags between the nodes it inserts that have that kind of dependency. It's not pretty but it ends up working since it has control over the exact linear order of these dependencies.

@jakobbotsch
Copy link
Member Author

ping @BruceForstall

The failure looks like #78251 (added a known build error for it).

Copy link
Member

@BruceForstall BruceForstall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@BruceForstall BruceForstall merged commit ea060e6 into dotnet:main Dec 1, 2022
@jakobbotsch jakobbotsch deleted the xarch-GT_SELECT branch December 1, 2022 11:39
@ghost ghost locked as resolved and limited conversation to collaborators Dec 31, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants