Skip to content

Commit

Permalink
JIT: Transform SELECT(relop, 1/0, 0/1) to relop (#81880)
Browse files Browse the repository at this point in the history
Fix #81479
  • Loading branch information
jakobbotsch authored Feb 9, 2023
1 parent fe16076 commit d0fdb17
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
50 changes: 48 additions & 2 deletions src/coreclr/jit/lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,7 @@ GenTree* Lowering::LowerNode(GenTree* node)
#endif
break;
case GT_SELECT:
ContainCheckSelect(node->AsConditional());
break;
return LowerSelect(node->AsConditional());

#ifdef TARGET_X86
case GT_SELECT_HI:
Expand Down Expand Up @@ -3280,6 +3279,53 @@ GenTree* Lowering::LowerJTrue(GenTreeOp* jtrue)
return nullptr;
}

//----------------------------------------------------------------------------------------------
// LowerSelect: Lower a GT_SELECT node.
//
// Arguments:
// select - The node
//
// Return Value:
// The next node to lower.
//
GenTree* Lowering::LowerSelect(GenTreeConditional* select)
{
GenTree* cond = select->gtCond;
GenTree* trueVal = select->gtOp1;
GenTree* falseVal = select->gtOp2;

// Replace SELECT cond 1/0 0/1 with (perhaps reversed) cond
if (cond->OperIsCompare() && ((trueVal->IsIntegralConst(0) && falseVal->IsIntegralConst(1)) ||
(trueVal->IsIntegralConst(1) && falseVal->IsIntegralConst(0))))
{
assert(select->TypeIs(TYP_INT, TYP_LONG));

LIR::Use use;
if (BlockRange().TryGetUse(select, &use))
{
if (trueVal->IsIntegralConst(0))
{
GenTree* reversed = comp->gtReverseCond(cond);
assert(reversed == cond);
}

// Codegen supports also TYP_LONG typed compares so we can just
// retype the compare instead of inserting a cast.
cond->gtType = select->TypeGet();

BlockRange().Remove(trueVal);
BlockRange().Remove(falseVal);
BlockRange().Remove(select);
use.ReplaceWith(cond);

return cond->gtNext;
}
}

ContainCheckSelect(select);
return select->gtNext;
}

//----------------------------------------------------------------------------------------------
// LowerNodeCC: Lowers a node that produces a boolean value by setting the condition flags.
//
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class Lowering final : public Phase
GenTree* OptimizeConstCompare(GenTree* cmp);
GenTree* LowerCompare(GenTree* cmp);
GenTree* LowerJTrue(GenTreeOp* jtrue);
GenTree* LowerSelect(GenTreeConditional* cond);
GenTreeCC* LowerNodeCC(GenTree* node, GenCondition condition);
void LowerJmpMethod(GenTree* jmp);
void LowerRet(GenTreeUnOp* ret);
Expand Down

0 comments on commit d0fdb17

Please sign in to comment.