@@ -4832,59 +4832,47 @@ SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
4832
4832
}
4833
4833
4834
4834
// 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
4836
4836
// comparison and the condition code define the case in which the arithmetic
4837
4837
// computation *does not* overflow.
4838
4838
std::pair<SDValue, SDValue>
4839
4839
ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
4840
4840
SDValue &ARMcc) const {
4841
4841
assert(Op.getValueType() == MVT::i32 && "Unsupported value type");
4842
4842
4843
- SDValue Value, OverflowCmp ;
4843
+ SDValue Value, Overflow ;
4844
4844
SDValue LHS = Op.getOperand(0);
4845
4845
SDValue RHS = Op.getOperand(1);
4846
4846
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;
4852
4848
4853
4849
switch (Op.getOpcode()) {
4854
4850
default:
4855
4851
llvm_unreachable("Unknown overflow instruction!");
4856
4852
case ISD::SADDO:
4853
+ Opc = ARMISD::ADDC;
4857
4854
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);
4860
4855
break;
4861
4856
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);
4869
4859
break;
4870
4860
case ISD::SSUBO:
4861
+ Opc = ARMISD::SUBC;
4871
4862
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);
4874
4863
break;
4875
4864
case ISD::USUBO:
4865
+ Opc = ARMISD::SUBC;
4876
4866
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);
4879
4867
break;
4880
4868
case ISD::UMULO:
4881
4869
// We generate a UMUL_LOHI and then check if the high word is 0.
4882
4870
ARMcc = DAG.getConstant(ARMCC::EQ, dl, MVT::i32);
4883
4871
Value = DAG.getNode(ISD::UMUL_LOHI, dl,
4884
4872
DAG.getVTList(Op.getValueType(), Op.getValueType()),
4885
4873
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));
4888
4876
Value = Value.getValue(0); // We only want the low 32 bits for the result.
4889
4877
break;
4890
4878
case ISD::SMULO:
@@ -4894,15 +4882,34 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
4894
4882
Value = DAG.getNode(ISD::SMUL_LOHI, dl,
4895
4883
DAG.getVTList(Op.getValueType(), Op.getValueType()),
4896
4884
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)));
4901
4889
Value = Value.getValue(0); // We only want the low 32 bits for the result.
4902
4890
break;
4903
4891
} // 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
+ }
4904
4911
4905
- return std::make_pair(Value, OverflowCmp );
4912
+ return std::make_pair(Value, Overflow );
4906
4913
}
4907
4914
4908
4915
SDValue
@@ -4911,20 +4918,18 @@ ARMTargetLowering::LowerSignedALUO(SDValue Op, SelectionDAG &DAG) const {
4911
4918
if (!isTypeLegal(Op.getValueType()))
4912
4919
return SDValue();
4913
4920
4914
- SDValue Value, OverflowCmp;
4915
- SDValue ARMcc;
4916
- std::tie(Value, OverflowCmp) = getARMXALUOOp(Op, DAG, ARMcc);
4917
4921
SDLoc dl(Op);
4922
+ SDValue Value, Overflow;
4923
+ SDValue ARMcc;
4924
+ std::tie(Value, Overflow) = getARMXALUOOp(Op, DAG, ARMcc);
4918
4925
// We use 0 and 1 as false and true values.
4919
4926
SDValue TVal = DAG.getConstant(1, dl, MVT::i32);
4920
4927
SDValue FVal = DAG.getConstant(0, dl, MVT::i32);
4921
- EVT VT = Op.getValueType();
4922
4928
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 );
4925
4931
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);
4928
4933
}
4929
4934
4930
4935
static SDValue ConvertBooleanCarryToCarryFlag(SDValue BoolCarry,
@@ -5055,12 +5060,12 @@ SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
5055
5060
if (!isTypeLegal(Cond->getValueType(0)))
5056
5061
return SDValue();
5057
5062
5058
- SDValue Value, OverflowCmp ;
5063
+ SDValue Value, Overflow ;
5059
5064
SDValue ARMcc;
5060
- std::tie(Value, OverflowCmp ) = getARMXALUOOp(Cond, DAG, ARMcc);
5065
+ std::tie(Value, Overflow ) = getARMXALUOOp(Cond, DAG, ARMcc);
5061
5066
EVT VT = Op.getValueType();
5062
5067
5063
- return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, OverflowCmp , DAG);
5068
+ return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, Overflow , DAG);
5064
5069
}
5065
5070
5066
5071
// Convert:
@@ -5657,9 +5662,9 @@ SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
5657
5662
return SDValue();
5658
5663
5659
5664
// The actual operation with overflow check.
5660
- SDValue Value, OverflowCmp ;
5665
+ SDValue Value, Overflow ;
5661
5666
SDValue ARMcc;
5662
- std::tie(Value, OverflowCmp ) = getARMXALUOOp(Cond, DAG, ARMcc);
5667
+ std::tie(Value, Overflow ) = getARMXALUOOp(Cond, DAG, ARMcc);
5663
5668
5664
5669
// Reverse the condition code.
5665
5670
ARMCC::CondCodes CondCode =
@@ -5668,7 +5673,7 @@ SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
5668
5673
ARMcc = DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
5669
5674
5670
5675
return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5671
- OverflowCmp );
5676
+ Overflow );
5672
5677
}
5673
5678
5674
5679
return SDValue();
@@ -5707,9 +5712,9 @@ SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
5707
5712
return SDValue();
5708
5713
5709
5714
// The actual operation with overflow check.
5710
- SDValue Value, OverflowCmp ;
5715
+ SDValue Value, Overflow ;
5711
5716
SDValue ARMcc;
5712
- std::tie(Value, OverflowCmp ) = getARMXALUOOp(LHS.getValue(0), DAG, ARMcc);
5717
+ std::tie(Value, Overflow ) = getARMXALUOOp(LHS.getValue(0), DAG, ARMcc);
5713
5718
5714
5719
if ((CC == ISD::SETNE) != isOneConstant(RHS)) {
5715
5720
// Reverse the condition code.
@@ -5720,7 +5725,7 @@ SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
5720
5725
}
5721
5726
5722
5727
return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
5723
- OverflowCmp );
5728
+ Overflow );
5724
5729
}
5725
5730
5726
5731
if (LHS.getValueType() == MVT::i32) {
0 commit comments