[llvm] Revert "[ARM] Stop gluing ALU nodes to branches / selects" (PR #118232)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Dec 1 14:02:44 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-arm
Author: Martin Storsjö (mstorsjo)
<details>
<summary>Changes</summary>
Reverts llvm/llvm-project#<!-- -->116970.
This change broke Wine compiled for armv7, causing segfaults when starting Wine. See llvm/llvm-project#<!-- -->116970 for more detailed discussion about the issue.
---
Patch is 1.12 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/118232.diff
83 Files Affected:
- (modified) llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp (+35-18)
- (modified) llvm/lib/Target/ARM/ARMISelLowering.cpp (+134-71)
- (modified) llvm/lib/Target/ARM/ARMISelLowering.h (+3-1)
- (modified) llvm/lib/Target/ARM/ARMInstrFormats.td (+10-3)
- (modified) llvm/lib/Target/ARM/ARMInstrInfo.td (+64-84)
- (modified) llvm/lib/Target/ARM/ARMInstrThumb.td (+10-12)
- (modified) llvm/lib/Target/ARM/ARMInstrThumb2.td (+65-87)
- (modified) llvm/lib/Target/ARM/ARMInstrVFP.td (+20-32)
- (modified) llvm/test/CodeGen/ARM/add-like-or.ll (+5-5)
- (modified) llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll (+43-51)
- (modified) llvm/test/CodeGen/ARM/atomic-64bit.ll (+40-20)
- (modified) llvm/test/CodeGen/ARM/atomic-ops-v8.ll (+20-8)
- (modified) llvm/test/CodeGen/ARM/atomicrmw-cond-sub-clamp.ll (+16-12)
- (modified) llvm/test/CodeGen/ARM/atomicrmw-uinc-udec-wrap.ll (+19-15)
- (modified) llvm/test/CodeGen/ARM/atomicrmw_exclusive_monitor_ints.ll (+68-56)
- (modified) llvm/test/CodeGen/ARM/bfi.ll (+4-5)
- (modified) llvm/test/CodeGen/ARM/cmov_fp16.ll (+54-54)
- (modified) llvm/test/CodeGen/ARM/cse-call.ll (+1-3)
- (modified) llvm/test/CodeGen/ARM/cttz.ll (+106-98)
- (modified) llvm/test/CodeGen/ARM/fadd-select-fneg-combine.ll (+10-10)
- (modified) llvm/test/CodeGen/ARM/fcmp-xo.ll (+10-10)
- (modified) llvm/test/CodeGen/ARM/fpclamptosat.ll (+1050-694)
- (modified) llvm/test/CodeGen/ARM/fpclamptosat_vec.ll (+1640-1564)
- (modified) llvm/test/CodeGen/ARM/fpscr-multi-use.ll (+12-32)
- (modified) llvm/test/CodeGen/ARM/fptoi-sat-store.ll (+80-77)
- (modified) llvm/test/CodeGen/ARM/fptosi-sat-scalar.ll (+864-798)
- (modified) llvm/test/CodeGen/ARM/fptoui-sat-scalar.ll (+779-693)
- (modified) llvm/test/CodeGen/ARM/funnel-shift-rot.ll (+4-4)
- (modified) llvm/test/CodeGen/ARM/funnel-shift.ll (+74-70)
- (modified) llvm/test/CodeGen/ARM/ifcvt1.ll (+3-3)
- (modified) llvm/test/CodeGen/ARM/minnum-maxnum-intrinsics.ll (+34-34)
- (modified) llvm/test/CodeGen/ARM/neon_vabd.ll (+20-20)
- (modified) llvm/test/CodeGen/ARM/overflow-intrinsic-optimizations.ll (+3-3)
- (modified) llvm/test/CodeGen/ARM/sadd_sat.ll (+23-21)
- (modified) llvm/test/CodeGen/ARM/sadd_sat_plus.ll (+11-11)
- (modified) llvm/test/CodeGen/ARM/select.ll (+24-24)
- (modified) llvm/test/CodeGen/ARM/select_const.ll (+5-7)
- (modified) llvm/test/CodeGen/ARM/shift-i64.ll (+7-7)
- (modified) llvm/test/CodeGen/ARM/ssub_sat.ll (+11-10)
- (modified) llvm/test/CodeGen/ARM/ssub_sat_plus.ll (+11-11)
- (modified) llvm/test/CodeGen/ARM/sub-cmp-peephole.ll (+1-1)
- (modified) llvm/test/CodeGen/ARM/uadd_sat.ll (+5-3)
- (modified) llvm/test/CodeGen/ARM/uadd_sat_plus.ll (+13-11)
- (modified) llvm/test/CodeGen/ARM/umulo-128-legalisation-lowering.ll (+160-162)
- (modified) llvm/test/CodeGen/ARM/umulo-64-legalisation-lowering.ll (+27-26)
- (modified) llvm/test/CodeGen/ARM/usub_sat.ll (+4-3)
- (modified) llvm/test/CodeGen/ARM/usub_sat_plus.ll (+4-3)
- (modified) llvm/test/CodeGen/ARM/vselect_imax.ll (+181-177)
- (modified) llvm/test/CodeGen/ARM/wide-compares.ll (+56-29)
- (modified) llvm/test/CodeGen/Thumb/arm_q15_to_q31.ll (+2-1)
- (modified) llvm/test/CodeGen/Thumb/select.ll (+2-2)
- (modified) llvm/test/CodeGen/Thumb/smul_fix_sat.ll (+228-198)
- (modified) llvm/test/CodeGen/Thumb/stack-guard-xo.ll (+75-175)
- (modified) llvm/test/CodeGen/Thumb/umul_fix_sat.ll (+79-82)
- (modified) llvm/test/CodeGen/Thumb2/LowOverheadLoops/arm_cmplx_dot_prod_f32.ll (+3-3)
- (modified) llvm/test/CodeGen/Thumb2/LowOverheadLoops/exitcount.ll (+8-8)
- (modified) llvm/test/CodeGen/Thumb2/LowOverheadLoops/fast-fp-loops.ll (+5-5)
- (modified) llvm/test/CodeGen/Thumb2/float-ops.ll (+5-5)
- (modified) llvm/test/CodeGen/Thumb2/mve-blockplacement.ll (+4-4)
- (modified) llvm/test/CodeGen/Thumb2/mve-doublereduct.ll (+24-24)
- (modified) llvm/test/CodeGen/Thumb2/mve-float16regloops.ll (+1-1)
- (modified) llvm/test/CodeGen/Thumb2/mve-float32regloops.ll (+3-3)
- (modified) llvm/test/CodeGen/Thumb2/mve-fmas.ll (+58-58)
- (modified) llvm/test/CodeGen/Thumb2/mve-fpclamptosat_vec.ll (+381-323)
- (modified) llvm/test/CodeGen/Thumb2/mve-fptosi-sat-vector.ll (+2038-1745)
- (modified) llvm/test/CodeGen/Thumb2/mve-fptoui-sat-vector.ll (+1619-1366)
- (modified) llvm/test/CodeGen/Thumb2/mve-gather-scatter-ptr-address.ll (+8-8)
- (modified) llvm/test/CodeGen/Thumb2/mve-laneinterleaving.ll (+46-47)
- (modified) llvm/test/CodeGen/Thumb2/mve-minmaxi.ll (+40-24)
- (modified) llvm/test/CodeGen/Thumb2/mve-pipelineloops.ll (+1-1)
- (modified) llvm/test/CodeGen/Thumb2/mve-pred-ext.ll (+143-151)
- (modified) llvm/test/CodeGen/Thumb2/mve-pred-or.ll (+10-8)
- (modified) llvm/test/CodeGen/Thumb2/mve-pred-vctpvpsel.ll (+8-8)
- (modified) llvm/test/CodeGen/Thumb2/mve-pred-vselect.ll (+57-53)
- (modified) llvm/test/CodeGen/Thumb2/mve-pred-xor.ll (+12-10)
- (modified) llvm/test/CodeGen/Thumb2/mve-satmul-loops.ll (+64-59)
- (modified) llvm/test/CodeGen/Thumb2/mve-vcmpf.ll (+78-78)
- (modified) llvm/test/CodeGen/Thumb2/mve-vcmpfr.ll (+156-156)
- (modified) llvm/test/CodeGen/Thumb2/mve-vcmpfz.ll (+156-156)
- (modified) llvm/test/CodeGen/Thumb2/mve-vmaxv-vminv-scalar.ll (+32-16)
- (modified) llvm/test/CodeGen/Thumb2/mve-vqdmulh.ll (+2-2)
- (modified) llvm/test/CodeGen/Thumb2/umulo-128-legalisation-lowering.ll (+96-94)
- (modified) llvm/test/CodeGen/Thumb2/umulo-64-legalisation-lowering.ll (+13-12)
``````````diff
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
index fd024ffdeefde4..73ee8cf81adcd6 100644
--- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -111,6 +111,13 @@ class ARMDAGToDAGISel : public SelectionDAGISel {
bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm);
bool SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc);
+ bool SelectCMOVPred(SDValue N, SDValue &Pred, SDValue &Reg) {
+ const ConstantSDNode *CN = cast<ConstantSDNode>(N);
+ Pred = CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(N), MVT::i32);
+ Reg = CurDAG->getRegister(ARM::CPSR, MVT::i32);
+ return true;
+ }
+
bool SelectAddrMode2OffsetReg(SDNode *Op, SDValue N,
SDValue &Offset, SDValue &Opc);
bool SelectAddrMode2OffsetImm(SDNode *Op, SDValue N,
@@ -4116,15 +4123,17 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
SDValue Chain = N->getOperand(0);
SDValue N1 = N->getOperand(1);
SDValue N2 = N->getOperand(2);
- SDValue Flags = N->getOperand(3);
+ SDValue N3 = N->getOperand(3);
+ SDValue InGlue = N->getOperand(4);
assert(N1.getOpcode() == ISD::BasicBlock);
assert(N2.getOpcode() == ISD::Constant);
+ assert(N3.getOpcode() == ISD::Register);
unsigned CC = (unsigned)N2->getAsZExtVal();
- if (Flags.getOpcode() == ARMISD::CMPZ) {
- if (Flags.getOperand(0).getOpcode() == ISD::INTRINSIC_W_CHAIN) {
- SDValue Int = Flags.getOperand(0);
+ if (InGlue.getOpcode() == ARMISD::CMPZ) {
+ if (InGlue.getOperand(0).getOpcode() == ISD::INTRINSIC_W_CHAIN) {
+ SDValue Int = InGlue.getOperand(0);
uint64_t ID = Int->getConstantOperandVal(1);
// Handle low-overhead loops.
@@ -4146,15 +4155,15 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
ReplaceUses(N, LoopEnd);
CurDAG->RemoveDeadNode(N);
- CurDAG->RemoveDeadNode(Flags.getNode());
+ CurDAG->RemoveDeadNode(InGlue.getNode());
CurDAG->RemoveDeadNode(Int.getNode());
return;
}
}
bool SwitchEQNEToPLMI;
- SelectCMPZ(Flags.getNode(), SwitchEQNEToPLMI);
- Flags = N->getOperand(3);
+ SelectCMPZ(InGlue.getNode(), SwitchEQNEToPLMI);
+ InGlue = N->getOperand(4);
if (SwitchEQNEToPLMI) {
switch ((ARMCC::CondCodes)CC) {
@@ -4170,18 +4179,25 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
}
SDValue Tmp2 = CurDAG->getTargetConstant(CC, dl, MVT::i32);
- Chain = CurDAG->getCopyToReg(Chain, dl, ARM::CPSR, Flags, SDValue());
- SDValue Ops[] = {N1, Tmp2, CurDAG->getRegister(ARM::CPSR, MVT::i32), Chain,
- Chain.getValue(1)};
- CurDAG->SelectNodeTo(N, Opc, MVT::Other, Ops);
+ SDValue Ops[] = { N1, Tmp2, N3, Chain, InGlue };
+ SDNode *ResNode = CurDAG->getMachineNode(Opc, dl, MVT::Other,
+ MVT::Glue, Ops);
+ Chain = SDValue(ResNode, 0);
+ if (N->getNumValues() == 2) {
+ InGlue = SDValue(ResNode, 1);
+ ReplaceUses(SDValue(N, 1), InGlue);
+ }
+ ReplaceUses(SDValue(N, 0),
+ SDValue(Chain.getNode(), Chain.getResNo()));
+ CurDAG->RemoveDeadNode(N);
return;
}
case ARMISD::CMPZ: {
// select (CMPZ X, #-C) -> (CMPZ (ADDS X, #C), #0)
// This allows us to avoid materializing the expensive negative constant.
- // The CMPZ #0 is useless and will be peepholed away but we need to keep
- // it for its flags output.
+ // The CMPZ #0 is useless and will be peepholed away but we need to keep it
+ // for its glue output.
SDValue X = N->getOperand(0);
auto *C = dyn_cast<ConstantSDNode>(N->getOperand(1).getNode());
if (C && C->getSExtValue() < 0 && Subtarget->isThumb()) {
@@ -4208,7 +4224,7 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
}
if (Add) {
SDValue Ops2[] = {SDValue(Add, 0), CurDAG->getConstant(0, dl, MVT::i32)};
- CurDAG->MorphNodeTo(N, ARMISD::CMPZ, N->getVTList(), Ops2);
+ CurDAG->MorphNodeTo(N, ARMISD::CMPZ, CurDAG->getVTList(MVT::Glue), Ops2);
}
}
// Other cases are autogenerated.
@@ -4216,11 +4232,11 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
}
case ARMISD::CMOV: {
- SDValue Flags = N->getOperand(3);
+ SDValue InGlue = N->getOperand(4);
- if (Flags.getOpcode() == ARMISD::CMPZ) {
+ if (InGlue.getOpcode() == ARMISD::CMPZ) {
bool SwitchEQNEToPLMI;
- SelectCMPZ(Flags.getNode(), SwitchEQNEToPLMI);
+ SelectCMPZ(InGlue.getNode(), SwitchEQNEToPLMI);
if (SwitchEQNEToPLMI) {
SDValue ARMcc = N->getOperand(2);
@@ -4237,9 +4253,10 @@ void ARMDAGToDAGISel::Select(SDNode *N) {
}
SDValue NewARMcc = CurDAG->getConstant((unsigned)CC, dl, MVT::i32);
SDValue Ops[] = {N->getOperand(0), N->getOperand(1), NewARMcc,
- N->getOperand(3)};
+ N->getOperand(3), N->getOperand(4)};
CurDAG->MorphNodeTo(N, ARMISD::CMOV, N->getVTList(), Ops);
}
+
}
// Other cases are autogenerated.
break;
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index c9250e4ed3422c..6b290135c5bcba 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -4924,11 +4924,14 @@ SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
CC == ISD::SETUGT && isa<ConstantSDNode>(LHS.getOperand(1)) &&
LHS.getConstantOperandVal(1) < 31) {
unsigned ShiftAmt = LHS.getConstantOperandVal(1) + 1;
- SDValue Shift =
- DAG.getNode(ARMISD::LSLS, dl, DAG.getVTList(MVT::i32, FlagsVT),
- LHS.getOperand(0), DAG.getConstant(ShiftAmt, dl, MVT::i32));
+ SDValue Shift = DAG.getNode(ARMISD::LSLS, dl,
+ DAG.getVTList(MVT::i32, MVT::i32),
+ LHS.getOperand(0),
+ DAG.getConstant(ShiftAmt, dl, MVT::i32));
+ SDValue Chain = DAG.getCopyToReg(DAG.getEntryNode(), dl, ARM::CPSR,
+ Shift.getValue(1), SDValue());
ARMcc = DAG.getConstant(ARMCC::HI, dl, MVT::i32);
- return Shift.getValue(1);
+ return Chain.getValue(1);
}
ARMCC::CondCodes CondCode = IntCCToARMCC(CC);
@@ -4960,7 +4963,7 @@ SDValue ARMTargetLowering::getARMCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC,
break;
}
ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
- return DAG.getNode(CompareType, dl, FlagsVT, LHS, RHS);
+ return DAG.getNode(CompareType, dl, MVT::Glue, LHS, RHS);
}
/// Returns a appropriate VFP CMP (fcmp{s|d}+fmstat) for the given operands.
@@ -4975,7 +4978,24 @@ SDValue ARMTargetLowering::getVFPCmp(SDValue LHS, SDValue RHS,
else
Flags = DAG.getNode(Signaling ? ARMISD::CMPFPEw0 : ARMISD::CMPFPw0, dl,
FlagsVT, LHS);
- return DAG.getNode(ARMISD::FMSTAT, dl, FlagsVT, Flags);
+ return DAG.getNode(ARMISD::FMSTAT, dl, MVT::Glue, Flags);
+}
+
+/// duplicateCmp - Glue values can have only one use, so this function
+/// duplicates a comparison node.
+SDValue
+ARMTargetLowering::duplicateCmp(SDValue Cmp, SelectionDAG &DAG) const {
+ unsigned Opc = Cmp.getOpcode();
+ SDLoc DL(Cmp);
+ if (Opc == ARMISD::CMP || Opc == ARMISD::CMPZ)
+ return DAG.getNode(Opc, DL, MVT::Glue, Cmp.getOperand(0),Cmp.getOperand(1));
+
+ assert(Opc == ARMISD::FMSTAT && "unexpected comparison operation");
+ SDValue Flags = Cmp.getOperand(0);
+ assert((Flags.getOpcode() == ARMISD::CMPFP ||
+ Flags.getOpcode() == ARMISD::CMPFPw0) &&
+ "unexpected operand of FMSTAT");
+ return DAG.getNode(ARMISD::FMSTAT, DL, MVT::Glue, Flags);
}
// This function returns three things: the arithmetic computation itself
@@ -5003,7 +5023,7 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
case ISD::SADDO:
ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
Value = DAG.getNode(ISD::ADD, dl, Op.getValueType(), LHS, RHS);
- OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
+ OverflowCmp = DAG.getNode(ARMISD::CMP, dl, MVT::Glue, Value, LHS);
break;
case ISD::UADDO:
ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
@@ -5012,17 +5032,17 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
Value = DAG.getNode(ARMISD::ADDC, dl,
DAG.getVTList(Op.getValueType(), MVT::i32), LHS, RHS)
.getValue(0);
- OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value, LHS);
+ OverflowCmp = DAG.getNode(ARMISD::CMP, dl, MVT::Glue, Value, LHS);
break;
case ISD::SSUBO:
ARMcc = DAG.getConstant(ARMCC::VC, dl, MVT::i32);
Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
- OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
+ OverflowCmp = DAG.getNode(ARMISD::CMP, dl, MVT::Glue, LHS, RHS);
break;
case ISD::USUBO:
ARMcc = DAG.getConstant(ARMCC::HS, dl, MVT::i32);
Value = DAG.getNode(ISD::SUB, dl, Op.getValueType(), LHS, RHS);
- OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, LHS, RHS);
+ OverflowCmp = DAG.getNode(ARMISD::CMP, dl, MVT::Glue, LHS, RHS);
break;
case ISD::UMULO:
// We generate a UMUL_LOHI and then check if the high word is 0.
@@ -5030,7 +5050,7 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
Value = DAG.getNode(ISD::UMUL_LOHI, dl,
DAG.getVTList(Op.getValueType(), Op.getValueType()),
LHS, RHS);
- OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value.getValue(1),
+ OverflowCmp = DAG.getNode(ARMISD::CMP, dl, MVT::Glue, Value.getValue(1),
DAG.getConstant(0, dl, MVT::i32));
Value = Value.getValue(0); // We only want the low 32 bits for the result.
break;
@@ -5041,7 +5061,7 @@ ARMTargetLowering::getARMXALUOOp(SDValue Op, SelectionDAG &DAG,
Value = DAG.getNode(ISD::SMUL_LOHI, dl,
DAG.getVTList(Op.getValueType(), Op.getValueType()),
LHS, RHS);
- OverflowCmp = DAG.getNode(ARMISD::CMP, dl, FlagsVT, Value.getValue(1),
+ OverflowCmp = DAG.getNode(ARMISD::CMP, dl, MVT::Glue, Value.getValue(1),
DAG.getNode(ISD::SRA, dl, Op.getValueType(),
Value.getValue(0),
DAG.getConstant(31, dl, MVT::i32)));
@@ -5061,14 +5081,15 @@ ARMTargetLowering::LowerSignedALUO(SDValue Op, SelectionDAG &DAG) const {
SDValue Value, OverflowCmp;
SDValue ARMcc;
std::tie(Value, OverflowCmp) = getARMXALUOOp(Op, DAG, ARMcc);
+ SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
SDLoc dl(Op);
// We use 0 and 1 as false and true values.
SDValue TVal = DAG.getConstant(1, dl, MVT::i32);
SDValue FVal = DAG.getConstant(0, dl, MVT::i32);
EVT VT = Op.getValueType();
- SDValue Overflow =
- DAG.getNode(ARMISD::CMOV, dl, VT, TVal, FVal, ARMcc, OverflowCmp);
+ SDValue Overflow = DAG.getNode(ARMISD::CMOV, dl, VT, TVal, FVal,
+ ARMcc, CCR, OverflowCmp);
SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::i32);
return DAG.getNode(ISD::MERGE_VALUES, dl, VTs, Value, Overflow);
@@ -5205,9 +5226,11 @@ SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
SDValue Value, OverflowCmp;
SDValue ARMcc;
std::tie(Value, OverflowCmp) = getARMXALUOOp(Cond, DAG, ARMcc);
+ SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
EVT VT = Op.getValueType();
- return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, OverflowCmp, DAG);
+ return getCMOV(dl, VT, SelectTrue, SelectFalse, ARMcc, CCR,
+ OverflowCmp, DAG);
}
// Convert:
@@ -5235,9 +5258,14 @@ SDValue ARMTargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
False = SelectTrue;
}
- if (True.getNode() && False.getNode())
- return getCMOV(dl, Op.getValueType(), True, False, Cond.getOperand(2),
- Cond.getOperand(3), DAG);
+ if (True.getNode() && False.getNode()) {
+ EVT VT = Op.getValueType();
+ SDValue ARMcc = Cond.getOperand(2);
+ SDValue CCR = Cond.getOperand(3);
+ SDValue Cmp = duplicateCmp(Cond.getOperand(4), DAG);
+ assert(True.getValueType() == VT);
+ return getCMOV(dl, VT, True, False, ARMcc, CCR, Cmp, DAG);
+ }
}
}
@@ -5302,8 +5330,8 @@ static void checkVSELConstraints(ISD::CondCode CC, ARMCC::CondCodes &CondCode,
}
SDValue ARMTargetLowering::getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal,
- SDValue TrueVal, SDValue ARMcc,
- SDValue Flags, SelectionDAG &DAG) const {
+ SDValue TrueVal, SDValue ARMcc, SDValue CCR,
+ SDValue Cmp, SelectionDAG &DAG) const {
if (!Subtarget->hasFP64() && VT == MVT::f64) {
FalseVal = DAG.getNode(ARMISD::VMOVRRD, dl,
DAG.getVTList(MVT::i32, MVT::i32), FalseVal);
@@ -5316,13 +5344,15 @@ SDValue ARMTargetLowering::getCMOV(const SDLoc &dl, EVT VT, SDValue FalseVal,
SDValue FalseHigh = FalseVal.getValue(1);
SDValue Low = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseLow, TrueLow,
- ARMcc, Flags);
+ ARMcc, CCR, Cmp);
SDValue High = DAG.getNode(ARMISD::CMOV, dl, MVT::i32, FalseHigh, TrueHigh,
- ARMcc, Flags);
+ ARMcc, CCR, duplicateCmp(Cmp, DAG));
return DAG.getNode(ARMISD::VMOVDRR, dl, MVT::f64, Low, High);
+ } else {
+ return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMcc, CCR,
+ Cmp);
}
- return DAG.getNode(ARMISD::CMOV, dl, VT, FalseVal, TrueVal, ARMcc, Flags);
}
static bool isGTorGE(ISD::CondCode CC) {
@@ -5595,11 +5625,12 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
}
SDValue ARMcc;
+ SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
// Choose GE over PL, which vsel does now support
if (ARMcc->getAsZExtVal() == ARMCC::PL)
ARMcc = DAG.getConstant(ARMCC::GE, dl, MVT::i32);
- return getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
+ return getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, CCR, Cmp, DAG);
}
ARMCC::CondCodes CondCode, CondCode2;
@@ -5629,10 +5660,13 @@ SDValue ARMTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
- SDValue Result = getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, Cmp, DAG);
+ SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
+ SDValue Result = getCMOV(dl, VT, FalseVal, TrueVal, ARMcc, CCR, Cmp, DAG);
if (CondCode2 != ARMCC::AL) {
SDValue ARMcc2 = DAG.getConstant(CondCode2, dl, MVT::i32);
- Result = getCMOV(dl, VT, Result, TrueVal, ARMcc2, Cmp, DAG);
+ // FIXME: Needs another CMP because flag can have but one use.
+ SDValue Cmp2 = getVFPCmp(LHS, RHS, DAG, dl);
+ Result = getCMOV(dl, VT, Result, TrueVal, ARMcc2, CCR, Cmp2, DAG);
}
return Result;
}
@@ -5733,8 +5767,9 @@ ARMTargetLowering::OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const {
RHS = DAG.getNode(ISD::AND, dl, MVT::i32,
bitcastf32Toi32(RHS, DAG), Mask);
SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
- return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
- Cmp);
+ SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
+ return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other,
+ Chain, Dest, ARMcc, CCR, Cmp);
}
SDValue LHS1, LHS2;
@@ -5745,8 +5780,9 @@ ARMTargetLowering::OptimizeVFPBrcond(SDValue Op, SelectionDAG &DAG) const {
RHS2 = DAG.getNode(ISD::AND, dl, MVT::i32, RHS2, Mask);
ARMCC::CondCodes CondCode = IntCCToARMCC(CC);
ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
+ SDVTList VTList = DAG.getVTList(MVT::Other, MVT::Glue);
SDValue Ops[] = { Chain, ARMcc, LHS1, LHS2, RHS1, RHS2, Dest };
- return DAG.getNode(ARMISD::BCC_i64, dl, MVT::Other, Ops);
+ return DAG.getNode(ARMISD::BCC_i64, dl, VTList, Ops);
}
return SDValue();
@@ -5780,8 +5816,9 @@ SDValue ARMTargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) const {
(ARMCC::CondCodes)cast<const ConstantSDNode>(ARMcc)->getZExtValue();
CondCode = ARMCC::getOppositeCondition(CondCode);
ARMcc = DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
+ SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
- return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
+ return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc, CCR,
OverflowCmp);
}
@@ -5833,15 +5870,18 @@ SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
CondCode = ARMCC::getOppositeCondition(CondCode);
ARMcc = DAG.getConstant(CondCode, SDLoc(ARMcc), MVT::i32);
}
+ SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
- return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc,
+ return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc, CCR,
OverflowCmp);
}
if (LHS.getValueType() == MVT::i32) {
SDValue ARMcc;
SDValue Cmp = getARMCmp(LHS, RHS, CC, ARMcc, DAG, dl);
- return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Chain, Dest, ARMcc, Cmp);
+ SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
+ return DAG.getNode(ARMISD::BRCOND, dl, MVT::Other,
+ Chain, Dest, ARMcc, CCR, Cmp);
}
if (getTargetMachine().Options.UnsafeFPMath &&
@@ -5856,12 +5896,14 @@ SDValue ARMTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
SDValue ARMcc = DAG.getConstant(CondCode, dl, MVT::i32);
SDValue Cmp = getVFPCmp(LHS, RHS, DAG, dl);
- SDValue Ops[] = {Chain, Dest, ARMcc, Cmp};
- SDValue Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
+ SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
+ SDVTList VTList = DAG.getVTList(MVT::Other, MVT::Glue);
+ SDValue Ops[] = { Chain, Dest, ARMcc, CCR, Cmp };
+ SDValue Res = DAG.getNode(ARMISD::BRCOND, dl, VTList, Ops);
if (CondCode2 != ARMCC::AL) {
ARMcc = DAG.getConstant(CondCode2, dl, MVT::i32);
- SDValue Ops[] = {Res, Dest, ARMcc, Cmp};
- Res = DAG.getNode(ARMISD::BRCOND, dl, MVT::Other, Ops);
+ SDValue Ops[] = { Res, Dest, ARMcc, CCR, Res.getValue(1) };
+ Res = DAG.getNode(ARMISD::BRCOND, dl, VTList, Ops);
}
return Res;
}
@@ -6366,6 +6408,7 @@ SDValue ARMTargetLowering::LowerShiftRightParts(SDValue Op,
SDValue ShOpHi = Op.getOperand(1);
SDValue ShAmt = Op.getOperand(2);
SDValue ARMcc;
+ SDValue CCR = DAG.getRegister(ARM::CPSR, MVT::i32);
unsigned Opc = (Op.getOpcode() == ISD::SRA_PARTS) ? ISD::SRA : ISD::SRL;
assert(Op.getOpcode() == ISD::SRA_PARTS || Op.getOpcode() == ISD::SRL_PARTS);
@@ -6380,8 +6423,8 @@ SDValue ARMTargetLowering::LowerShiftRightParts(SDValue Op,
SDValue LoBigShift = DAG.getNode(Opc, dl, VT, ShOpHi, ExtraShAmt);
SDValue CmpLo = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
ISD::SETGE, ARMcc, DAG, dl);
- SDValue Lo =
- DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift, LoBigShift, ARMcc, CmpLo);
+ SDValue Lo = DAG.getNode(ARMISD::CMOV, dl, VT, LoSmallShift, LoBigShift,
+ ARMcc, CCR, CmpLo);
SDValue HiSmallShift = DAG.getNode(Opc, dl, VT, ShOpHi, ShAmt);
SDValue HiBigShift = Opc == ISD::SRA
@@ -6390,8 +6433,8 @@ SDValue ARMTargetLowering::LowerShiftRightParts(SDValue Op,
: DAG.getConstant(0, dl, VT);
SDValue CmpHi = getARMCmp(ExtraShAmt, DAG.getConstant(0, dl, MVT::i32),
ISD::SETGE, ARMcc, DAG, dl);
- SDValue Hi =
- DAG.getNode(ARMISD::CMOV, dl, VT, HiSmallShift, HiBigShift, ARMcc, CmpHi);
+ SDValue Hi = DAG.getNode(ARMISD::CMOV, d...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/118232
More information about the llvm-commits
mailing list