[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp SelectionDAG.cpp
Nate Begeman
natebegeman at mac.com
Fri Sep 9 12:50:03 PDT 2005
Changes in directory llvm/lib/CodeGen/SelectionDAG:
DAGCombiner.cpp updated: 1.9 -> 1.10
SelectionDAG.cpp updated: 1.189 -> 1.190
---
Log message:
Last round of 2-node folds from SD.cpp. Will move on to 3 node ops such
as setcc and select next.
---
Diffs of the changes: (+107 -2)
DAGCombiner.cpp | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
SelectionDAG.cpp | 6 ++-
2 files changed, 107 insertions(+), 2 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.9 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.10
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.9 Thu Sep 8 15:18:10 2005
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Fri Sep 9 14:49:52 2005
@@ -574,6 +574,7 @@
SDOperand DAGCombiner::visitAND(SDNode *N) {
SDOperand N0 = N->getOperand(0);
SDOperand N1 = N->getOperand(1);
+ SDOperand LL, LR, RL, RR, CC0, CC1;
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
MVT::ValueType VT = N1.getValueType();
@@ -620,12 +621,60 @@
if (ConstantSDNode *ORI = dyn_cast<ConstantSDNode>(N0.getOperand(1)))
if ((ORI->getValue() & N1C->getValue()) == N1C->getValue())
return N1;
+ // fold (and (setcc x), (setcc y)) -> (setcc (and x, y))
+ if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){
+ ISD::CondCode Op0 = cast<CondCodeSDNode>(CC0)->get();
+ ISD::CondCode Op1 = cast<CondCodeSDNode>(CC1)->get();
+
+ if (LR == RR && isa<ConstantSDNode>(LR) && Op0 == Op1 &&
+ MVT::isInteger(LL.getValueType())) {
+ // fold (X == 0) & (Y == 0) -> (X|Y == 0)
+ if (cast<ConstantSDNode>(LR)->getValue() == 0 && Op1 == ISD::SETEQ) {
+ SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL);
+ WorkList.push_back(ORNode.Val);
+ return DAG.getSetCC(VT, ORNode, LR, Op1);
+ }
+ // fold (X == -1) & (Y == -1) -> (X&Y == -1)
+ if (cast<ConstantSDNode>(LR)->isAllOnesValue() && Op1 == ISD::SETEQ) {
+ SDOperand ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL);
+ WorkList.push_back(ANDNode.Val);
+ return DAG.getSetCC(VT, ANDNode, LR, Op1);
+ }
+ // fold (X > -1) & (Y > -1) -> (X|Y > -1)
+ if (cast<ConstantSDNode>(LR)->isAllOnesValue() && Op1 == ISD::SETGT) {
+ SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL);
+ WorkList.push_back(ORNode.Val);
+ return DAG.getSetCC(VT, ORNode, LR, Op1);
+ }
+ }
+ // canonicalize equivalent to ll == rl
+ if (LL == RR && LR == RL) {
+ Op1 = ISD::getSetCCSwappedOperands(Op1);
+ std::swap(RL, RR);
+ }
+ if (LL == RL && LR == RR) {
+ bool isInteger = MVT::isInteger(LL.getValueType());
+ ISD::CondCode Result = ISD::getSetCCAndOperation(Op0, Op1, isInteger);
+ if (Result != ISD::SETCC_INVALID)
+ return DAG.getSetCC(N0.getValueType(), LL, LR, Result);
+ }
+ }
+ // fold (and (zext x), (zext y)) -> (zext (and x, y))
+ if (N0.getOpcode() == ISD::ZERO_EXTEND &&
+ N1.getOpcode() == ISD::ZERO_EXTEND &&
+ N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
+ SDOperand ANDNode = DAG.getNode(ISD::AND, N0.getOperand(0).getValueType(),
+ N0.getOperand(0), N1.getOperand(0));
+ WorkList.push_back(ANDNode.Val);
+ return DAG.getNode(ISD::ZERO_EXTEND, VT, ANDNode);
+ }
return SDOperand();
}
SDOperand DAGCombiner::visitOR(SDNode *N) {
SDOperand N0 = N->getOperand(0);
SDOperand N1 = N->getOperand(1);
+ SDOperand LL, LR, RL, RR, CC0, CC1;
ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
MVT::ValueType VT = N1.getValueType();
@@ -661,6 +710,51 @@
return DAG.getNode(ISD::OR, VT, N0.getOperand(0),
DAG.getConstant(N1C->getValue()|N01C->getValue(), VT));
}
+ // fold (or (setcc x), (setcc y)) -> (setcc (or x, y))
+ if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){
+ ISD::CondCode Op0 = cast<CondCodeSDNode>(CC0)->get();
+ ISD::CondCode Op1 = cast<CondCodeSDNode>(CC1)->get();
+
+ if (LR == RR && isa<ConstantSDNode>(LR) && Op0 == Op1 &&
+ MVT::isInteger(LL.getValueType())) {
+ // fold (X != 0) | (Y != 0) -> (X|Y != 0)
+ // fold (X < 0) | (Y < 0) -> (X|Y < 0)
+ if (cast<ConstantSDNode>(LR)->getValue() == 0 &&
+ (Op1 == ISD::SETNE || Op1 == ISD::SETLT)) {
+ SDOperand ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL);
+ WorkList.push_back(ORNode.Val);
+ return DAG.getSetCC(VT, ORNode, LR, Op1);
+ }
+ // fold (X != -1) | (Y != -1) -> (X&Y != -1)
+ // fold (X > -1) | (Y > -1) -> (X&Y > -1)
+ if (cast<ConstantSDNode>(LR)->isAllOnesValue() &&
+ (Op1 == ISD::SETNE || Op1 == ISD::SETGT)) {
+ SDOperand ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL);
+ WorkList.push_back(ANDNode.Val);
+ return DAG.getSetCC(VT, ANDNode, LR, Op1);
+ }
+ }
+ // canonicalize equivalent to ll == rl
+ if (LL == RR && LR == RL) {
+ Op1 = ISD::getSetCCSwappedOperands(Op1);
+ std::swap(RL, RR);
+ }
+ if (LL == RL && LR == RR) {
+ bool isInteger = MVT::isInteger(LL.getValueType());
+ ISD::CondCode Result = ISD::getSetCCOrOperation(Op0, Op1, isInteger);
+ if (Result != ISD::SETCC_INVALID)
+ return DAG.getSetCC(N0.getValueType(), LL, LR, Result);
+ }
+ }
+ // fold (or (zext x), (zext y)) -> (zext (or x, y))
+ if (N0.getOpcode() == ISD::ZERO_EXTEND &&
+ N1.getOpcode() == ISD::ZERO_EXTEND &&
+ N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
+ SDOperand ORNode = DAG.getNode(ISD::OR, N0.getOperand(0).getValueType(),
+ N0.getOperand(0), N1.getOperand(0));
+ WorkList.push_back(ORNode.Val);
+ return DAG.getNode(ISD::ZERO_EXTEND, VT, ORNode);
+ }
return SDOperand();
}
@@ -733,6 +827,15 @@
// fold (xor x, x) -> 0
if (N0 == N1)
return DAG.getConstant(0, VT);
+ // fold (xor (zext x), (zext y)) -> (zext (xor x, y))
+ if (N0.getOpcode() == ISD::ZERO_EXTEND &&
+ N1.getOpcode() == ISD::ZERO_EXTEND &&
+ N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
+ SDOperand XORNode = DAG.getNode(ISD::XOR, N0.getOperand(0).getValueType(),
+ N0.getOperand(0), N1.getOperand(0));
+ WorkList.push_back(XORNode.Val);
+ return DAG.getNode(ISD::ZERO_EXTEND, VT, XORNode);
+ }
return SDOperand();
}
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.189 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.190
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.189 Thu Sep 8 15:18:10 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Sep 9 14:49:52 2005
@@ -1310,10 +1310,10 @@
}
}
+ if (!CombinerEnabled) {
if (N2C) {
uint64_t C2 = N2C->getValue();
- if (!CombinerEnabled) {
switch (Opcode) {
case ISD::ADD:
if (!C2) return N1; // add X, 0 -> X
@@ -1486,7 +1486,7 @@
if (ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N1.Val->getOperand(1)))
return getNode(Opcode, VT, N1.Val->getOperand(0),
getNode(Opcode, VT, N2, N1.Val->getOperand(1)));
- }
+ }
}
ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1.Val);
@@ -1533,6 +1533,7 @@
case ISD::AND:
case ISD::OR:
+ if (!CombinerEnabled) {
if (N1.Val->getOpcode() == ISD::SETCC && N2.Val->getOpcode() == ISD::SETCC){
SDNode *LHS = N1.Val, *RHS = N2.Val;
SDOperand LL = LHS->getOperand(0), RL = RHS->getOperand(0);
@@ -1595,6 +1596,7 @@
return getNode(ISD::ZERO_EXTEND, VT,
getNode(Opcode, N1.getOperand(0).getValueType(),
N1.getOperand(0), N2.getOperand(0)));
+ }
break;
case ISD::XOR:
if (!CombinerEnabled) {
More information about the llvm-commits
mailing list