Skip to content

Commit 190db4b

Browse files
committed
Use addc nodes when lowering overflow
Cannot for thumb1 at this moment because of scheduler issues.
1 parent 018ae02 commit 190db4b

File tree

8 files changed

+321
-212
lines changed

8 files changed

+321
-212
lines changed

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4832,59 +4832,47 @@ SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
48324832
}
48334833

48344834
// This function returns three things: the arithmetic computation itself
4835-
// (Value), a comparison (OverflowCmp), and a condition code (ARMcc). The
4835+
// (Value), a comparison (Overflow), and a condition code (ARMcc). The
48364836
// comparison and the condition code define the case in which the arithmetic
48374837
// computation *does not* overflow.
48384838
std::pair<SDValue, SDValue>
48394839
ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
48404840
SDValue &ARMcc) const {
48414841
assert(Op.getValueType() == MVT::i32 && "Unsupported value type");
48424842

4843-
SDValue Value, OverflowCmp;
4843+
SDValue Value, Overflow;
48444844
SDValue LHS = Op.getOperand(0);
48454845
SDValue RHS = Op.getOperand(1);
48464846
SDLoc dl(Op);
4847-
4848-
// FIXME: We are currently always generating CMPs because we don't support
4849-
// generating CMN through the backend. This is not as good as the natural
4850-
// CMP case because it causes a register dependency and cannot be folded
4851-
// later.
4847+
unsigned Opc = 0;
48524848

48534849
switch (Op.getOpcode()) {
48544850
default:
48554851
llvm_unreachable("Unknown overflow instruction!");
48564852
case ISD::SADDO:
4853+
Opc = ARMISD::ADDC;
48574854
ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4858-
Value = DAG.getNode(ISD::ADD, dl, Op.getValueType(), LHS, RHS);
4859-
OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
48604855
break;
48614856
case ISD::UADDO:
4862-
ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4863-
// We use ADDC here to correspond to its use in LowerUnsignedALUO.
4864-
// We do not use it in the USUBO case as Value may not be used.
4865-
Value = DAG.getNode(ARMISD::ADDC, dl,
4866-
DAG.getVTList(Op.getValueType(), MVT::i32), LHS, RHS)
4867-
.getValue(0);
4868-
OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4857+
Opc = ARMISD::ADDC;
4858+
ARMcc = DAG.getConstant(ARMCC::LO, dl, MVT::i32);
48694859
break;
48704860
case ISD::SSUBO:
4861+
Opc = ARMISD::SUBC;
48714862
ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
4872-
Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4873-
OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
48744863
break;
48754864
case ISD::USUBO:
4865+
Opc = ARMISD::SUBC;
48764866
ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
4877-
Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4878-
OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
48794867
break;
48804868
case ISD::UMULO:
48814869
// We generate a UMUL_LOHI and then check if the high word is 0.
48824870
ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
48834871
Value = DAG.getNode(ISD::UMUL_LOHI, dl,
48844872
DAG.getVTList(Op.getValueType(), Op.getValueType()),
48854873
LHS, RHS);
4886-
OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value.getValue(1),
4887-
DAG.getConstant(0, dl, MVT::i32));
4874+
Overflow = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value.getValue(1),
4875+
DAG.getConstant(0, dl, MVT::i32));
48884876
Value = Value.getValue(0); // We only want the low 32 bits for the result.
48894877
break;
48904878
case ISD::SMULO:
@@ -4894,15 +4882,34 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
48944882
Value = DAG.getNode(ISD::SMUL_LOHI, dl,
48954883
DAG.getVTList(Op.getValueType(), Op.getValueType()),
48964884
LHS, RHS);
4897-
OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value.getValue(1),
4898-
DAG.getNode(ISD::SRA, dl, Op.getValueType(),
4899-
Value.getValue(0),
4900-
DAG.getConstant(31, dl, MVT::i32)));
4885+
Overflow = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value.getValue(1),
4886+
DAG.getNode(ISD::SRA, dl, Op.getValueType(),
4887+
Value.getValue(0),
4888+
DAG.getConstant(31, dl, MVT::i32)));
49014889
Value = Value.getValue(0); // We only want the low 32 bits for the result.
49024890
break;
49034891
} // switch (...)
4892+
if (Opc) {
4893+
if (Subtarget->isThumb1Only() &&
4894+
(Op.getOpcode() == ISD::SADDO || Op.getOpcode() == ISD::SSUBO)) {
4895+
// FIXME: Thumb1 has to split between the cmp and the add/sub.
4896+
// Remove when the peephole optimizer handles this or we no longer need to
4897+
// split.
4898+
if (Opc == ARMISD::ADDC) {
4899+
Value = DAG.getNode(ISD::ADD, dl, Op.getValueType(), LHS, RHS);
4900+
Overflow = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
4901+
} else {
4902+
Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
4903+
Overflow = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
4904+
}
4905+
} else {
4906+
SDVTList VTs = DAG.getVTList(Op.getValueType(), FlagsVT);
4907+
Value = DAG.getNode(Opc, dl, VTs, LHS, RHS);
4908+
Overflow = Value.getValue(1);
4909+
}
4910+
}
49044911

