Skip to content

Commit 44f65f3

Browse files
committed
[ARM] Set operation action for UMULO and SMULO as Custom if not Thumb1
We should specify a custom lowering for SMULO and UMULO like we do for AArch64, but only if not Thumb 1 obviously. Properly lower UMULO and SMULO if not thumb1.
1 parent 5ad56ca commit 44f65f3

File tree

4 files changed

+81
-90
lines changed

4 files changed

+81
-90
lines changed

llvm/lib/Target/ARM/ARMISelLowering.cpp

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
49904973
static 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:

llvm/lib/Target/ARM/ARMISelLowering.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -881,8 +881,7 @@ class VectorType;
881881
SDValue LowerGlobalTLSAddressDarwin(SDValue Op, SelectionDAG &DAG) const;
882882
SDValue LowerGlobalTLSAddressWindows(SDValue Op, SelectionDAG &DAG) const;
883883
SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
884-
SDValue LowerSignedALUO(SDValue Op, SelectionDAG &DAG) const;
885-
SDValue LowerUnsignedALUO(SDValue Op, SelectionDAG &DAG) const;
884+
SDValue LowerALUO(SDValue Op, SelectionDAG &DAG) const;
886885
SDValue LowerSELECT(SDValue Op, SelectionDAG &DAG) const;
887886
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
888887
SDValue LowerBRCOND(SDValue Op, SelectionDAG &DAG) const;

0 commit comments

Comments
 (0)