summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2016-05-09 16:42:50 +0000
committerSanjay Patel <spatel@rotateright.com>2016-05-09 16:42:50 +0000
commit91592568f93ee77e3670387a18b4916278e7be5f (patch)
treebdf1c534f794cc8d9d10974569f76794ad3a5e0d /llvm
parent0a81921cdb9d19672a2522069fb5a26738adf210 (diff)
downloadbcm5719-llvm-91592568f93ee77e3670387a18b4916278e7be5f.tar.gz
bcm5719-llvm-91592568f93ee77e3670387a18b4916278e7be5f.zip
[TargetLowering] make helper function for SetCC + and optimizations (NFC)
After looking at D19087 again, it occurred to me that we can do better. If we consolidate the valueHasExactlyOneBitSet() transforms, we won't incur extra overhead from calling it a 2nd time, and we can shrink SimplifySetCC() a bit. No functional change intended. Differential Revision: http://reviews.llvm.org/D20050 llvm-svn: 268932
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Target/TargetLowering.h5
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp92
2 files changed, 45 insertions, 52 deletions
diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h
index ea7ef5d4db6..c47e3c0d963 100644
--- a/llvm/include/llvm/Target/TargetLowering.h
+++ b/llvm/include/llvm/Target/TargetLowering.h
@@ -3018,6 +3018,11 @@ public:
/// Lower TLS global address SDNode for target independent emulated TLS model.
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA,
SelectionDAG &DAG) const;
+
+private:
+ SDValue simplifySetCCWithAnd(EVT VT, SDValue N0, SDValue N1,
+ ISD::CondCode Cond, DAGCombinerInfo &DCI,
+ SDLoc DL) const;
};
/// Given an LLVM IR type and return type attributes, compute the return value
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 6faad8b8151..7010347f12a 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -1304,18 +1304,20 @@ bool TargetLowering::isExtendedTrueVal(const ConstantSDNode *N, EVT VT,
llvm_unreachable("Unexpected enumeration.");
}
-/// If the target supports an 'and-not' or 'and-complement' logic operation,
-/// try to use that to make a comparison operation more efficient.
-static SDValue createAndNotSetCC(EVT VT, SDValue N0, SDValue N1,
- ISD::CondCode Cond, SelectionDAG &DAG,
- SDLoc dl) {
+/// This helper function of SimplifySetCC tries to optimize the comparison when
+/// either operand of the SetCC node is a bitwise-and instruction.
+SDValue TargetLowering::simplifySetCCWithAnd(EVT VT, SDValue N0, SDValue N1,
+ ISD::CondCode Cond,
+ DAGCombinerInfo &DCI,
+ SDLoc DL) const {
// Match these patterns in any of their permutations:
// (X & Y) == Y
// (X & Y) != Y
if (N1.getOpcode() == ISD::AND && N0.getOpcode() != ISD::AND)
std::swap(N0, N1);
- if (N0.getOpcode() != ISD::AND || !N0.hasOneUse() ||
+ EVT OpVT = N0.getValueType();
+ if (N0.getOpcode() != ISD::AND || !OpVT.isInteger() ||
(Cond != ISD::SETEQ && Cond != ISD::SETNE))
return SDValue();
@@ -1330,24 +1332,37 @@ static SDValue createAndNotSetCC(EVT VT, SDValue N0, SDValue N1,
return SDValue();
}
- // Bail out if the compare operand that we want to turn into a zero is already
- // a zero (otherwise, infinite loop).
- auto *YConst = dyn_cast<ConstantSDNode>(Y);
- if (YConst && YConst->isNullValue())
- return SDValue();
-
- // We don't want to do this transform if the mask is a single bit because
- // there are more efficient ways to deal with that case (for example, 'bt' on
- // x86 or 'rlwinm' on PPC).
- if (!DAG.getTargetLoweringInfo().hasAndNotCompare(Y) ||
- valueHasExactlyOneBitSet(Y, DAG))
- return SDValue();
+ SelectionDAG &DAG = DCI.DAG;
+ SDValue Zero = DAG.getConstant(0, DL, OpVT);
+ if (valueHasExactlyOneBitSet(Y, DAG)) {
+ // Simplify X & Y == Y to X & Y != 0 if Y has exactly one bit set.
+ // Note that where Y is variable and is known to have at most one bit set
+ // (for example, if it is Z & 1) we cannot do this; the expressions are not
+ // equivalent when Y == 0.
+ Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
+ if (DCI.isBeforeLegalizeOps() ||
+ isCondCodeLegal(Cond, N0.getSimpleValueType()))
+ return DAG.getSetCC(DL, VT, N0, Zero, Cond);
+ } else if (N0.hasOneUse() && hasAndNotCompare(Y)) {
+ // If the target supports an 'and-not' or 'and-complement' logic operation,
+ // try to use that to make a comparison operation more efficient.
+ // But don't do this transform if the mask is a single bit because there are
+ // more efficient ways to deal with that case (for example, 'bt' on x86 or
+ // 'rlwinm' on PPC).
+
+ // Bail out if the compare operand that we want to turn into a zero is
+ // already a zero (otherwise, infinite loop).
+ auto *YConst = dyn_cast<ConstantSDNode>(Y);
+ if (YConst && YConst->isNullValue())
+ return SDValue();
+
+ // Transform this into: ~X & Y == 0.
+ SDValue NotX = DAG.getNOT(SDLoc(X), X, OpVT);
+ SDValue NewAnd = DAG.getNode(ISD::AND, SDLoc(N0), OpVT, NotX, Y);
+ return DAG.getSetCC(DL, VT, NewAnd, Zero, Cond);
+ }
- // Transform this into: ~X & Y == 0.
- EVT OpVT = X.getValueType();
- SDValue NotX = DAG.getNOT(SDLoc(X), X, OpVT);
- SDValue NewAnd = DAG.getNode(ISD::AND, SDLoc(N0), OpVT, NotX, Y);
- return DAG.getSetCC(dl, VT, NewAnd, DAG.getConstant(0, dl, OpVT), Cond);
+ return SDValue();
}
/// Try to simplify a setcc built with the specified operands and cc. If it is
@@ -2134,32 +2149,8 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
}
}
- // Simplify x&y == y to x&y != 0 if y has exactly one bit set.
- // Note that where y is variable and is known to have at most
- // one bit set (for example, if it is z&1) we cannot do this;
- // the expressions are not equivalent when y==0.
- if (N0.getOpcode() == ISD::AND)
- if (N0.getOperand(0) == N1 || N0.getOperand(1) == N1) {
- if (valueHasExactlyOneBitSet(N1, DAG)) {
- Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
- if (DCI.isBeforeLegalizeOps() ||
- isCondCodeLegal(Cond, N0.getSimpleValueType())) {
- SDValue Zero = DAG.getConstant(0, dl, N1.getValueType());
- return DAG.getSetCC(dl, VT, N0, Zero, Cond);
- }
- }
- }
- if (N1.getOpcode() == ISD::AND)
- if (N1.getOperand(0) == N0 || N1.getOperand(1) == N0) {
- if (valueHasExactlyOneBitSet(N0, DAG)) {
- Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
- if (DCI.isBeforeLegalizeOps() ||
- isCondCodeLegal(Cond, N1.getSimpleValueType())) {
- SDValue Zero = DAG.getConstant(0, dl, N0.getValueType());
- return DAG.getSetCC(dl, VT, N1, Zero, Cond);
- }
- }
- }
+ if (SDValue V = simplifySetCCWithAnd(VT, N0, N1, Cond, DCI, dl))
+ return V;
}
// Fold away ALL boolean setcc's.
@@ -2212,9 +2203,6 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
return N0;
}
- if (SDValue AndNotCC = createAndNotSetCC(VT, N0, N1, Cond, DAG, dl))
- return AndNotCC;
-
// Could not fold it.
return SDValue();
}
OpenPOWER on IntegriCloud