summaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-05-05 05:51:50 +0000
committerChris Lattner <sabre@nondot.org>2006-05-05 05:51:50 +0000
commit35e5c14b80a732c7d061a13a3717362e936852b1 (patch)
tree102c1eab90d7a46e4e1d8eb19a6e82d860349b18 /lib/CodeGen
parent8f7f7125e95e4fce29a4b8acbc88f708e7fae42f (diff)
downloadllvm-35e5c14b80a732c7d061a13a3717362e936852b1.tar.gz
llvm-35e5c14b80a732c7d061a13a3717362e936852b1.tar.bz2
llvm-35e5c14b80a732c7d061a13a3717362e936852b1.tar.xz
Factor some code, add these transformations:
// fold (and (trunc x), (trunc y)) -> (trunc (and x, y)) // fold (or (trunc x), (trunc y)) -> (trunc (or x, y)) // fold (xor (trunc x), (trunc y)) -> (trunc (xor x, y)) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28120 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp121
1 files changed, 66 insertions, 55 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index ac70150f8e..68ebf7a78b 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -222,6 +222,7 @@ namespace {
SDOperand ReassociateOps(unsigned Opc, SDOperand LHS, SDOperand RHS);
bool SimplifySelectOps(SDNode *SELECT, SDOperand LHS, SDOperand RHS);
+ SDOperand SimplifyBinOpWithSameOpcodeHands(SDNode *N);
SDOperand SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2);
SDOperand SimplifySelectCC(SDOperand N0, SDOperand N1, SDOperand N2,
SDOperand N3, ISD::CondCode CC);
@@ -1035,6 +1036,53 @@ SDOperand DAGCombiner::visitMULHU(SDNode *N) {
return SDOperand();
}
+/// SimplifyBinOpWithSameOpcodeHands - If this is a binary operator with
+/// two operands of the same opcode, try to simplify it.
+SDOperand DAGCombiner::SimplifyBinOpWithSameOpcodeHands(SDNode *N) {
+ SDOperand N0 = N->getOperand(0), N1 = N->getOperand(1);
+ MVT::ValueType VT = N0.getValueType();
+ assert(N0.getOpcode() == N1.getOpcode() && "Bad input!");
+
+ // fold (and (zext x), (zext y)) -> (zext (and x, y))
+ // fold (or (zext x), (zext y)) -> (zext (or x, y))
+ // fold (xor (zext x), (zext y)) -> (zext (xor x, y))
+ if (N0.getOpcode() == ISD::ZERO_EXTEND &&
+ N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
+ SDOperand ORNode = DAG.getNode(N->getOpcode(),
+ N0.getOperand(0).getValueType(),
+ N0.getOperand(0), N1.getOperand(0));
+ AddToWorkList(ORNode.Val);
+ return DAG.getNode(ISD::ZERO_EXTEND, VT, ORNode);
+ }
+
+ // fold (and (trunc x), (trunc y)) -> (trunc (and x, y))
+ // fold (or (trunc x), (trunc y)) -> (trunc (or x, y))
+ // fold (xor (trunc x), (trunc y)) -> (trunc (xor x, y))
+ if (N0.getOpcode() == ISD::TRUNCATE &&
+ N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
+ SDOperand ORNode = DAG.getNode(N->getOpcode(),
+ N0.getOperand(0).getValueType(),
+ N0.getOperand(0), N1.getOperand(0));
+ AddToWorkList(ORNode.Val);
+ return DAG.getNode(ISD::TRUNCATE, VT, ORNode);
+ }
+
+ // fold (and (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (and x, y))
+ // fold (or (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (or x, y))
+ // fold (xor (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (xor x, y))
+ if ((N0.getOpcode() == ISD::SHL || N0.getOpcode() == ISD::SRL ||
+ N0.getOpcode() == ISD::SRA) &&
+ N0.getOperand(1) == N1.getOperand(1)) {
+ SDOperand ORNode = DAG.getNode(N->getOpcode(),
+ N0.getOperand(0).getValueType(),
+ N0.getOperand(0), N1.getOperand(0));
+ AddToWorkList(ORNode.Val);
+ return DAG.getNode(N0.getOpcode(), VT, ORNode, N0.getOperand(1));
+ }
+
+ return SDOperand();
+}
+
SDOperand DAGCombiner::visitAND(SDNode *N) {
SDOperand N0 = N->getOperand(0);
SDOperand N1 = N->getOperand(1);
@@ -1121,25 +1169,13 @@ SDOperand DAGCombiner::visitAND(SDNode *N) {
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));
- AddToWorkList(ANDNode.Val);
- return DAG.getNode(ISD::ZERO_EXTEND, VT, ANDNode);
- }
- // fold (and (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (and x, y))
- if (((N0.getOpcode() == ISD::SHL && N1.getOpcode() == ISD::SHL) ||
- (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SRL) ||
- (N0.getOpcode() == ISD::SRA && N1.getOpcode() == ISD::SRA)) &&
- N0.getOperand(1) == N1.getOperand(1)) {
- SDOperand ANDNode = DAG.getNode(ISD::AND, N0.getOperand(0).getValueType(),
- N0.getOperand(0), N1.getOperand(0));
- AddToWorkList(ANDNode.Val);
- return DAG.getNode(N0.getOpcode(), VT, ANDNode, N0.getOperand(1));
+
+ // Simplify: and (op x...), (op y...) -> (op (and x, y))
+ if (N0.getOpcode() == N1.getOpcode()) {
+ SDOperand Tmp = SimplifyBinOpWithSameOpcodeHands(N);
+ if (Tmp.Val) return Tmp;
}
+
// fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1)
// fold (and (sra)) -> (and (srl)) when possible.
if (!MVT::isVector(VT) &&
@@ -1292,25 +1328,13 @@ SDOperand DAGCombiner::visitOR(SDNode *N) {
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));
- AddToWorkList(ORNode.Val);
- return DAG.getNode(ISD::ZERO_EXTEND, VT, ORNode);
- }
- // fold (or (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (or x, y))
- if (((N0.getOpcode() == ISD::SHL && N1.getOpcode() == ISD::SHL) ||
- (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SRL) ||
- (N0.getOpcode() == ISD::SRA && N1.getOpcode() == ISD::SRA)) &&
- N0.getOperand(1) == N1.getOperand(1)) {
- SDOperand ORNode = DAG.getNode(ISD::OR, N0.getOperand(0).getValueType(),
- N0.getOperand(0), N1.getOperand(0));
- AddToWorkList(ORNode.Val);
- return DAG.getNode(N0.getOpcode(), VT, ORNode, N0.getOperand(1));
+
+ // Simplify: or (op x...), (op y...) -> (op (or x, y))
+ if (N0.getOpcode() == N1.getOpcode()) {
+ SDOperand Tmp = SimplifyBinOpWithSameOpcodeHands(N);
+ if (Tmp.Val) return Tmp;
}
+
// canonicalize shl to left side in a shl/srl pair, to match rotate
if (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SHL)
std::swap(N0, N1);
@@ -1429,26 +1453,13 @@ SDOperand DAGCombiner::visitXOR(SDNode *N) {
return DAG.getNode(ISD::BUILD_VECTOR, VT, Ops);
}
}
- // 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));
- AddToWorkList(XORNode.Val);
- return DAG.getNode(ISD::ZERO_EXTEND, VT, XORNode);
- }
- // fold (xor (shl/srl/sra x), (shl/srl/sra y)) -> (shl/srl/sra (xor x, y))
- if (((N0.getOpcode() == ISD::SHL && N1.getOpcode() == ISD::SHL) ||
- (N0.getOpcode() == ISD::SRL && N1.getOpcode() == ISD::SRL) ||
- (N0.getOpcode() == ISD::SRA && N1.getOpcode() == ISD::SRA)) &&
- N0.getOperand(1) == N1.getOperand(1)) {
- SDOperand XORNode = DAG.getNode(ISD::XOR, N0.getOperand(0).getValueType(),
- N0.getOperand(0), N1.getOperand(0));
- AddToWorkList(XORNode.Val);
- return DAG.getNode(N0.getOpcode(), VT, XORNode, N0.getOperand(1));
+
+ // Simplify: xor (op x...), (op y...) -> (op (xor x, y))
+ if (N0.getOpcode() == N1.getOpcode()) {
+ SDOperand Tmp = SimplifyBinOpWithSameOpcodeHands(N);
+ if (Tmp.Val) return Tmp;
}
-
+
// Simplify the expression using non-local knowledge.
if (!MVT::isVector(VT) &&
SimplifyDemandedBits(SDOperand(N, 0)))