@@ -998,6 +998,11 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_,
998998 setOperationAction(ISD::SSUBO, MVT::i32, Custom);
999999 setOperationAction(ISD::USUBO, MVT::i32, Custom);
10001000
1001+ if (!Subtarget->isThumb1Only()) {
1002+ setOperationAction(ISD::UMULO, MVT::i32, Custom);
1003+ setOperationAction(ISD::SMULO, MVT::i32, Custom);
1004+ }
1005+
10011006 setOperationAction(ISD::UADDO_CARRY, MVT::i32, Custom);
10021007 setOperationAction(ISD::USUBO_CARRY, MVT::i32, Custom);
10031008 if (Subtarget->hasDSP()) {
@@ -4943,7 +4948,7 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
49434948 Value = DAG.getNode(ISD::UMUL_LOHI, dl,
49444949 DAG.getVTList(Op.getValueType(), Op.getValueType()),
49454950 LHS, RHS);
4946- OverflowCmp = DAG.getNode(ARMISD::CMP , dl, FlagsVT, Value.getValue(1),
4951+ OverflowCmp = DAG.getNode(ARMISD::CMPZ , dl, FlagsVT, Value.getValue(1),
49474952 DAG.getConstant(0, dl, MVT::i32));
49484953 Value = Value.getValue(0); // We only want the low 32 bits for the result.
49494954 break;
@@ -4954,7 +4959,7 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
49544959 Value = DAG.getNode(ISD::SMUL_LOHI, dl,
49554960 DAG.getVTList(Op.getValueType(), Op.getValueType()),
49564961 LHS, RHS);
4957- OverflowCmp = DAG.getNode(ARMISD::CMP , dl, FlagsVT, Value.getValue(1),
4962+ OverflowCmp = DAG.getNode(ARMISD::CMPZ , dl, FlagsVT, Value.getValue(1),
49584963 DAG.getNode(ISD::SRA, dl, Op.getValueType(),
49594964 Value.getValue(0),
49604965 DAG.getConstant(31, dl, MVT::i32)));
@@ -4965,28 +4970,6 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
49654970 return std::make_pair(Value, OverflowCmp);
49664971}
49674972
4968- SDValue
4969- ARMTargetLowering::LowerSignedALUO(SDValue Op, SelectionDAG &DAG) const {
4970- // Let legalize expand this if it isn't a legal type yet.
4971- if (!isTypeLegal(Op.getValueType()))
4972- return SDValue();
4973-
4974- SDValue Value, OverflowCmp;
4975- SDValue ARMcc;
4976- std::tie(Value, OverflowCmp) = getARMXALUOOp(Op, DAG, ARMcc);
4977- SDLoc dl(Op);
4978- // We use 0 and 1 as false and true values.
4979- SDValue TVal = DAG.getConstant(1, dl, MVT::i32);
4980- SDValue FVal = DAG.getConstant(0, dl, MVT::i32);
4981- EVT VT = Op.getValueType();
4982-
4983- SDValue Overflow =
4984- DAG.getNode(ARMISD::CMOV, dl, VT, TVal, FVal, ARMcc, OverflowCmp);
4985-
4986- SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
4987- return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
4988- }
4989-
49904973static SDValue ConvertBooleanCarryToCarryFlag(SDValue BoolCarry,
49914974 SelectionDAG &DAG) {
49924975 SDLoc DL(BoolCarry);
@@ -5011,8 +4994,7 @@ static SDValue ConvertCarryFlagToBooleanCarry(SDValue Flags, EVT VT,
50114994 DAG.getConstant(0, DL, MVT::i32), Flags);
50124995}
50134996
5014- SDValue ARMTargetLowering::LowerUnsignedALUO(SDValue Op,
5015- SelectionDAG &DAG) const {
4997+ SDValue ARMTargetLowering::LowerALUO(SDValue Op, SelectionDAG &DAG) const {
50164998 // Let legalize expand this if it isn't a legal type yet.
50174999 if (!isTypeLegal(Op.getValueType()))
50185000 return SDValue();
@@ -5026,14 +5008,12 @@ SDValue ARMTargetLowering::LowerUnsignedALUO(SDValue Op,
50265008 SDValue Value;
50275009 SDValue Overflow;
50285010 switch (Op.getOpcode()) {
5029- default:
5030- llvm_unreachable("Unknown overflow instruction!");
50315011 case ISD::UADDO:
50325012 Value = DAG.getNode(ARMISD::ADDC, dl, VTs, LHS, RHS);
50335013 // Convert the carry flag into a boolean value.
50345014 Overflow = ConvertCarryFlagToBooleanCarry(Value.getValue(1), VT, DAG);
50355015 break;
5036- case ISD::USUBO: {
5016+ case ISD::USUBO:
50375017 Value = DAG.getNode(ARMISD::SUBC, dl, VTs, LHS, RHS);
50385018 // Convert the carry flag into a boolean value.
50395019 Overflow = ConvertCarryFlagToBooleanCarry(Value.getValue(1), VT, DAG);
@@ -5042,6 +5022,17 @@ SDValue ARMTargetLowering::LowerUnsignedALUO(SDValue Op,
50425022 Overflow = DAG.getNode(ISD::SUB, dl, MVT::i32,
50435023 DAG.getConstant(1, dl, MVT::i32), Overflow);
50445024 break;
5025+ default: {
5026+ // Handle other operations with getARMXALUOOp
5027+ SDValue OverflowCmp, ARMcc;
5028+ std::tie(Value, OverflowCmp) = getARMXALUOOp(Op, DAG, ARMcc);
5029+ // We use 0 and 1 as false and true values.
5030+ SDValue TVal = DAG.getConstant(1, dl, MVT::i32);
5031+ SDValue FVal = DAG.getConstant(0, dl, MVT::i32);
5032+
5033+ Overflow =
5034+ DAG.getNode(ARMISD::CMOV, dl, MVT::i32, TVal, FVal, ARMcc, OverflowCmp);
5035+ break;
50455036 }
50465037 }
50475038
@@ -5109,9 +5100,11 @@ SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
51095100 SDLoc dl(Op);
51105101 unsigned Opc = Cond.getOpcode();
51115102
5103+ bool OptimizeMul =
5104+ (Opc == ISD::SMULO || Opc == ISD::UMULO) && !Subtarget->isThumb1Only();
51125105 if (Cond.getResNo() == 1 &&
51135106 (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
5114- Opc == ISD::USUBO)) {
5107+ Opc == ISD::USUBO || OptimizeMul )) {
51155108 if (!isTypeLegal(Cond->getValueType(0)))
51165109 return SDValue();
51175110
@@ -10658,12 +10651,13 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1065810651 case ISD::UADDO_CARRY:
1065910652 case ISD::USUBO_CARRY:
1066010653 return LowerUADDSUBO_CARRY(Op, DAG);
10661- case ISD::SADDO:
10662- case ISD::SSUBO:
10663- return LowerSignedALUO(Op, DAG);
1066410654 case ISD::UADDO:
1066510655 case ISD::USUBO:
10666- return LowerUnsignedALUO(Op, DAG);
10656+ case ISD::UMULO:
10657+ case ISD::SADDO:
10658+ case ISD::SSUBO:
10659+ case ISD::SMULO:
10660+ return LowerALUO(Op, DAG);
1066710661 case ISD::SADDSAT:
1066810662 case ISD::SSUBSAT:
1066910663 case ISD::UADDSAT:
0 commit comments