Skip to content

[PowerPC] Deprecate uses of ISD::ADDC/ISD::ADDE/ISD::SUBC/ISD::SUBE #116984

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 13, 2025

Conversation

diggerlin
Copy link
Contributor

@diggerlin diggerlin commented Nov 20, 2024

The patch is based on the Kai's patch #88604, thanks for Kai's work.

ISD::ADDC, ISD::ADDE, ISD::SUBC and ISD::SUBE are being deprecated, using ISD::UADDO_CARRY,ISD::USUBO_CARRY instead. Lowering the UADDO, UADDO_CARRY, USUBO, USUBO_CARRY in the patch.

@llvmbot
Copy link
Member

llvmbot commented Nov 20, 2024

@llvm/pr-subscribers-backend-powerpc

Author: zhijian lin (diggerlin)

Changes

Patch is 63.53 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/116984.diff

26 Files Affected:

  • (modified) llvm/lib/Target/PowerPC/PPCISelLowering.cpp (+133-15)
  • (modified) llvm/lib/Target/PowerPC/PPCISelLowering.h (+8)
  • (modified) llvm/lib/Target/PowerPC/PPCInstr64Bit.td (+10-10)
  • (modified) llvm/lib/Target/PowerPC/PPCInstrInfo.cpp (+17)
  • (modified) llvm/lib/Target/PowerPC/PPCInstrInfo.td (+34-10)
  • (modified) llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp (+11)
  • (modified) llvm/lib/Target/PowerPC/PPCRegisterInfo.h (+3)
  • (modified) llvm/lib/Target/PowerPC/PPCRegisterInfo.td (+1)
  • (modified) llvm/test/CodeGen/PowerPC/adde_return_type.ll (+1-1)
  • (modified) llvm/test/CodeGen/PowerPC/addegluecrash.ll (+12-12)
  • (modified) llvm/test/CodeGen/PowerPC/aix-cc-abi-mir.ll (+8-8)
  • (modified) llvm/test/CodeGen/PowerPC/aix-cc-abi.ll (+4-4)
  • (modified) llvm/test/CodeGen/PowerPC/aix-cc-byval-split.ll (+4-4)
  • (modified) llvm/test/CodeGen/PowerPC/aix-tls-gd-longlong.ll (+27-23)
  • (modified) llvm/test/CodeGen/PowerPC/aix-tls-le-ldst-longlong.ll (+60-60)
  • (modified) llvm/test/CodeGen/PowerPC/aix-tls-le-xcoff-reloc-large32.ll (+12-12)
  • (modified) llvm/test/CodeGen/PowerPC/cvt_i64_to_fp.ll (+3-3)
  • (modified) llvm/test/CodeGen/PowerPC/inc-of-add.ll (+1-1)
  • (modified) llvm/test/CodeGen/PowerPC/pr35688.ll (+1-1)
  • (modified) llvm/test/CodeGen/PowerPC/pr36292.ll (+4-3)
  • (modified) llvm/test/CodeGen/PowerPC/pr40922.ll (+4-5)
  • (modified) llvm/test/CodeGen/PowerPC/pr45448.ll (+7-5)
  • (modified) llvm/test/CodeGen/PowerPC/sat-add.ll (+20-15)
  • (modified) llvm/test/CodeGen/PowerPC/select.ll (+12-8)
  • (modified) llvm/test/CodeGen/PowerPC/umulo-128-legalisation-lowering.ll (+108-111)
  • (modified) llvm/test/CodeGen/PowerPC/urem-seteq-illegal-types.ll (+11-12)
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index ab31898e262e7e..88a255fae2d62c 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -254,13 +254,15 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
     setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
   }
 
-  // PowerPC uses ADDC/ADDE/SUBC/SUBE to propagate carry.
+  // PowerPC uses addo,addo_carry,subo,subo_carry to propagate carry.
   const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
   for (MVT VT : ScalarIntVTs) {
-    setOperationAction(ISD::ADDC, VT, Legal);
-    setOperationAction(ISD::ADDE, VT, Legal);
-    setOperationAction(ISD::SUBC, VT, Legal);
-    setOperationAction(ISD::SUBE, VT, Legal);
+    if ((VT == MVT::i64) != isPPC64)
+      continue;
+    setOperationAction(ISD::UADDO, VT, Custom);
+    setOperationAction(ISD::USUBO, VT, Custom);
+    setOperationAction(ISD::UADDO_CARRY, VT, Custom);
+    setOperationAction(ISD::USUBO_CARRY, VT, Custom);
   }
 
   if (Subtarget.useCRBits()) {
@@ -1853,6 +1855,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
   case PPCISD::LXVRZX:          return "PPCISD::LXVRZX";
   case PPCISD::STORE_COND:
     return "PPCISD::STORE_COND";
+  case PPCISD::ADDC:
+    return "PPCISD::ADDC";
+  case PPCISD::ADDE:
+    return "PPCISD::ADDE";
+  case PPCISD::SUBC:
+    return "PPCISD::SUBC";
+  case PPCISD::SUBE:
+    return "PPCISD::SUBE";
   }
   return nullptr;
 }
@@ -12016,6 +12026,75 @@ SDValue PPCTargetLowering::LowerUaddo(SDValue Op, SelectionDAG &DAG) const {
   return Res;
 }
 
