diff options
author | Artyom Skrobov <Artyom.Skrobov@arm.com> | 2017-03-13 22:36:14 +0000 |
---|---|---|
committer | Artyom Skrobov <Artyom.Skrobov@arm.com> | 2017-03-13 22:36:14 +0000 |
commit | bf19d4bc298efd7887f8c6d66458c5ba7184a1bc (patch) | |
tree | 65e699d13146518d624fe851079525d0206d0f33 /llvm/lib/Target/ARM/ARMISelLowering.cpp | |
parent | 987a281afe049c25a9ae6a01591925798931a63e (diff) | |
download | bcm5719-llvm-bf19d4bc298efd7887f8c6d66458c5ba7184a1bc.tar.gz bcm5719-llvm-bf19d4bc298efd7887f8c6d66458c5ba7184a1bc.zip |
[Thumb1] combine ADDC/SUBC with a negative immediate
Summary: This simple optimization has been split out of https://reviews.llvm.org/D30400
Reviewers: efriedma, jmolloy
Subscribers: llvm-commits, rengolin
Differential Revision: https://reviews.llvm.org/D30829
llvm-svn: 297682
Diffstat (limited to 'llvm/lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 598ed1ae481..ad95d988e9a 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -9660,6 +9660,24 @@ static SDValue PerformUMLALCombine(SDNode *N, SelectionDAG &DAG, return SDValue(); } +static SDValue PerformAddcSubcCombine(SDNode *N, SelectionDAG &DAG, + const ARMSubtarget *Subtarget) { + if (Subtarget->isThumb1Only()) { + SDValue RHS = N->getOperand(1); + if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS)) { + int64_t imm = C->getSExtValue(); + if (imm < 0) { + SDLoc DL(N); + RHS = DAG.getConstant(-imm, DL, MVT::i32); + unsigned Opcode = (N->getOpcode() == ARMISD::ADDC) ? ARMISD::SUBC + : ARMISD::ADDC; + return DAG.getNode(Opcode, DL, N->getVTList(), N->getOperand(0), RHS); + } + } + } + return SDValue(); +} + static SDValue PerformAddeSubeCombine(SDNode *N, SelectionDAG &DAG, const ARMSubtarget *Subtarget) { if (Subtarget->isThumb1Only()) { @@ -11729,6 +11747,8 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N, case ISD::OR: return PerformORCombine(N, DCI, Subtarget); case ISD::XOR: return PerformXORCombine(N, DCI, Subtarget); case ISD::AND: return PerformANDCombine(N, DCI, Subtarget); + case ARMISD::ADDC: + case ARMISD::SUBC: return PerformAddcSubcCombine(N, DCI.DAG, Subtarget); case ARMISD::SUBE: return PerformAddeSubeCombine(N, DCI.DAG, Subtarget); case ARMISD::BFI: return PerformBFICombine(N, DCI); case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI, Subtarget); |