4905-
return std::make_pair(Value, OverflowCmp);
4912+
return std::make_pair(Value, Overflow);
49064913
}
49074914

49084915
SDValue
@@ -4911,20 +4918,18 @@ ARMTargetLowering::LowerSignedALUO(SDValue Op, SelectionDAG &DAG) const {
49114918
if (!isTypeLegal(Op.getValueType()))
49124919
return SDValue();
49134920

4914-
SDValue Value, OverflowCmp;
4915-
SDValue ARMcc;
4916-
std::tie(Value, OverflowCmp) = getARMXALUOOp(Op, DAG, ARMcc);
49174921
SDLoc dl(Op);
4922+
SDValue Value, Overflow;
4923+
SDValue ARMcc;
4924+
std::tie(Value, Overflow) = getARMXALUOOp(Op, DAG, ARMcc);
49184925
// We use 0 and 1 as false and true values.
49194926
SDValue TVal = DAG.getConstant(1, dl, MVT::i32);
49204927
SDValue FVal = DAG.getConstant(0, dl, MVT::i32);
4921-
EVT VT = Op.getValueType();
49224928

4923-
SDValue Overflow =
4924-
DAG.getNode(ARMISD::CMOV, dl, VT, TVal, FVal, ARMcc, OverflowCmp);
4929+
Overflow =
4930+
DAG.getNode(ARMISD::CMOV, dl, MVT::i32, TVal, FVal, ARMcc, Overflow);
49254931

4926-
SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
4927-
return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
4932+
return DAG.getMergeValues({Value, Overflow}, dl);
49284933
}
49294934

49304935
static SDValue ConvertBooleanCarryToCarryFlag(SDValue BoolCarry,
@@ -5055,12 +5060,12 @@ SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
50555060
if (!isTypeLegal(Cond->getValueType(0)))
50565061
return SDValue();
50575062

5058-
SDValue Value, OverflowCmp;
5063+
SDValue Value, Overflow;
50595064
SDValue ARMcc;
5060-
std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
5065+
std::tie(Value, Overflow) = getARMXALUOOp(Cond, DAG, ARMcc);
50615066
EVT VT = Op.getValueType();
50625067

5063-
return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, OverflowCmp, DAG);
5068+
return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, Overflow, DAG);
50645069
}
50655070

50665071
// Convert:
@@ -5657,9 +5662,9 @@ SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
56575662
return SDValue();
56585663

56595664
// The actual operation with overflow check.
5660-
SDValue Value, OverflowCmp;
5665+
SDValue Value, Overflow;
56615666
SDValue ARMcc;
5662-
std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
5667+
std::tie(Value, Overflow) = getARMXALUOOp(Cond, DAG, ARMcc);
56635668

