Skip to content

Conversation

amanasifkhalid
Copy link
Contributor

Fixes #103252. In the (rare?) case where a BBJ_COND block still ends with a GT_JTRUE node post-layout and lowering, and reversing the block's condition would eliminate a jump, find the conditional IR preceding the GT_JTRUE node, and reverse its condition instead of trying to wrap the GT_JTRUE node in a GT_NOT, and triggering asserts.

@ghost ghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jun 11, 2024
Copy link
Contributor

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

Comment on lines 2480 to 2495
GenTree* test = block->lastNode();
assert(test->OperIsConditionalJump());

if (test->OperIs(GT_JTRUE))
{
// If we didn't lower a GT_JTRUE node to some conditional IR,
// search for the correct node to flip the condition on
do
{
test = test->gtPrev;
assert(test != nullptr);
} while (!test->OperIsCompare() && !test->OperIs(GT_SETCC));
}

GenTree* const cond = gtReverseCond(test);
assert(cond == test); // Ensure `gtReverseCond` did not create a new node
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is quite right. There is no invariant on the JTRUE node operand after lowering, so we do need to handle the GT_NOT inserted case (or just skip this optimization for these rare cases).

I think the code should rather be something like:

if (test->OperIs(GT_JTRUE))
{
  GenTree* const cond = gtReverseCond(test->gtGetOp1());
  if (cond != test->gtGetOp1())
  {
    LIR::AsRange(block).InsertAfter(test->gtGetOp1(), cond);
    test->AsUnOp()->gtOp1 = cond;
  }
}
else
{
  GenTree* const cond = gtReverseCond(test);
  assert(cond == test);
}

Skipping the transformation when the terminator node is not JCC, JCMP or JTEST would be fine to me as well.

It might be nice to add a stress mode that LowerJTrue uses to leave more JTRUEs in place (TryLowerConditionToFlagsNode is almost able to convert all JTRUEs today, as you pointed out).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see, thank you for the suggestion! Fixed.

It might be nice to add a stress mode that LowerJTrue uses to leave more JTRUEs in place (TryLowerConditionToFlagsNode is almost able to convert all JTRUEs today, as you pointed out).

I'll add a stress mode in a follow-up PR. The lack of diffs seems to further justify exercising these cases.

@amanasifkhalid
Copy link
Contributor Author

Failure is unrelated timeout. No diffs

@amanasifkhalid amanasifkhalid merged commit 332fbb4 into dotnet:main Jun 12, 2024
@amanasifkhalid amanasifkhalid deleted the post-layout-reverse-cond branch June 12, 2024 16:04
@github-actions github-actions bot locked and limited conversation to collaborators Jul 13, 2024
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.

JIT: Assertion failed 'cond == test' during 'Optimize post-layout'
2 participants