diff options
author | Chris Lattner <sabre@nondot.org> | 2006-05-05 05:51:50 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2006-05-05 05:51:50 +0000 |
commit | 35e5c14b80a732c7d061a13a3717362e936852b1 (patch) | |
tree | 102c1eab90d7a46e4e1d8eb19a6e82d860349b18 /lib/CodeGen | |
parent | 8f7f7125e95e4fce29a4b8acbc88f708e7fae42f (diff) | |
download | llvm-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.cpp | 121 |
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))) |