56645669
// Reverse the condition code.
56655670
ARMCC::CondCodes CondCode =
@@ -5668,7 +5673,7 @@ SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
56685673
ARMcc = DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
56695674

56705675
return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5671-
OverflowCmp);
5676+
Overflow);
56725677
}
56735678

56745679
return SDValue();
@@ -5707,9 +5712,9 @@ SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
57075712
return SDValue();
57085713

57095714
// The actual operation with overflow check.
5710-
SDValue Value, OverflowCmp;
5715+
SDValue Value, Overflow;
57115716
SDValue ARMcc;
5712-
std::tie(Value, OverflowCmp) = getARMXALUOOp(LHS.getValue(0), DAG, ARMcc);
5717+
std::tie(Value, Overflow) = getARMXALUOOp(LHS.getValue(0), DAG, ARMcc);
57135718

57145719
if ((CC == ISD::SETNE) != isOneConstant(RHS)) {
57155720
// Reverse the condition code.
@@ -5720,7 +5725,7 @@ SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
57205725
}
57215726

57225727
return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5723-
OverflowCmp);
5728+
Overflow);
57245729
}
57255730

57265731
if (LHS.getValueType() == MVT::i32) {

llvm/test/CodeGen/ARM/arm-shrink-wrapping-linux.ll

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,12 @@ define fastcc ptr @wrongUseOfPostDominate(ptr readonly %s, i32 %off, ptr readnon
3434
; ENABLE-NEXT: .LBB0_4: @ %while.body
3535
; ENABLE-NEXT: @ =>This Inner Loop Header: Depth=1
3636
; ENABLE-NEXT: ldrb r3, [r0]
37+
; ENABLE-NEXT: subs r1, r1, #1
3738
; ENABLE-NEXT: ldrb r3, [r12, r3]
3839
; ENABLE-NEXT: add r0, r0, r3
39-
; ENABLE-NEXT: sub r3, r1, #1
40-
; ENABLE-NEXT: cmp r3, r1
41-
; ENABLE-NEXT: bhs .LBB0_6
40+
; ENABLE-NEXT: blo .LBB0_6
4241
; ENABLE-NEXT: @ %bb.5: @ %while.body
4342
; ENABLE-NEXT: @ in Loop: Header=BB0_4 Depth=1
44-
; ENABLE-NEXT: mov r1, r3
4543
; ENABLE-NEXT: cmp r0, r2
4644
; ENABLE-NEXT: blo .LBB0_4
4745
; ENABLE-NEXT: .LBB0_6: @ %if.end29
@@ -124,14 +122,12 @@ define fastcc ptr @wrongUseOfPostDominate(ptr readonly %s, i32 %off, ptr readnon
124122
; DISABLE-NEXT: .LBB0_4: @ %while.body
125123
; DISABLE-NEXT: @ =>This Inner Loop Header: Depth=1
126124
; DISABLE-NEXT: ldrb r3, [r0]
125+
; DISABLE-NEXT: subs r1, r1, #1
127126
; DISABLE-NEXT: ldrb r3, [r12, r3]
128127
; DISABLE-NEXT: add r0, r0, r3
129-
; DISABLE-NEXT: sub r3, r1, #1
130-
; DISABLE-NEXT: cmp r3, r1
131-
; DISABLE-NEXT: bhs .LBB0_6
128+
; DISABLE-NEXT: blo .LBB0_6
132129
; DISABLE-NEXT: @ %bb.5: @ %while.body
133130
; DISABLE-NEXT: @ in Loop: Header=BB0_4 Depth=1
134-
; DISABLE-NEXT: mov r1, r3
135131
; DISABLE-NEXT: cmp r0, r2
136132
; DISABLE-NEXT: blo .LBB0_4
137133
; DISABLE-NEXT: .LBB0_6: @ %if.end29

0 commit comments

Comments
 (0)