[llvm] r299266 - [DAGCombiner] refactor and/or-of-setcc to get rid of duplicated code; NFCI
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 31 14:30:50 PDT 2017
Author: spatel
Date: Fri Mar 31 16:30:50 2017
New Revision: 299266
URL: http://llvm.org/viewvc/llvm-project?rev=299266&view=rev
Log:
[DAGCombiner] refactor and/or-of-setcc to get rid of duplicated code; NFCI
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=299266&r1=299265&r2=299266&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Mar 31 16:30:50 2017
@@ -350,8 +350,8 @@ namespace {
bool NotExtCompare = false);
SDValue foldSelectCCToShiftAnd(const SDLoc &DL, SDValue N0, SDValue N1,
SDValue N2, SDValue N3, ISD::CondCode CC);
- SDValue foldAndOfSetCCs(SDValue N0, SDValue N1, const SDLoc &DL);
- SDValue foldOrOfSetCCs(SDValue N0, SDValue N1, const SDLoc &DL);
+ SDValue foldLogicOfSetCCs(bool IsAnd, SDValue N0, SDValue N1,
+ const SDLoc &DL);
SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond,
const SDLoc &DL, bool foldBooleans = true);
@@ -3172,23 +3172,23 @@ SDValue DAGCombiner::SimplifyBinOpWithSa
return SDValue();
}
-/// Try to make (and setcc (LL, LR), setcc (RL, RR)) more efficient.
-SDValue DAGCombiner::foldAndOfSetCCs(SDValue N0, SDValue N1, const SDLoc &DL) {
- // FIXME: This should be refactored with foldOrOfSetCCs.
+/// Try to make (and/or setcc (LL, LR), setcc (RL, RR)) more efficient.
+SDValue DAGCombiner::foldLogicOfSetCCs(bool IsAnd, SDValue N0, SDValue N1,
+ const SDLoc &DL) {
SDValue LL, LR, RL, RR, N0CC, N1CC;
if (!isSetCCEquivalent(N0, LL, LR, N0CC) ||
!isSetCCEquivalent(N1, RL, RR, N1CC))
return SDValue();
assert(N0.getValueType() == N1.getValueType() &&
- "Unexpected operand types for 'and' op");
+ "Unexpected operand types for bitwise logic op");
assert(LL.getValueType() == LR.getValueType() &&
RL.getValueType() == RR.getValueType() &&
"Unexpected operand types for setcc");
- // If we're here post-legalization or the 'and' is not i1, the 'and' type must
- // match a setcc result type. Also, all folds require new operations on the
- // left and right operands, so those types must match.
+ // If we're here post-legalization or the logic op type is not i1, the logic
+ // op type must match a setcc result type. Also, all folds require new
+ // operations on the left and right operands, so those types must match.
EVT VT = N0.getValueType();
EVT OpVT = LL.getValueType();
if (LegalOperations || VT != MVT::i1)
@@ -3201,31 +3201,47 @@ SDValue DAGCombiner::foldAndOfSetCCs(SDV
ISD::CondCode CC1 = cast<CondCodeSDNode>(N1CC)->get();
bool IsInteger = OpVT.isInteger();
if (LR == RR && CC0 == CC1 && IsInteger) {
- // All bits cleared?
+ // All bits set?
+ bool AndEqNeg1 = IsAnd && CC1 == ISD::SETEQ && isAllOnesConstant(LR);
+ // All sign bits clear?
+ bool AndGtNeg1 = IsAnd && CC1 == ISD::SETGT && isAllOnesConstant(LR);
+ // All bits clear?
+ bool AndEqZero = IsAnd && CC1 == ISD::SETEQ && isNullConstant(LR);
+ // All sign bits set?
+ bool AndLtZero = IsAnd && CC1 == ISD::SETLT && isNullConstant(LR);
+ // Any bits clear?
+ bool OrNeNeg1 = !IsAnd && CC1 == ISD::SETNE && isAllOnesConstant(LR);
+ // Any sign bits clear?
+ bool OrGtNeg1 = !IsAnd && CC1 == ISD::SETGT && isAllOnesConstant(LR);
+ // Any bits set?
+ bool OrNeZero = !IsAnd && CC1 == ISD::SETNE && isNullConstant(LR);
+ // Any sign bits set?
+ bool OrLtZero = !IsAnd && CC1 == ISD::SETLT && isNullConstant(LR);
+
// (and (seteq X, 0), (seteq Y, 0)) --> (seteq (or X, Y), 0)
- // All sign bits cleared?
// (and (setgt X, -1), (setgt Y, -1)) --> (setgt (or X, Y), -1)
- if ((isNullConstant(LR) && CC1 == ISD::SETEQ) ||
- (isAllOnesConstant(LR) && CC1 == ISD::SETGT)) {
+ // (or (setne X, 0), (setne Y, 0)) --> (setne (or X, Y), 0)
+ // (or (setlt X, 0), (setlt Y, 0)) --> (setlt (or X, Y), 0)
+ if (AndEqZero || AndGtNeg1 || OrNeZero || OrLtZero) {
SDValue Or = DAG.getNode(ISD::OR, SDLoc(N0), OpVT, LL, RL);
AddToWorklist(Or.getNode());
return DAG.getSetCC(DL, VT, Or, LR, CC1);
}
- // All bits set?
// (and (seteq X, -1), (seteq Y, -1)) --> (seteq (and X, Y), -1)
- // All sign bits set?
// (and (setlt X, 0), (setlt Y, 0)) --> (setlt (and X, Y), 0)
- if ((isAllOnesConstant(LR) && CC1 == ISD::SETEQ) ||
- (isNullConstant(LR) && CC1 == ISD::SETLT)) {
+ // (or (setne X, -1), (setne Y, -1)) --> (setne (and X, Y), -1)
+ // (or (setgt X, -1), (setgt Y -1)) --> (setgt (and X, Y), -1)
+ if (AndEqNeg1 || AndLtZero || OrNeNeg1 || OrGtNeg1) {
SDValue And = DAG.getNode(ISD::AND, SDLoc(N0), OpVT, LL, RL);
AddToWorklist(And.getNode());
return DAG.getSetCC(DL, VT, And, LR, CC1);
}
}
+ // TODO: What is the 'or' equivalent of this fold?
// (and (setne X, 0), (setne X, -1)) --> (setuge (add X, 1), 2)
- if (LL == RL && CC0 == CC1 && IsInteger && CC0 == ISD::SETNE &&
+ if (IsAnd && LL == RL && CC0 == CC1 && IsInteger && CC0 == ISD::SETNE &&
((isNullConstant(LR) && isAllOnesConstant(RR)) ||
(isAllOnesConstant(LR) && isNullConstant(RR)))) {
SDValue One = DAG.getConstant(1, DL, OpVT);
@@ -3242,8 +3258,10 @@ SDValue DAGCombiner::foldAndOfSetCCs(SDV
}
// (and (setcc X, Y, CC0), (setcc X, Y, CC1)) --> (setcc X, Y, NewCC)
+ // (or (setcc X, Y, CC0), (setcc X, Y, CC1)) --> (setcc X, Y, NewCC)
if (LL == RL && LR == RR) {
- ISD::CondCode NewCC = ISD::getSetCCAndOperation(CC0, CC1, IsInteger);
+ ISD::CondCode NewCC = IsAnd ? ISD::getSetCCAndOperation(CC0, CC1, IsInteger)
+ : ISD::getSetCCOrOperation(CC0, CC1, IsInteger);
if (NewCC != ISD::SETCC_INVALID &&
(!LegalOperations ||
(TLI.isCondCodeLegal(NewCC, LL.getSimpleValueType()) &&
@@ -3266,7 +3284,7 @@ SDValue DAGCombiner::visitANDLike(SDValu
if (N0.isUndef() || N1.isUndef())
return DAG.getConstant(0, DL, VT);
- if (SDValue V = foldAndOfSetCCs(N0, N1, DL))
+ if (SDValue V = foldLogicOfSetCCs(true, N0, N1, DL))
return V;
if (N0.getOpcode() == ISD::ADD && N1.getOpcode() == ISD::SRL &&
@@ -3972,75 +3990,6 @@ SDValue DAGCombiner::MatchBSwapHWord(SDN
DAG.getNode(ISD::SRL, DL, VT, BSwap, ShAmt));
}
-
-/// Try to make (or setcc (LL, LR), setcc (RL, RR)) more efficient.
-SDValue DAGCombiner::foldOrOfSetCCs(SDValue N0, SDValue N1, const SDLoc &DL) {
- // FIXME: This should be refactored with foldAndOfSetCCs.
- SDValue LL, LR, RL, RR, N0CC, N1CC;
- if (!isSetCCEquivalent(N0, LL, LR, N0CC) ||
- !isSetCCEquivalent(N1, RL, RR, N1CC))
- return SDValue();
-
- assert(N0.getValueType() == N1.getValueType() &&
- "Unexpected operand types for 'or' op");
- assert(LL.getValueType() == LR.getValueType() &&
- RL.getValueType() == RR.getValueType() &&
- "Unexpected operand types for setcc");
-
- // If we're here post-legalization or the 'or' is not i1, the 'or' type must
- // match a setcc result type. Also, all folds require new operations on the
- // left and right operands, so those types must match.
- EVT VT = N0.getValueType();
- EVT OpVT = LL.getValueType();
- if (LegalOperations || VT != MVT::i1)
- if (VT != getSetCCResultType(OpVT))
- return SDValue();
- if (OpVT != RL.getValueType())
- return SDValue();
-
- ISD::CondCode CC0 = cast<CondCodeSDNode>(N0CC)->get();
- ISD::CondCode CC1 = cast<CondCodeSDNode>(N1CC)->get();
- bool IsInteger = OpVT.isInteger();
- if (LR == RR && CC0 == CC1 && IsInteger) {
- // Any bits set?
- // (or (setne X, 0), (setne Y, 0)) --> (setne (or X, Y), 0)
- // Any sign bits set?
- // (or (setlt X, 0), (setlt Y, 0)) --> (setlt (or X, Y), 0)
- if (isNullConstant(LR) && (CC1 == ISD::SETNE || CC1 == ISD::SETLT)) {
- SDValue Or = DAG.getNode(ISD::OR, SDLoc(N0), OpVT, LL, RL);
- AddToWorklist(Or.getNode());
- return DAG.getSetCC(DL, VT, Or, LR, CC1);
- }
- // Any bits clear?
- // (or (setne X, -1), (setne Y, -1)) --> (setne (and X, Y), -1)
- // Any sign bits clear?
- // (or (setgt X, -1), (setgt Y -1)) --> (setgt (and X, Y), -1)
- if (isAllOnesConstant(LR) && (CC1 == ISD::SETNE || CC1 == ISD::SETGT)) {
- SDValue And = DAG.getNode(ISD::AND, SDLoc(N0), OpVT, LL, RL);
- AddToWorklist(And.getNode());
- return DAG.getSetCC(DL, VT, And, LR, CC1);
- }
- }
-
- // Canonicalize equivalent operands to LL == RL.
- if (LL == RR && LR == RL) {
- CC1 = ISD::getSetCCSwappedOperands(CC1);
- std::swap(RL, RR);
- }
-
- // (or (setcc X, Y, CC0), (setcc X, Y, CC1)) --> (setcc X, Y, NewCC)
- if (LL == RL && LR == RR) {
- ISD::CondCode NewCC = ISD::getSetCCOrOperation(CC0, CC1, IsInteger);
- if (NewCC != ISD::SETCC_INVALID &&
- (!LegalOperations ||
- (TLI.isCondCodeLegal(NewCC, LL.getSimpleValueType()) &&
- TLI.isOperationLegal(ISD::SETCC, OpVT))))
- return DAG.getSetCC(DL, VT, LL, LR, NewCC);
- }
-
- return SDValue();
-}
-
/// This contains all DAGCombine rules which reduce two values combined by
/// an Or operation to a single value \see visitANDLike().
SDValue DAGCombiner::visitORLike(SDValue N0, SDValue N1, SDNode *N) {
@@ -4051,7 +4000,7 @@ SDValue DAGCombiner::visitORLike(SDValue
if (!LegalOperations && (N0.isUndef() || N1.isUndef()))
return DAG.getAllOnesConstant(DL, VT);
- if (SDValue V = foldOrOfSetCCs(N0, N1, DL))
+ if (SDValue V = foldLogicOfSetCCs(false, N0, N1, DL))
return V;
// (or (and X, C1), (and Y, C2)) -> (and (or X, Y), C3) if possible.
More information about the llvm-commits
mailing list