+static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
+                                            SelectionDAG &DAG,
+                                            const PPCSubtarget &STI) {
+  SDLoc DL(Value);
+  if (STI.useCRBits())
+    Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
+                        DAG.getConstant(1, DL, SumType),
+                        DAG.getConstant(0, DL, SumType));
+  else
+    Value = DAG.getZExtOrTrunc(Value, DL, SumType);
+  SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
+                            Value, DAG.getAllOnesConstant(DL, SumType));
+  return Sum.getValue(1);
+}
+
+static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
+                                            EVT CarryType, SelectionDAG &DAG,
+                                            const PPCSubtarget &STI) {
+  SDLoc DL(Flag);
+  SDValue Zero = DAG.getConstant(0, DL, SumType);
+  SDValue Carry = DAG.getNode(
+      PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
+  if (STI.useCRBits())
+    return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
+  return DAG.getZExtOrTrunc(Carry, DL, CarryType);
+}
+
+SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
+  SDLoc DL(Op);
+  SDNode *N = Op.getNode();
+  EVT VT = N->getValueType(0);
+  EVT CarryType = N->getValueType(1);
+  unsigned Opc = N->getOpcode();
+  bool IsAdd = Opc == ISD::UADDO;
+  Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
+  SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
+                            N->getOperand(0), N->getOperand(1));
+  SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
+                                               DAG, Subtarget);
+  if (!IsAdd)
+    Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
+                        DAG.getAllOnesConstant(DL, CarryType));
+  return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
+}
+
+SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
+                                              SelectionDAG &DAG) const {
+  SDLoc DL(Op);
+  SDNode *N = Op.getNode();
+  unsigned Opc = N->getOpcode();
+  EVT VT = N->getValueType(0);
+  EVT CarryType = N->getValueType(1);
+  SDValue CarryOp = N->getOperand(2);
+  bool IsAdd = Opc == ISD::UADDO_CARRY;
+  Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
+  if (!IsAdd)
+    CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
+                          DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
+  CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
+  SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
+                            Op.getOperand(0), Op.getOperand(1), CarryOp);
+  CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
+                                         Subtarget);
+  if (!IsAdd)
+    CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
+                          DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
+  return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
+}
+
 /// LowerOperation - Provide custom lowering hooks for some operations.
 ///
 SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
@@ -12112,6 +12191,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
     return LowerATOMIC_LOAD_STORE(Op, DAG);
   case ISD::IS_FPCLASS:
     return LowerIS_FPCLASS(Op, DAG);
+  case ISD::UADDO:
+  case ISD::USUBO:
+    return LowerADDSUBO(Op, DAG);
+  case ISD::UADDO_CARRY:
+  case ISD::USUBO_CARRY:
+    return LowerADDSUBO_CARRY(Op, DAG);
   }
 }
 
@@ -16005,6 +16090,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
   return true;
 }
 
+static SDValue DAGCombineAddc(SDNode *N,
+                              llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
+  if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
+    // (ADDC (ADDE 0, 0, C), -1) -> C
+    SDValue LHS = N->getOperand(0);
+    SDValue RHS = N->getOperand(1);
+    if (LHS->getOpcode() == PPCISD::ADDE &&
+        isNullConstant(LHS->getOperand(0)) &&
+        isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
+      return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
+    }
+  }
+  return SDValue();
+}
+
 SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
                                              DAGCombinerInfo &DCI) const {
   SelectionDAG &DAG = DCI.DAG;
@@ -16794,6 +16894,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
   }
   case ISD::BUILD_VECTOR:
     return DAGCombineBuildVector(N, DCI);
+  case PPCISD::ADDC:
+    return DAGCombineAddc(N, DCI);
   }
 
   return SDValue();
@@ -16847,6 +16949,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
       Known.Zero = 0xFFFF0000;
     break;
   }
+  case PPCISD::ADDE: {
+    if (Op.getResNo() == 0) {
+      // (0|1), _ = ADDE 0, 0, CARRY
+      SDValue LHS = Op.getOperand(0);
+      SDValue RHS = Op.getOperand(1);
+      if (isNullConstant(LHS) && isNullConstant(RHS))
+        Known.Zero = ~1ULL;
+    }
+    break;
+  }
   case ISD::INTRINSIC_WO_CHAIN: {
     switch (Op.getConstantOperandVal(0)) {
     default: break;
@@ -18117,7 +18229,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
     return SDValue();
 
   SDLoc DL(N);
-  SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
+  EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
+  SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
   SDValue Cmp = RHS.getOperand(0);
   SDValue Z = Cmp.getOperand(0);
   auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18135,11 +18248,13 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
     SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
                               DAG.getConstant(NegConstant, DL, MVT::i64));
     SDValue AddOrZ = NegConstant != 0 ? Add : Z;
-    SDValue Addc = DAG.getNode(ISD::ADDC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
-                               AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
-    return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
+    SDValue Addc =
+        DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
+                    DAG.getConstant(-1ULL, DL, MVT::i64));
+    return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
+                       DAG.getConstant(0, DL, MVT::i64),
                        SDValue(Addc.getNode(), 1));
-    }
+  }
   case ISD::SETEQ: {
     //                                 when C == 0
     //                             --> addze X, (subfic Z, 0).carry
@@ -18150,11 +18265,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
     SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
                               DAG.getConstant(NegConstant, DL, MVT::i64));
     SDValue AddOrZ = NegConstant != 0 ? Add : Z;
