@@ -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.
48384838std::pair<SDValue, SDValue>
48394839ARMTargetLowering::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
49084915SDValue
@@ -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
49304935static 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) {
0 commit comments