diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2012-07-17 18:54:11 +0000 |
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2012-07-17 18:54:11 +0000 |
| commit | e6a3b03ee05332a96f61c39759658bbab7bd6783 (patch) | |
| tree | cb6f2a64b62afaeb1227162fe7728f70b784277e /llvm/lib/CodeGen/SelectionDAG | |
| parent | 831c1e081965ab860076d305e7a484b235b9a90e (diff) | |
| download | bcm5719-llvm-e6a3b03ee05332a96f61c39759658bbab7bd6783.tar.gz bcm5719-llvm-e6a3b03ee05332a96f61c39759658bbab7bd6783.zip | |
Back out r160101 and instead implement a dag combine to recover from instcombine transformation.
llvm-svn: 160387
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 0e5ecd5d2dc..013e8be21a0 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2716,6 +2716,34 @@ SDValue DAGCombiner::visitAND(SDNode *N) { } } + if (N0.getOpcode() == ISD::ADD && N1.getOpcode() == ISD::SRL && + VT.getSizeInBits() <= 64) { + if (ConstantSDNode *ADDI = dyn_cast<ConstantSDNode>(N0.getOperand(1))) { + APInt ADDC = ADDI->getAPIntValue(); + if (!TLI.isLegalAddImmediate(ADDC.getSExtValue())) { + // Look for (and (add x, c1), (lshr y, c2)). If C1 wasn't a legal + // immediate for an add, but it is legal if its top c2 bits are set, + // transform the ADD so the immediate doesn't need to be materialized + // in a register. + if (ConstantSDNode *SRLI = dyn_cast<ConstantSDNode>(N1.getOperand(1))) { + APInt Mask = APInt::getHighBitsSet(VT.getSizeInBits(), + SRLI->getZExtValue()); + if (DAG.MaskedValueIsZero(N0.getOperand(1), Mask)) { + ADDC |= Mask; + if (TLI.isLegalAddImmediate(ADDC.getSExtValue())) { + SDValue NewAdd = + DAG.getNode(ISD::ADD, N0.getDebugLoc(), VT, + N0.getOperand(0), DAG.getConstant(ADDC, VT)); + CombineTo(N0.getNode(), NewAdd); + return SDValue(N, 0); // Return N so it doesn't get rechecked! + } + } + } + } + } + } + + return SDValue(); } |