-    SDValue Subc = DAG.getNode(ISD::SUBC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
-                               DAG.getConstant(0, DL, MVT::i64), AddOrZ);
-    return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
-                       SDValue(Subc.getNode(), 1));
-    }
+    SDValue Subc =
+        DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
+                    DAG.getConstant(0, DL, MVT::i64), AddOrZ);
+    SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
+                                 DAG.getAllOnesConstant(DL, CarryType));
+    return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
+                       DAG.getConstant(0, DL, MVT::i64), Invert);
+  }
   }
 
   return SDValue();
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 0adbad86845973..476e1a1763cc17 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -164,6 +164,12 @@ namespace llvm {
     SRA,
     SHL,
 
+    /// These nodes represent PPC arithmetic operations with carry.
+    ADDC,
+    ADDE,
+    SUBC,
+    SUBE,
+
     /// FNMSUB - Negated multiply-subtract instruction.
     FNMSUB,
 
@@ -1312,6 +1318,8 @@ namespace llvm {
     SDValue LowerBSWAP(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;
     SDValue LowerIS_FPCLASS(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG) const;
+    SDValue LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const;
     SDValue lowerToLibCall(const char *LibCallName, SDValue Op,
                            SelectionDAG &DAG) const;
     SDValue lowerLibCallBasedOnType(const char *LibCallFloatName,
diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index 68419068e52a64..f778f39419b71a 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -760,13 +760,13 @@ def STFDXTLS : XForm_8<31, 727, (outs), (ins f8rc:$RST, ptr_rc_nor0:$RA, tlsreg:
 let isCommutable = 1 in
 defm ADDC8 : XOForm_1rc<31, 10, 0, (outs g8rc:$RT), (ins g8rc:$RA, g8rc:$RB),
                         "addc", "$RT, $RA, $RB", IIC_IntGeneral,
-                        [(set i64:$RT, (addc i64:$RA, i64:$RB))]>,
+                        [(set i64:$RT, (PPCaddc i64:$RA, i64:$RB))]>,
                         PPC970_DGroup_Cracked;
 
 let Defs = [CARRY] in
 def ADDIC8 : DForm_2<12, (outs g8rc:$RST), (ins g8rc:$RA, s16imm64:$D),
                      "addic $RST, $RA, $D", IIC_IntGeneral,
-                     [(set i64:$RST, (addc i64:$RA, imm64SExt16:$D))]>;
+                     [(set i64:$RST, (PPCaddc i64:$RA, imm64SExt16:$D))]>;
 def ADDI8  : DForm_2<14, (outs g8rc:$RST), (ins g8rc_nox0:$RA, s16imm64:$D),
                      "addi $RST, $RA, $D", IIC_IntSimple,
                      [(set i64:$RST, (add i64:$RA, imm64SExt16:$D))]>;
@@ -782,11 +782,11 @@ def LA8     : DForm_2<14, (outs g8rc:$RST), (ins g8rc_nox0:$RA, s16imm64:$D),
 let Defs = [CARRY] in {
 def SUBFIC8: DForm_2< 8, (outs g8rc:$RST), (ins g8rc:$RA, s16imm64:$D),
                      "subfic $RST, $RA, $D", IIC_IntGeneral,
-                     [(set i64:$RST, (subc imm64SExt16:$D, i64:$RA))]>;
+                     [(set i64:$RST, (PPCsubc imm64SExt16:$D, i64:$RA))]>;
 }
 defm SUBFC8 : XOForm_1rc<31, 8, 0, (outs g8rc:$RT), (ins g8rc:$RA, g8rc:$RB),
                         "subfc", "$RT, $RA, $RB", IIC_IntGeneral,
-                        [(set i64:$RT, (subc i64:$RB, i64:$RA))]>,
+                        [(set i64:$RT, (PPCsubc i64:$RB, i64:$RA))]>,
                         PPC970_DGroup_Cracked;
 defm SUBF8 : XOForm_1rx<31, 40, (outs g8rc:$RT), (ins g8rc:$RA, g8rc:$RB),
                         "subf", "$RT, $RA, $RB", IIC_IntGeneral,
@@ -798,22 +798,22 @@ let Uses = [CARRY] in {
 let isCommutable = 1 in
 defm ADDE8   : XOForm_1rc<31, 138, 0, (outs g8rc:$RT), (ins g8rc:$RA, g8rc:$RB),
                           "adde", "$RT, $RA, $RB", IIC_IntGeneral,
-                          [(set i64:$RT, (adde i64:$RA, i64:$RB))]>;
+                          [(set i64:$RT, (PPCadde i64:$RA, i64:$RB, CARRY))]>;
 defm ADDME8  : XOForm_3rc<31, 234, 0, (outs g8rc:$RT), (ins g8rc:$RA),
                           "addme", "$RT, $RA", IIC_IntGeneral,
-                          [(set i64:$RT, (adde i64:$RA, -1))]>;
+                          [(set i64:$RT, (PPCadde i64:$RA, -1, CARRY))]>;
 defm ADDZE8  : XOForm_3rc<31, 202, 0, (outs g8rc:$RT), (ins g8rc:$RA),
                           "addze", "$RT, $RA", IIC_IntGeneral,
-                          [(set i64:$RT, (adde i64:$RA, 0))]>;
+                          [(set i64:$RT, (PPCadde i64:$RA, 0, CARRY))]>;
 defm SUBFE8  : XOForm_1rc<31, 136, 0, (outs g8rc:$RT), (ins g8rc:$RA, g8rc:$RB),
                           "subfe", "$RT, $RA, $RB", IIC_IntGeneral,
-                          [(set i64:$RT, (sube i64:$RB, i64:$RA))]>;
+                          [(set i64:$RT, (PPCsube i64:$RB, i64:$RA, CARRY))]>;
 defm SUBFME8 : XOForm_3rc<31, 232, 0, (outs g8rc:$RT), (ins g8rc:$RA),
                           "subfme", "$RT, $RA", IIC_IntGeneral,
-                          [(set i64:$RT, (sube -1, i64:$RA))]>;
+                          [(set i64:$RT, (PPCsube -1, i64:$RA, CARRY))]>;
 defm SUBFZE8 : XOForm_3rc<31, 200, 0, (outs g8rc:$RT), (ins g8rc:$RA),
                           "subfze", "$RT, $RA", IIC_IntGeneral,
-                          [(set i64:$RT, (sube 0, i64:$RA))]>;
+                          [(set i64:$RT, (PPCsube 0, i64:$RA, CARRY))]>;
 }
 } // isCodeGenOnly
 
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
index 3c331cee8f7648..a7e34e234a077d 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
@@ -1761,6 +1761,23 @@ void PPCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
     BuildMI(MBB, I, DL, get(PPC::EFDCFS), DestReg).addReg(SrcReg);
     getKillRegState(KillSrc);
     return;
+  } else if ((PPC::G8RCRegClass.contains(DestReg) ||
+              PPC::GPRCRegClass.contains(DestReg)) &&
+             SrcReg == PPC::CARRY) {
+    bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);
+    BuildMI(MBB, I, DL, get(Is64Bit ? PPC::MFSPR8 : PPC::MFSPR), DestReg)
+        .addImm(1)
+        .addReg(PPC::CARRY, RegState::Implicit);
+    return;
+  } else if ((PPC::G8RCRegClass.contains(SrcReg) ||
+              PPC::GPRCRegClass.contains(SrcReg)) &&
+             DestReg == PPC::CARRY) {
+    bool Is64Bit = PPC::G8RCRegClass.contains(SrcReg);
+    BuildMI(MBB, I, DL, get(Is64Bit ? PPC::MTSPR8 : PPC::MTSPR))
+        .addImm(1)
+        .addReg(SrcReg)
+        .addReg(PPC::CARRY, RegState::ImplicitDefine);
+    return;
   }
 
   unsigned Opc;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index b4a5e41c0107a3..f10be4dbeab35f 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -124,6 +124,21 @@ def SDT_PPCFPMinMax : SDTypeProfile<1, 2, [
   SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>, SDTCisFP<0>
 ]>;
 
+// RES, CARRY = op LHS, RHS
+def SDT_PPCBinaryArithWithFlagsOut : SDTypeProfile<2, 2, [
+  SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>,
+  SDTCisInt<0>,
+  SDTCisVT<1, i32>,
+]>;
+
+// RES, CARRY = op LHS, RHS, CARRY
+def SDT_PPCBinaryArithWithFlagsInOut : SDTypeProfile<2, 3, [
+  SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>,
+  SDTCisInt<0>,
+  SDTCisSameAs<1, 4>,
+  SDTCisVT<1, i32>,
+]>;
+
 //===----------------------------------------------------------------------===//
 // PowerPC specific DAG Nodes.
 //
@@ -401,6 +416,15 @@ def PPCtlsdynamatpcreladdr : SDNode<"PPCISD::TLS_DYNAMIC_MAT_PCREL_ADDR",
 def PPCtlslocalexecmataddr : SDNode<"PPCISD::TLS_LOCAL_EXEC_MAT_ADDR",
                                     SDTIntUnaryOp, []>;
 
+def PPCaddc : SDNode<"PPCISD::ADDC", SDT_PPCBinaryArithWithFlagsOut,
+                     [SDNPCommutative]>;
+def PPCadde : SDNode<"PPCISD::ADDE", SDT_PPCBinaryArithWithFlagsInOut,
+                     []>;
+def PPCsubc : SDNode<"PPCISD::SUBC", SDT_PPCBinaryArithWithFlagsOut,
+                     []>;
+def PPCsube : SDNode<"PPCISD::SUBE", SDT_PPCBinaryArithWithFlagsInOut,
+                     []>;
+
 //===----------------------------------------------------------------------===//
 // PowerPC specific transformation functions and pattern fragments.
 //
@@ -2289,7 +2313,7 @@ let BaseName = "addic" in {
 let Defs = [CARRY] in
 def ADDIC  : DForm_2<12, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
                      "addic $RST, $RA, $D", IIC_IntGeneral,
-                     [(set i32:$RST, (addc i32:$RA, imm32SExt16:$D))]>,
+                     [(set i32:$RST, (PPCaddc i32:$RA, imm32SExt16:$D))]>,
                      RecFormRel, PPC970_DGroup_Cracked;
 let Defs = [CARRY, CR0] in
 def ADDIC_rec : DForm_2<13, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
@@ -2310,7 +2334,7 @@ def MULLI  : DForm_2< 7, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
 let Defs = [CARRY] in
 def SUBFIC : DForm_2< 8, (outs gprc:$RST), (ins gprc:$RA, s16imm:$D),
                      "subfic $RST, $RA, $D", IIC_IntGeneral,
-                     [(set i32:$RST, (subc imm32SExt16:$D, i32:$RA))]>;
+                     [(set i32:$RST, (PPCsubc imm32SExt16:$D, i32:$RA))]>;
 
 let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
   def LI  : DForm_2_r0<14, (outs gprc:$RST), (ins s16imm:$D),
@@ -2907,7 +2931,7 @@ def ADD4TLS  : XOForm_1<31, 266, 0, (outs gprc:$RT), (ins gprc:$RA, tlsreg32:$RB
 let isCommutable = 1 in
 defm ADDC  : XOForm_1rc<31, 10, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
                         "addc", "$RT, $RA, $RB", IIC_IntGeneral,
-                        [(set i32:$RT, (addc i32:$RA, i32:$RB))]>,
+                        [(set i32:$RT, (PPCaddc i32:$RA, i32:$RB))]>,
                         PPC970_DGroup_Cracked;
 
 defm DIVW  : XOForm_1rcr<31, 491, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
@@ -2940,7 +2964,7 @@ defm SUBF  : XOForm_1rx<31, 40, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
                         [(set i32:$RT, (sub i32:$RB, i32:$RA))]>;
 defm SUBFC : XOForm_1rc<31, 8, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
                         "subfc", "$RT, $RA, $RB", IIC_IntGeneral,
-                        [(set i32:$RT, (subc i32:$RB, i32:$RA))]>,
+                        [(set i32:$RT, (PPCsubc i32:$RB, i32:$RA))]>,
                         PPC970_DGroup_Cracked;
 defm NEG    : XOForm_3r<31, 104, 0, (outs gprc:$RT), (ins gprc:$RA),
                         "neg", "$RT, $RA", IIC_IntSimple,
@@ -2949,22 +2973,22 @@ let Uses = [CARRY] in {
 let isCommutable = 1 in
 defm ADDE  : XOForm_1rc<31, 138, 0, (outs gprc:$RT), (ins gprc:$RA, gprc:$RB),
                         "adde", "$RT, $RA, $RB", IIC_IntGeneral,
-                        [(set i32:$RT, (adde i32:$RA, i32:$RB))]>;
+                        [(set i32:$RT, (PPCadde i32:$RA, i32:$RB, CARRY))]>;
 defm ADDME  : XOForm_3rc<31, 234, 0, (outs gprc:$RT), (ins gprc:$RA),
                          "addme", "$RT, $RA", IIC_IntGeneral,
-                         [(set i32:$RT, (adde i32:$RA, -1))]>;
+                         [(set i32:$RT, (PPCadde i32:$RA, -1, CARRY))]>;
 defm ADDZE  : XOForm_3rc<31, 202, 0, (outs gprc:$RT), (ins gprc:$RA),
                          "addze", "$RT, $RA", IIC_IntGeneral,
-                         [(set i32:$RT, (adde i32:$RA, 0))]>;
+                         [(set i32:$RT, (PPCadde i32:$RA, 0, CARRY))]>;
 defm SUBFE : XOForm_1rc<31, 136, 0, (outs gprc:$...
[truncated]

@bzEq
Copy link
Collaborator

bzEq commented Dec 3, 2024

Thanks for taking over this. I do have seen some regression in some tests which I don't have good way to fix, but I think they should be investigated further and get fixed.

@diggerlin diggerlin closed this Dec 10, 2024
@diggerlin diggerlin force-pushed the digger/use-carry-arith branch from f6bf4ab to 24162bd Compare December 10, 2024 21:20
@diggerlin diggerlin reopened this Dec 10, 2024
Copy link

github-actions bot commented Dec 10, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@diggerlin diggerlin force-pushed the digger/use-carry-arith branch from 7559062 to 64fb6c1 Compare January 13, 2025 20:21
@diggerlin
Copy link
Contributor Author

rebased the code to the latest code and fixed merge conflict.

setOperationAction(ISD::UADDO, RegVT, Custom);
setOperationAction(ISD::USUBO, RegVT, Custom);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to include/llvm/CodeGen/ISDOpcodes.h, UADDO_CARRY/USUBO_CARRY replace the ADDC/SUBC (UADDO/USUBO dont replace ADDC/SUBC). ADDC/SUBC are deprecated in favor of UADDO_CARRY and USUBO_CARRY.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, UADDO and USUBO are lowered by the function SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) which use PPCISD::ADDC/ PPCISD::SUBC instead of ISD::ADDC/ISD::SUBC since the ISD::ADDC/ISD::ADDE/ISD::SUBC/ISD::SUBE is deprecated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why using PPCISD::ADDC/ PPCISD::SUBC to lower UADDO/USUBO, instead of using the replacement nodes; ISD::UADDO_CARRY/USUBO_CARRY? (these new nodes are themselves lowered using PPCISD::ADDC/ PPCISD::SUBC)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, there is no uaddo_carry operator defined for pattern matching in order to select proper instruction. Correct me if I am wrong.

@@ -12028,43 +12031,74 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
llvm_unreachable("ERROR:Should return for all cases within swtich.");
}

SDValue PPCTargetLowering::LowerUaddo(SDValue Op, SelectionDAG &DAG) const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The custom lowering for uaddo is recently added by this commit , as uaddo produces overflow not carry-bit.

Copy link
Contributor Author

@diggerlin diggerlin Jan 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the commit , it still use ISD::ADDC/ISD::ADDE to lower the UADDO, since the ISD::ADDC/ISD::ADDE is deprecated we need to replac the commit in the implement of LowerADDSUBO which using PPCISD::ADDC and PPCISD::ADDE

AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
SDValue Addc =
DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same thing, ISD::UADDO does not replace ISD::ADDC.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ISD::UADDO --> ISD::UADDO_CARRY ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the third arg of ISD::UADDC_CARRY is zero here ,
I think it is OK to use the ISD::UADDO or ISD::UADDC_CARRY here. no matter using the second result of ISD::UADDO or ISD::UADDO as input of third arg of ISD::UADDO_CARRY

line 18326: return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,DAG.getConstant(0, DL, MVT::i64), SDValue(Addc.getNode(), 1));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From ISD reference,
UADDO_CARRY: These opcodes are different from [US]{ADD,SUB}O in that U{ADD,SUB}O_CARRY consume and produce a carry/borrow, whereas [US]{ADD,SUB}O produce an overflow.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The semantics of UADDO is not well defined IMO, since there should not be overflow when talking about unsigned arithmetic.

@@ -196,7 +196,11 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
}
}

// PowerPC uses addo,addo_carry,subo,subo_carry to propagate carry.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uaddo/usubo do not propagate carry bit.

SDValue(Subc.getNode(), 1));
}
SDValue Subc =
DAG.getNode(ISD::USUBO, DL, DAG.getVTList(MVT::i64, CarryType),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ISD::USUBO --> ISD::USUBO_CARRY ?

AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64));
return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
SDValue Addc =
DAG.getNode(ISD::UADDO, DL, DAG.getVTList(MVT::i64, CarryType), AddOrZ,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ISD::UADDO --> ISD::UADDO_CARRY ?

@diggerlin diggerlin requested a review from maryammo January 16, 2025 14:47
Copy link
Contributor

@maryammo maryammo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@diggerlin diggerlin force-pushed the digger/use-carry-arith branch from 15db1f6 to 43a3d1b Compare February 12, 2025 14:18
@diggerlin diggerlin merged commit 7763119 into llvm:main Feb 13, 2025
8 checks passed
joaosaffran pushed a commit to joaosaffran/llvm-project that referenced this pull request Feb 14, 2025
…lvm#116984)

ISD::ADDC, ISD::ADDE, ISD::SUBC and ISD::SUBE are being deprecated,
using ISD::UADDO_CARRY,ISD::USUBO_CARRY instead. Lowering the UADDO,
UADDO_CARRY, USUBO, USUBO_CARRY in the patch.
@nathanchance
Copy link
Member

This causes a crash while building the Linux kernel for 32-bit powerpc. For example:

$ make -skj"$(nproc)" ARCH=powerpc CROSS_COMPILE=powerpc-linux-gnu- LLVM=1 LLVM_IAS=0 mrproper pmac32_defconfig drivers/md/md.o
...
*** Bad machine code: Using an undefined physical register ***
- function:    md_seq_show
- basic block: %bb.101 land.lhs.true111.i (0x561040cce110)
- instruction: dead %438:gprc = ADDZE_rec %431:gprc, implicit-def dead $carry, implicit $carry, implicit-def $cr0
- operand 3:   implicit $carry
fatal error: error in backend: Found 1 machine code errors.
clang: error: clang frontend command failed with exit code 70 (use -v to see invocation)
...

cvise spits out:

struct {
  long long recovery_offset;
} *status_resync_rdev;
_Bool md_seq_show___trans_tmp_57;
int md_seq_show___trans_tmp_13;
int status_resync() {
  for (;;)
    if (status_resync_rdev->recovery_offset != ~00 &&
        status_resync_rdev->recovery_offset)
      return 1;
}
int md_seq_show() {
  status_resync();
  md_seq_show___trans_tmp_57 = md_seq_show___trans_tmp_13;
  return 0;
}

and from that, llvm-reduce spits outs:

target datalayout = "E-m:e-p:32:32-Fn32-i64:64-n32"
target triple = "powerpc-unknown-linux-gnu"

@md_seq_show___trans_tmp_57 = external global i8

define i32 @md_seq_show(i64 %0, i32 %1) #0 {
entry:
  switch i64 %0, label %status_resync.exit [
    i64 -1, label %for.cond.i.preheader
    i64 0, label %for.cond.i.preheader
  ]

for.cond.i.preheader:                             ; preds = %entry, %entry
  ret i32 0

status_resync.exit:                               ; preds = %entry
  %tobool = icmp ne i32 %1, 0
  %storedv = zext i1 %tobool to i8
  store i8 %storedv, ptr @md_seq_show___trans_tmp_57, align 1
  ret i32 0
}

attributes #0 = { "target-features"="-aix-shared-lib-tls-model-opt,-aix-small-local-dynamic-tls,-aix-small-local-exec-tls,-altivec,-bpermd,-crbits,-crypto,-direct-move,-extdiv,-htm,-isa-v206-instructions,-isa-v207-instructions,-isa-v30-instructions,-power8-vector,-power9-vector,-privileged,-quadword-atomics,-rop-protect,-spe,-vsx" }
$ llc -o /dev/null reduced.ll

# Machine code for function md_seq_show: NoPHIs, TracksLiveness, TiedOpsRewritten
Function Live Ins: $r3 in %0, $r4 in %1, $r5 in %2

bb.0.entry:
  successors: %bb.1(0x40000000), %bb.2(0x40000000); %bb.1(50.00%), %bb.2(50.00%)
  liveins: $r3, $r4, $r5
  %2:gprc = COPY $r5
  %1:gprc = COPY $r4
  %0:gprc = COPY $r3
  %5:gprc = ADDIC %1:gprc, 1, implicit-def dead $carry
  %6:crrc = CMPLWI %5:gprc, 1
  %22:gprc_and_gprc_nor0 = LI 1
  BCC 44, %6:crrc, %bb.2

bb.1.entry:
; predecessors: %bb.0
  successors: %bb.2(0x80000000); %bb.2(100.00%)

  %22:gprc_and_gprc_nor0 = LI 0

