-
Notifications
You must be signed in to change notification settings - Fork 13.9k
[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
Conversation
@llvm/pr-subscribers-backend-powerpc Author: zhijian lin (diggerlin) ChangesPatch is 63.53 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/116984.diff 26 Files Affected:
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]
|
b142d72
to
f6bf4ab
Compare
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. |
f6bf4ab
to
24162bd
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
7559062
to
64fb6c1
Compare
rebased the code to the latest code and fixed merge conflict. |
setOperationAction(ISD::UADDO, RegVT, Custom); | ||
setOperationAction(ISD::USUBO, RegVT, Custom); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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));
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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), |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
15db1f6
to
43a3d1b
Compare
…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.
This causes a crash while building the Linux kernel for 32-bit powerpc. For example:
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, 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" }
If there is any other information I can provide, please let me know. |
This is also breaking test-suite on AIX. I'm getting different numerical results in, for example:
|
A potential fix for it
in addition to #127376. 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" } |
…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.
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.