[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