bb.2.entry:
; predecessors: %bb.0, %bb.1
  successors: %bb.3(0x40000000), %bb.4(0x40000000); %bb.3(50.00%), %bb.4(50.00%)

  %10:gprc = ADDZE_rec %0:gprc, implicit-def dead $carry, implicit $carry, implicit-def $cr0
  %13:crrc = COPY killed $cr0
  %11:gprc = ADDIC %10:gprc, -1, implicit-def $carry
  %12:gprc_and_gprc_nor0 = SUBFE %11:gprc, %10:gprc, implicit-def dead $carry, implicit killed $carry
  BCC 76, %13:crrc, %bb.4

bb.3.entry:
; predecessors: %bb.2
  successors: %bb.4(0x80000000); %bb.4(100.00%)

  %22:gprc_and_gprc_nor0 = COPY %12:gprc_and_gprc_nor0

bb.4.entry:
; predecessors: %bb.2, %bb.3
  successors: %bb.5(0x55555556), %bb.6(0x2aaaaaaa); %bb.5(66.67%), %bb.6(33.33%)

  %15:crrc = CMPLWI %22:gprc_and_gprc_nor0, 0
  BCC 68, %15:crrc, %bb.6
  B %bb.5

bb.5.for.cond.i.preheader:
; predecessors: %bb.4

  $r3 = LI 0
  BLR implicit $lr, implicit $rm, implicit $r3

