forked from OSchip/llvm-project
[X86] combineSelect - refactor MIN/MAX detection code to make it easier to add additional select(setcc,x,y) folds. NFCI.
I need to add some additional handling to address some of the regressions from D101074
This commit is contained in:
parent
5b3cb31edb
commit
cdb4fcf9a1
|
@ -41796,41 +41796,44 @@ static SDValue combineSelect(SDNode *N, SelectionDAG &DAG,
|
|||
if (SDValue V = combineSelectOfTwoConstants(N, DAG))
|
||||
return V;
|
||||
|
||||
// Canonicalize min/max:
|
||||
// (x > 0) ? x : 0 -> (x >= 0) ? x : 0
|
||||
// (x < -1) ? x : -1 -> (x <= -1) ? x : -1
|
||||
// This allows use of COND_S / COND_NS (see TranslateX86CC) which eliminates
|
||||
// the need for an extra compare against zero. e.g.
|
||||
// (a - b) > 0 : (a - b) ? 0 -> (a - b) >= 0 : (a - b) ? 0
|
||||
// subl %esi, %edi
|
||||
// testl %edi, %edi
|
||||
// movl $0, %eax
|
||||
// cmovgl %edi, %eax
|
||||
// =>
|
||||
// xorl %eax, %eax
|
||||
// subl %esi, $edi
|
||||
// cmovsl %eax, %edi
|
||||
//
|
||||
// We can also canonicalize
|
||||
// (x s> 1) ? x : 1 -> (x s>= 1) ? x : 1 -> (x s> 0) ? x : 1
|
||||
// (x u> 1) ? x : 1 -> (x u>= 1) ? x : 1 -> (x != 0) ? x : 1
|
||||
// This allows the use of a test instruction for the compare.
|
||||
if (N->getOpcode() == ISD::SELECT && Cond.getOpcode() == ISD::SETCC &&
|
||||
Cond.hasOneUse() &&
|
||||
LHS == Cond.getOperand(0) && RHS == Cond.getOperand(1)) {
|
||||
Cond.hasOneUse()) {
|
||||
EVT CondVT = Cond.getValueType();
|
||||
SDValue Cond0 = Cond.getOperand(0);
|
||||
SDValue Cond1 = Cond.getOperand(1);
|
||||
ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get();
|
||||
if ((CC == ISD::SETGT && (isNullConstant(RHS) || isOneConstant(RHS))) ||
|
||||
(CC == ISD::SETLT && isAllOnesConstant(RHS))) {
|
||||
ISD::CondCode NewCC = CC == ISD::SETGT ? ISD::SETGE : ISD::SETLE;
|
||||
Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
|
||||
Cond.getOperand(0), Cond.getOperand(1), NewCC);
|
||||
return DAG.getSelect(DL, VT, Cond, LHS, RHS);
|
||||
}
|
||||
if (CC == ISD::SETUGT && isOneConstant(RHS)) {
|
||||
ISD::CondCode NewCC = ISD::SETUGE;
|
||||
Cond = DAG.getSetCC(SDLoc(Cond), Cond.getValueType(),
|
||||
Cond.getOperand(0), Cond.getOperand(1), NewCC);
|
||||
return DAG.getSelect(DL, VT, Cond, LHS, RHS);
|
||||
|
||||
// Canonicalize min/max:
|
||||
// (x > 0) ? x : 0 -> (x >= 0) ? x : 0
|
||||
// (x < -1) ? x : -1 -> (x <= -1) ? x : -1
|
||||
// This allows use of COND_S / COND_NS (see TranslateX86CC) which eliminates
|
||||
// the need for an extra compare against zero. e.g.
|
||||
// (a - b) > 0 : (a - b) ? 0 -> (a - b) >= 0 : (a - b) ? 0
|
||||
// subl %esi, %edi
|
||||
// testl %edi, %edi
|
||||
// movl $0, %eax
|
||||
// cmovgl %edi, %eax
|
||||
// =>
|
||||
// xorl %eax, %eax
|
||||
// subl %esi, $edi
|
||||
// cmovsl %eax, %edi
|
||||
//
|
||||
// We can also canonicalize
|
||||
// (x s> 1) ? x : 1 -> (x s>= 1) ? x : 1 -> (x s> 0) ? x : 1
|
||||
// (x u> 1) ? x : 1 -> (x u>= 1) ? x : 1 -> (x != 0) ? x : 1
|
||||
// This allows the use of a test instruction for the compare.
|
||||
if (LHS == Cond0 && RHS == Cond1) {
|
||||
if ((CC == ISD::SETGT && (isNullConstant(RHS) || isOneConstant(RHS))) ||
|
||||
(CC == ISD::SETLT && isAllOnesConstant(RHS))) {
|
||||
ISD::CondCode NewCC = CC == ISD::SETGT ? ISD::SETGE : ISD::SETLE;
|
||||
Cond = DAG.getSetCC(SDLoc(Cond), CondVT, Cond0, Cond1, NewCC);
|
||||
return DAG.getSelect(DL, VT, Cond, LHS, RHS);
|
||||
}
|
||||
if (CC == ISD::SETUGT && isOneConstant(RHS)) {
|
||||
ISD::CondCode NewCC = ISD::SETUGE;
|
||||
Cond = DAG.getSetCC(SDLoc(Cond), CondVT, Cond0, Cond1, NewCC);
|
||||
return DAG.getSelect(DL, VT, Cond, LHS, RHS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue