summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMISelLowering.cpp
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2018-12-03 11:16:21 +0000
committerTim Northover <tnorthover@apple.com>2018-12-03 11:16:21 +0000
commit5745b6ac3b1e0d9b2cabf4f777c2eb4ed2a43536 (patch)
tree6b68faab389699b4f6b6a47aa1851876557207ce /llvm/lib/Target/ARM/ARMISelLowering.cpp
parent3c7d062b6bbe026aecdc514b9d75a3f5fb2fa518 (diff)
downloadbcm5719-llvm-5745b6ac3b1e0d9b2cabf4f777c2eb4ed2a43536.tar.gz
bcm5719-llvm-5745b6ac3b1e0d9b2cabf4f777c2eb4ed2a43536.zip
ARM: use target-specific SUBS node when combining cmp with cmov.
This has two positive effects. First, using a custom node prevents recombination leading to an infinite loop since the output DAG is notionally a little more complex than the input one. Using a flag-setting instruction also allows the subtraction to be folded with the related comparison more easily. https://reviews.llvm.org/D53190 llvm-svn: 348122
Diffstat (limited to 'llvm/lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp31
1 files changed, 20 insertions, 11 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 3eaa6103ead..8289e956c6b 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -1282,6 +1282,7 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::FMSTAT: return "ARMISD::FMSTAT";
case ARMISD::CMOV: return "ARMISD::CMOV";
+ case ARMISD::SUBS: return "ARMISD::SUBS";
case ARMISD::SSAT: return "ARMISD::SSAT";
case ARMISD::USAT: return "ARMISD::USAT";
@@ -12707,30 +12708,38 @@ ARMTargetLowering::PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const {
DAG.getConstant(1, dl, MVT::i32), Neg.getValue(1));
Res = DAG.getNode(ISD::ADDCARRY, dl, VTs, Sub, Neg, Carry);
}
- } else if (CC == ARMCC::NE && LHS != RHS &&
+ } else if (CC == ARMCC::NE && !isNullConstant(RHS) &&
(!Subtarget->isThumb1Only() || isPowerOf2Constant(TrueVal))) {
// This seems pointless but will allow us to combine it further below.
- // CMOV 0, z, !=, (CMPZ x, y) -> CMOV (SUB x, y), z, !=, (CMPZ x, y)
- SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
+ // CMOV 0, z, !=, (CMPZ x, y) -> CMOV (SUBS x, y), z, !=, (SUBS x, y):1
+ SDValue Sub =
+ DAG.getNode(ARMISD::SUBS, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
+ SDValue CPSRGlue = DAG.getCopyToReg(DAG.getEntryNode(), dl, ARM::CPSR,
+ Sub.getValue(1), SDValue());
Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, TrueVal, ARMcc,
- N->getOperand(3), Cmp);
+ N->getOperand(3), CPSRGlue.getValue(1));
+ FalseVal = Sub;
}
} else if (isNullConstant(TrueVal)) {
- if (CC == ARMCC::EQ && LHS != RHS &&
+ if (CC == ARMCC::EQ && !isNullConstant(RHS) &&
(!Subtarget->isThumb1Only() || isPowerOf2Constant(FalseVal))) {
// This seems pointless but will allow us to combine it further below
// Note that we change == for != as this is the dual for the case above.
- // CMOV z, 0, ==, (CMPZ x, y) -> CMOV (SUB x, y), z, !=, (CMPZ x, y)
- SDValue Sub = DAG.getNode(ISD::SUB, dl, VT, LHS, RHS);
+ // CMOV z, 0, ==, (CMPZ x, y) -> CMOV (SUBS x, y), z, !=, (SUBS x, y):1
+ SDValue Sub =
+ DAG.getNode(ARMISD::SUBS, dl, DAG.getVTList(VT, MVT::i32), LHS, RHS);
+ SDValue CPSRGlue = DAG.getCopyToReg(DAG.getEntryNode(), dl, ARM::CPSR,
+ Sub.getValue(1), SDValue());
Res = DAG.getNode(ARMISD::CMOV, dl, VT, Sub, FalseVal,
DAG.getConstant(ARMCC::NE, dl, MVT::i32),
- N->getOperand(3), Cmp);
+ N->getOperand(3), CPSRGlue.getValue(1));
+ FalseVal = Sub;
}
}
// On Thumb1, the DAG above may be further combined if z is a power of 2
// (z == 2 ^ K).
- // CMOV (SUB x, y), z, !=, (CMPZ x, y) ->
+ // CMOV (SUBS x, y), z, !=, (SUBS x, y):1 ->
// merge t3, t4
// where t1 = (SUBCARRY (SUB x, y), z, 0)
// t2 = (SUBCARRY (SUB x, y), t1:0, t1:1)
@@ -12738,8 +12747,8 @@ ARMTargetLowering::PerformCMOVCombine(SDNode *N, SelectionDAG &DAG) const {
// t4 = (SUB 1, t2:1) [ we want a carry, not a borrow ]
const APInt *TrueConst;
if (Subtarget->isThumb1Only() && CC == ARMCC::NE &&
- (FalseVal.getOpcode() == ISD::SUB) && (FalseVal.getOperand(0) == LHS) &&
- (FalseVal.getOperand(1) == RHS) &&
+ (FalseVal.getOpcode() == ARMISD::SUBS) &&
+ (FalseVal.getOperand(0) == LHS) && (FalseVal.getOperand(1) == RHS) &&
(TrueConst = isPowerOf2Constant(TrueVal))) {
SDVTList VTs = DAG.getVTList(VT, MVT::i32);
unsigned ShiftAmount = TrueConst->logBase2();
OpenPOWER on IntegriCloud