bb.6.status_resync.exit:
; predecessors: %bb.4

  %17:gprc = ADDIC %2:gprc, -1, implicit-def $carry
  %19:gprc_and_gprc_nor0 = LIS target-flags(ppc-ha) @md_seq_show___trans_tmp_57
  %18:gprc = SUBFE %17:gprc, %2:gprc, implicit-def dead $carry, implicit killed $carry
  $r3 = LI 0
  STB %18:gprc, target-flags(ppc-lo) @md_seq_show___trans_tmp_57, %19:gprc_and_gprc_nor0 :: (store (s8) into @md_seq_show___trans_tmp_57)
  BLR implicit $lr, implicit $rm, implicit $r3

# End machine code for function md_seq_show.

*** Bad machine code: Using an undefined physical register ***
- function:    md_seq_show
- basic block: %bb.2 entry (0x55d10cfa37f0)
- instruction: %10:gprc = ADDZE_rec %0:gprc, implicit-def dead $carry, implicit $carry, implicit-def $cr0
- operand 3:   implicit $carry
LLVM ERROR: Found 1 machine code errors.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: llc -o /dev/null reduced.ll
1.	Running pass 'Function Pass Manager' on module 'reduced.ll'.
2.	Running pass 'Machine Instruction Scheduler' on function '@md_seq_show'
 #0 0x000055d10ab77c76 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x5930c76)
 #1 0x000055d10ab7558e llvm::sys::RunSignalHandlers() (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x592e58e)
 #2 0x000055d10ab78354 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #3 0x00007f146a44bcd0 (/usr/lib/libc.so.6+0x3dcd0)
 #4 0x00007f146a4a5624 (/usr/lib/libc.so.6+0x97624)
 #5 0x00007f146a44bba0 raise (/usr/lib/libc.so.6+0x3dba0)
 #6 0x00007f146a433582 abort (/usr/lib/libc.so.6+0x25582)
 #7 0x000055d10aadc5d4 llvm::report_fatal_error(llvm::Twine const&, bool) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x58955d4)
 #8 0x000055d109c6149c (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x4a1a49c)
 #9 0x000055d109c61bed llvm::MachineFunction::verify(llvm::Pass*, char const*, llvm::raw_ostream*, bool) const (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x4a1abed)
