Skip to content

Commit 075e5a2

Browse files
committedSep 11, 2017
Revert r312898 "[ARM] Use ADDCARRY / SUBCARRY"
It caused PR34564. > This is a preparatory step for D34515 and also is being recommitted as its > first version caused PR34045. > > This change: > - makes nodes ISD::ADDCARRY and ISD::SUBCARRY legal for i32 > - lowering is done by first converting the boolean value into the carry flag > using (_, C) ← (ARMISD::ADDC R, -1) and converted back to an integer value > using (R, _) ← (ARMISD::ADDE 0, 0, C). An ARMISD::ADDE between the two > operations does the actual addition. > - for subtraction, given that ISD::SUBCARRY second result is actually a > borrow, we need to invert the value of the second operand and result before > and after using ARMISD::SUBE. We need to invert the carry result of > ARMISD::SUBE to preserve the semantics. > - given that the generic combiner may lower ISD::ADDCARRY and > ISD::SUBCARRYinto ISD::UADDO and ISD::USUBO we need to update their lowering > as well otherwise i64 operations now would require branches. This implies > updating the corresponding test for unsigned. > - add new combiner to remove the redundant conversions from/to carry flags > to/from boolean values (ARMISD::ADDC (ARMISD::ADDE 0, 0, C), -1) → C > - fixes PR34045 > > Differential Revision: https://reviews.llvm.org/D35192 llvm-svn: 312980
1 parent b7147ad commit 075e5a2

File tree

4 files changed

+35
-294
lines changed

4 files changed

+35
-294
lines changed
 

‎llvm/lib/Target/ARM/ARMISelLowering.cpp

+19-166
Original file line numberDiff line numberDiff line change
@@ -802,9 +802,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
802802
setOperationAction(ISD::SSUBO, MVT::i32, Custom);
803803
setOperationAction(ISD::USUBO, MVT::i32, Custom);
804804

805-
setOperationAction(ISD::ADDCARRY, MVT::i32, Custom);
806-
setOperationAction(ISD::SUBCARRY, MVT::i32, Custom);
807-
808805
// i64 operation support.
809806
setOperationAction(ISD::MUL, MVT::i64, Expand);
810807
setOperationAction(ISD::MULHU, MVT::i32, Expand);
@@ -3956,7 +3953,7 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
39563953
}
39573954