#10 0x000055d109a71974 llvm::LiveRangeCalc::findReachingDefs(llvm::LiveRange&, llvm::MachineBasicBlock&, llvm::SlotIndex, unsigned int, llvm::ArrayRef<llvm::SlotIndex>) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x482a974)
#11 0x000055d109a70bd7 llvm::LiveRangeCalc::extend(llvm::LiveRange&, llvm::SlotIndex, unsigned int, llvm::ArrayRef<llvm::SlotIndex>) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x4829bd7)
#12 0x000055d109a7475a llvm::LiveIntervalCalc::extendToUses(llvm::LiveRange&, llvm::Register, llvm::LaneBitmask, llvm::LiveInterval*) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x482d75a)
#13 0x000055d109a5c4c3 llvm::LiveIntervals::computeRegUnitRange(llvm::LiveRange&, unsigned int) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x48154c3)
#14 0x000055d109a6024b llvm::LiveIntervals::HMEditor::updateAllRanges(llvm::MachineInstr*) LiveIntervals.cpp:0:0
#15 0x000055d109a5fe22 llvm::LiveIntervals::handleMove(llvm::MachineInstr&, bool) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x4818e22)
#16 0x000055d109c0155f llvm::ScheduleDAGMI::moveInstruction(llvm::MachineInstr*, llvm::MachineInstrBundleIterator<llvm::MachineInstr, false>) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x49ba55f)
#17 0x000055d109c08be2 llvm::ScheduleDAGMILive::scheduleMI(llvm::SUnit*, bool) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x49c1be2)
#18 0x000055d109c08262 llvm::ScheduleDAGMILive::schedule() (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x49c1262)
#19 0x000055d109bffa39 llvm::impl_detail::MachineSchedulerBase::scheduleRegions(llvm::ScheduleDAGInstrs&, bool) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x49b8a39)
#20 0x000055d109bff3fa llvm::impl_detail::MachineSchedulerImpl::run(llvm::MachineFunction&, llvm::TargetMachine const&, llvm::impl_detail::MachineSchedulerImpl::RequiredAnalyses const&) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x49b83fa)
#21 0x000055d109c151f3 (anonymous namespace)::MachineSchedulerLegacy::runOnMachineFunction(llvm::MachineFunction&) MachineScheduler.cpp:0:0
#22 0x000055d109b332f3 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x48ec2f3)
#23 0x000055d10a0aba49 llvm::FPPassManager::runOnFunction(llvm::Function&) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x4e64a49)
#24 0x000055d10a0b4332 llvm::FPPassManager::runOnModule(llvm::Module&) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x4e6d332)
#25 0x000055d10a0ac4f2 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x4e654f2)
#26 0x000055d10837b75d compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#27 0x000055d108378eb0 main (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x3131eb0)
#28 0x00007f146a435488 (/usr/lib/libc.so.6+0x27488)
#29 0x00007f146a43554c __libc_start_main (/usr/lib/libc.so.6+0x2754c)
#30 0x000055d108374ce5 _start (/mnt/nvme/tmp/cvise.DtPcjCvPux/install/llvm-7763119c6eb0976e4836f81c9876c49a36d46d73/bin/llc+0x312dce5)