39583955
SDValue
3959-
ARMTargetLowering::LowerSignedALUO(SDValue Op, SelectionDAG &DAG) const {
3956+
ARMTargetLowering::LowerXALUO(SDValue Op, SelectionDAG &DAG) const {
39603957
// Let legalize expand this if it isn't a legal type yet.
39613958
if (!DAG.getTargetLoweringInfo().isTypeLegal(Op.getValueType()))
39623959
return SDValue();
@@ -3978,66 +3975,6 @@ ARMTargetLowering::LowerSignedALUO(SDValue Op, SelectionDAG &DAG) const {
39783975
return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
39793976
}
39803977

3981-
static SDValue ConvertBooleanCarryToCarryFlag(SDValue BoolCarry,
3982-
SelectionDAG &DAG) {
3983-
SDLoc DL(BoolCarry);
3984-
EVT CarryVT = BoolCarry.getValueType();
3985-
3986-
APInt NegOne = APInt::getAllOnesValue(CarryVT.getScalarSizeInBits());
3987-
// This converts the boolean value carry into the carry flag by doing
3988-
// ARMISD::ADDC Carry, ~0
3989-
return DAG.getNode(ARMISD::ADDC, DL, DAG.getVTList(CarryVT, MVT::i32),
3990-
BoolCarry, DAG.getConstant(NegOne, DL, CarryVT));
3991-
}
3992-
3993-
static SDValue ConvertCarryFlagToBooleanCarry(SDValue Flags, EVT VT,
3994-
SelectionDAG &DAG) {
3995-
SDLoc DL(Flags);
3996-
3997-
// Now convert the carry flag into a boolean carry. We do this
3998-
// using ARMISD:ADDE 0, 0, Carry
3999-
return DAG.getNode(ARMISD::ADDE, DL, DAG.getVTList(VT, MVT::i32),
4000-
DAG.getConstant(0, DL, MVT::i32),
4001-
DAG.getConstant(0, DL, MVT::i32), Flags);
4002-
}
4003-
4004-
SDValue ARMTargetLowering::LowerUnsignedALUO(SDValue Op,
4005-
SelectionDAG &DAG) const {
4006-
// Let legalize expand this if it isn't a legal type yet.
4007-
if (!DAG.getTargetLoweringInfo().isTypeLegal(Op.getValueType()))
4008-
return SDValue();
4009-
4010-
SDValue LHS = Op.getOperand(0);
4011-
SDValue RHS = Op.getOperand(1);
4012-
SDLoc dl(Op);
4013-
4014-
EVT VT = Op.getValueType();
4015-
SDVTList VTs = DAG.getVTList(VT, MVT::i32);
4016-
SDValue Value;
4017-
SDValue Overflow;
4018-
switch (Op.getOpcode()) {
4019-
default:
4020-
llvm_unreachable("Unknown overflow instruction!");
4021-
case ISD::UADDO:
4022-
Value = DAG.getNode(ARMISD::ADDC, dl, VTs, LHS, RHS);
4023-
// Convert the carry flag into a boolean value.
4024-
Overflow = ConvertCarryFlagToBooleanCarry(Value.getValue(1), VT, DAG);
4025-
break;
4026-
case ISD::USUBO: {
4027-
Value = DAG.getNode(ARMISD::SUBC, dl, VTs, LHS, RHS);
4028-
// Convert the carry flag into a boolean value.
4029-
Overflow = ConvertCarryFlagToBooleanCarry(Value.getValue(1), VT, DAG);
4030-
// ARMISD::SUBC returns 0 when we have to borrow, so make it an overflow
4031-
// value. So compute 1 - C.
4032-
Overflow = DAG.getNode(ISD::SUB, dl, VTs,
4033-
DAG.getConstant(1, dl, MVT::i32), Overflow);
4034-
break;
4035-
}
4036-
}
4037-
4038-
return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
4039-
}
4040-
40413978
SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
40423979
SDValue Cond = Op.getOperand(0);
40433980
SDValue SelectTrue = Op.getOperand(1);
@@ -7443,53 +7380,6 @@ static SDValue LowerADDC_ADDE_SUBC_SUBE(SDValue Op, SelectionDAG &DAG) {
74437380
Op.getOperand(1), Op.getOperand(2));
74447381
}
74457382

7446-
static SDValue LowerADDSUBCARRY(SDValue Op, SelectionDAG &DAG) {
7447-
SDNode *N = Op.getNode();
7448-
EVT VT = N->getValueType(0);
7449-
SDVTList VTs = DAG.getVTList(VT, MVT::i32);
7450-
7451-
SDValue Carry = Op.getOperand(2);
7452-
EVT CarryVT = Carry.getValueType();
7453-
7454-
SDLoc DL(Op);
7455-
7456-
APInt NegOne = APInt::getAllOnesValue(CarryVT.getScalarSizeInBits());
7457-
7458-
SDValue Result;
7459-
if (Op.getOpcode() == ISD::ADDCARRY) {
7460-
// This converts the boolean value carry into the carry flag.
7461-
Carry = ConvertBooleanCarryToCarryFlag(Carry, DAG);
7462-
7463-
// Do the addition proper using the carry flag we wanted.
7464-
Result = DAG.getNode(ARMISD::ADDE, DL, VTs, Op.getOperand(0),
7465-
Op.getOperand(1), Carry.getValue(1));
7466-
7467-
// Now convert the carry flag into a boolean value.
7468-
Carry = ConvertCarryFlagToBooleanCarry(Result.getValue(1), VT, DAG);
7469-
} else {
7470-
// ARMISD::SUBE expects a carry not a borrow like ISD::SUBCARRY so we
7471-
// have to invert the carry first.
7472-
Carry =
7473-
DAG.getNode(ISD::SUB, DL, VTs, DAG.getConstant(1, DL, MVT::i32), Carry);
7474-
// This converts the boolean value carry into the carry flag.
7475-
Carry = ConvertBooleanCarryToCarryFlag(Carry, DAG);
7476-
7477-
// Do the subtraction proper using the carry flag we wanted.
7478-
Result = DAG.getNode(ARMISD::SUBE, DL, VTs, Op.getOperand(0),
7479-
Op.getOperand(1), Carry.getValue(1));
7480-
7481-
// Now convert the carry flag into a boolean value.
7482-
Carry = ConvertCarryFlagToBooleanCarry(Result.getValue(1), VT, DAG);
7483-
// But the carry returned by ARMISD::SUBE is not a borrow as expected
7484-
// by ISD::SUBCARRY, so compute 1 - C.
7485-
Carry =
7486-
DAG.getNode(ISD::SUB, DL, VTs, DAG.getConstant(1, DL, MVT::i32), Carry);
7487-
}
7488-
7489-
// Return both values.
7490-
return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Result, Carry);
7491-
}
7492-
74937383
SDValue ARMTargetLowering::LowerFSINCOS(SDValue Op, SelectionDAG &DAG) const {
74947384
assert(Subtarget->isTargetDarwin());
74957385

@@ -7844,14 +7734,11 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
78447734
case ISD::ADDE:
78457735
case ISD::SUBC:
78467736
case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
7847-
case ISD::ADDCARRY:
7848-
case ISD::SUBCARRY: return LowerADDSUBCARRY(Op, DAG);
78497737
case ISD::SADDO:
7850-
case ISD::SSUBO:
7851-
return LowerSignedALUO(Op, DAG);
78527738
case ISD::UADDO:
7739+
case ISD::SSUBO:
78537740
case ISD::USUBO:
7854-
return LowerUnsignedALUO(Op, DAG);
7741+
return LowerXALUO(Op, DAG);
78557742
case ISD::ATOMIC_LOAD:
78567743
case ISD::ATOMIC_STORE: return LowerAtomicLoadStore(Op, DAG);
78577744
case ISD::FSINCOS: return LowerFSINCOS(Op, DAG);
@@ -9800,19 +9687,19 @@ static SDValue AddCombineTo64bitMLAL(SDNode *AddeNode,
98009687
// a S/UMLAL instruction.
98019688
// UMUL_LOHI
98029689
// / :lo \ :hi
9803-
// V \ [no multiline comment]
9804-
// loAdd -> ADDC |
9805-
// \ :carry /
9806-
// V V
9807-
// ADDE <- hiAdd
9690+
// / \ [no multiline comment]
9691+
// loAdd -> ADDE |
9692+
// \ :glue /
9693+
// \ /
9694+
// ADDC <- hiAdd
98089695
//
98099696
assert(AddeNode->getOpcode() == ARMISD::ADDE && "Expect an ADDE");
98109697

98119698
assert(AddeNode->getNumOperands() == 3 &&
98129699
AddeNode->getOperand(2).getValueType() == MVT::i32 &&
98139700
"ADDE node has the wrong inputs");
98149701

9815-
// Check that we are chained to the right ADDC node.
9702+
// Check that we have a glued ADDC node.
98169703
SDNode* AddcNode = AddeNode->getOperand(2).getNode();
98179704
if (AddcNode->getOpcode() != ARMISD::ADDC)
98189705
return SDValue();
@@ -9863,7 +9750,7 @@ static SDValue AddCombineTo64bitMLAL(SDNode *AddeNode,
98639750
SDValue* LoMul = nullptr;
98649751
SDValue* LowAdd = nullptr;
98659752

9866-
// Ensure that ADDE is from high result of ISD::xMUL_LOHI.
9753+
// Ensure that ADDE is from high result of ISD::SMUL_LOHI.
98679754
if ((AddeOp0 != MULOp.getValue(1)) && (AddeOp1 != MULOp.getValue(1)))
98689755
return SDValue();
98699756

@@ -9888,11 +9775,6 @@ static SDValue AddCombineTo64bitMLAL(SDNode *AddeNode,
98889775
if (!LoMul)
98899776
return SDValue();
98909777

9891-
// If HiAdd is a predecessor of ADDC, the replacement below will create a
9892-
// cycle.
9893-
if (AddcNode->isPredecessorOf(HiAdd->getNode()))
9894-
return SDValue();
9895-
98969778
// Create the merged node.
98979779
SelectionDAG &DAG = DCI.DAG;
98989780

@@ -9995,22 +9877,8 @@ static SDValue PerformUMLALCombine(SDNode *N, SelectionDAG &DAG,
99959877
return SDValue();
99969878
}
99979879

9998-
static SDValue PerformAddcSubcCombine(SDNode *N,
9999-
TargetLowering::DAGCombinerInfo &DCI,
9880+
static SDValue PerformAddcSubcCombine(SDNode *N, SelectionDAG &DAG,
100009881
const ARMSubtarget *Subtarget) {
10001-
SelectionDAG &DAG(DCI.DAG);
10002-
10003-
if (N->getOpcode() == ARMISD::ADDC) {
10004-
// (ADDC (ADDE 0, 0, C), -1) -> C
10005-
SDValue LHS = N->getOperand(0);
10006-
SDValue RHS = N->getOperand(1);
10007-
if (LHS->getOpcode() == ARMISD::ADDE &&
10008-
isNullConstant(LHS->getOperand(0)) &&
10009-
isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
10010-
return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
10011-
}
10012-
}
10013-
100149882
if (Subtarget->isThumb1Only()) {
100159883
SDValue RHS = N->getOperand(1);
100169884
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(RHS)) {
@@ -11899,14 +11767,6 @@ static SDValue PerformExtendCombine(SDNode *N, SelectionDAG &DAG,
1189911767
return SDValue();
1190011768
}
1190111769

11902-
static const APInt *isPowerOf2Constant(SDValue V) {
11903-
ConstantSDNode *C = dyn_cast<ConstantSDNode>(V);
11904-
if (!C)
11905-
return nullptr;
11906-
const APInt *CV = &C->getAPIntValue();
11907-
return CV->isPowerOf2() ? CV : nullptr;
11908-
}
11909-
1191011770
SDValue ARMTargetLowering::PerformCMOVToBFICombine(SDNode *CMOV, SelectionDAG &DAG) const {
1191111771
// If we have a CMOV, OR and AND combination such as:
1191211772
// if (x & CN)
@@ -11935,8 +11795,8 @@ SDValue ARMTargetLowering::PerformCMOVToBFICombine(SDNode *CMOV, SelectionDAG &D
1193511795
SDValue And = CmpZ->getOperand(0);
1193611796
if (And->getOpcode() != ISD::AND)
1193711797
return SDValue();
11938-
const APInt *AndC = isPowerOf2Constant(And->getOperand(1));
11939-
if (!AndC)
11798+
ConstantSDNode *AndC = dyn_cast<ConstantSDNode>(And->getOperand(1));
11799+
if (!AndC || !AndC->getAPIntValue().isPowerOf2())
1194011800
return SDValue();
1194111801
SDValue X = And->getOperand(0);
1194211802

@@ -11976,7 +11836,7 @@ SDValue ARMTargetLowering::PerformCMOVToBFICombine(SDNode *CMOV, SelectionDAG &D
1197611836
SDValue V = Y;
1197711837
SDLoc dl(X);
1197811838
EVT VT = X.getValueType();
11979-
unsigned BitInX = AndC->logBase2();
11839+
unsigned BitInX = AndC->getAPIntValue().logBase2();
1198011840

1198111841
if (BitInX != 0) {
1198211842
// We must shift X first.
@@ -12137,7 +11997,7 @@ SDValue ARMTargetLowering::PerformDAGCombine(SDNode *N,
1213711997
case ISD::XOR: return PerformXORCombine(N, DCI, Subtarget);
1213811998
case ISD::AND: return PerformANDCombine(N, DCI, Subtarget);
1213911999
case ARMISD::ADDC:
12140-
case ARMISD::SUBC: return PerformAddcSubcCombine(N, DCI, Subtarget);
12000+
case ARMISD::SUBC: return PerformAddcSubcCombine(N, DCI.DAG, Subtarget);
1214112001
case ARMISD::SUBE: return PerformAddeSubeCombine(N, DCI.DAG, Subtarget);
1214212002
case ARMISD::BFI: return PerformBFICombine(N, DCI);
1214312003
case ARMISD::VMOVRRD: return PerformVMOVRRDCombine(N, DCI, Subtarget);
@@ -12833,17 +12693,10 @@ void ARMTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1283312693
case ARMISD::ADDE:
1283412694
case ARMISD::SUBC:
1283512695
case ARMISD::SUBE:
12836-
// Special cases when we convert a carry to a boolean.
12837-
if (Op.getResNo() == 0) {
12838-
SDValue LHS = Op.getOperand(0);
12839-
SDValue RHS = Op.getOperand(1);
12840-
// (ADDE 0, 0, C) will give us a single bit.
12841-
if (Op->getOpcode() == ARMISD::ADDE && isNullConstant(LHS) &&
12842-
isNullConstant(RHS)) {
12843-
Known.Zero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1);
12844-
return;
12845-
}
12846-
}
12696+
// These nodes' second result is a boolean
12697+
if (Op.getResNo() == 0)
12698+
break;
12699+
Known.Zero |= APInt::getHighBitsSet(BitWidth, BitWidth - 1);
1284712700
break;
1284812701
case ARMISD::CMOV: {
1284912702
// Bits are known zero/one if known on the LHS and RHS.

‎llvm/lib/Target/ARM/ARMISelLowering.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -625,8 +625,7 @@ class InstrItineraryData;
625625
SDValue LowerGlobalTLSAddressWindows(SDValue Op, SelectionDAG &DAG) const;
626626
SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const;
627627
SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
628-
SDValue LowerSignedALUO(SDValue Op, SelectionDAG &DAG) const;
629-
SDValue LowerUnsignedALUO(SDValue Op, SelectionDAG &DAG) const;
628+
SDValue LowerXALUO(SDValue Op, SelectionDAG &DAG) const;
630629
SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
631630
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
632631
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;

0 commit comments

Comments
 (0)
Please sign in to comment.