If there is any other information I can provide, please let me know.

@daltenty
Copy link
Member

This is also breaking test-suite on AIX. I'm getting different numerical results in, for example:

test-suite :: MultiSource/Benchmarks/Prolangs-C/allroots/allroots.test

daltenty added a commit that referenced this pull request Feb 19, 2025
…::SUBE (#116984)"

This reverts commit 7763119 (leaving the modifications from 03cb46d)..
@bzEq
Copy link
Collaborator

bzEq commented Feb 19, 2025

A potential fix for it

diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 4720928f472b..f9159417e2a6 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -12059,7 +12059,7 @@ SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
                                                DAG, Subtarget);
   if (!IsAdd)
     Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
-                        DAG.getAllOnesConstant(DL, CarryType));
+                        DAG.getConstant(1UL, DL, CarryType));
   return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
 }
 
@@ -12075,7 +12075,7 @@ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
   Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
   if (!IsAdd)
     CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
-                          DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
+                          DAG.getConstant(1UL, DL, CarryOp.getValueType()));
   CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
   SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
                             Op.getOperand(0), Op.getOperand(1), CarryOp);
@@ -12083,7 +12083,7 @@ SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
                                          Subtarget);
   if (!IsAdd)
     CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
-                          DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
+                          DAG.getConstant(1UL, DL, CarryOp.getValueType()));
   return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
 }
 
@@ -18329,7 +18329,7 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
                     DAG.getConstant(0, DL, MVT::i64), AddOrZ,
                     DAG.getConstant(0, DL, CarryType));
     SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
-                                 DAG.getAllOnesConstant(DL, CarryType));
+                                 DAG.getConstant(1UL, DL, CarryType));
     return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
                        DAG.getConstant(0, DL, MVT::i64), Invert);
   }

in addition to #127376.
Reduced IR

target datalayout = "E-m:e-Fi64-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512"
target triple = "powerpc64-unknown-linux-gnu"

define fastcc void @mab_mas_cp(i64 %0, i64 %1) #0 {
  br label %3

3:                                                ; preds = %6, %2
  %4 = phi i64 [ %7, %6 ], [ %0, %2 ]
  %5 = icmp ult i64 %4, %1
  br i1 %5, label %6, label %8

6:                                                ; preds = %3
  %7 = add i64 %4, 1
  br label %3

8:                                                ; preds = %3
  ret void
}

attributes #0 = { "target-features"="-aix-shared-lib-tls-model-opt,-aix-small-local-dynamic-tls,-aix-small-local-exec-tls,-altivec,-bpermd,-crbits,-crypto,-direct-move,-efpu2,-extdiv,-float128,-hard-float,-htm,-isa-v206-instructions,-isa-v207-instructions,-isa-v30-instructions,-mma,-paired-vector-memops,-pcrelative-memops,-power10-vector,-power8-vector,-power9-vector,-prefix-instrs,-privileged,-quadword-atomics,-rop-protect,-spe,-vsx" }

sivan-shani pushed a commit to sivan-shani/llvm-project that referenced this pull request Feb 24, 2025
…lvm#116984)

ISD::ADDC, ISD::ADDE, ISD::SUBC and ISD::SUBE are being deprecated,
using ISD::UADDO_CARRY,ISD::USUBO_CARRY instead. Lowering the UADDO,
UADDO_CARRY, USUBO, USUBO_CARRY in the patch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants