Skip to content

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

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

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 133 additions & 15 deletions llvm/lib/Target/PowerPC/PPCISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,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()) {
Expand Down Expand Up @@ -1841,6 +1843,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;
}
Expand Down Expand Up @@ -11722,6 +11732,75 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
llvm_unreachable("ERROR:Should return for all cases within swtich.");
}

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 {
Expand Down Expand Up @@ -11815,6 +11894,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);
}
}

Expand Down Expand Up @@ -15708,6 +15793,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;
Expand Down Expand Up @@ -16497,6 +16597,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
}
case ISD::BUILD_VECTOR:
return DAGCombineBuildVector(N, DCI);
case PPCISD::ADDC:
return DAGCombineAddc(N, DCI);
}

return SDValue();
Expand Down Expand Up @@ -16550,6 +16652,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;
Expand Down Expand Up @@ -17811,7 +17923,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));
Expand All @@ -17829,11 +17942,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
Expand All @@ -17844,11 +17959,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();
Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/Target/PowerPC/PPCISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down Expand Up @@ -1310,6 +1316,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,
Expand Down
20 changes: 10 additions & 10 deletions llvm/lib/Target/PowerPC/PPCInstr64Bit.td
Original file line number Diff line number Diff line change
Expand Up @@ -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))]>;
Expand All @@ -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,
Expand All @@ -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

Expand Down
17 changes: 17 additions & 0 deletions llvm/lib/Target/PowerPC/PPCInstrInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1759,6 +1759,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;
Expand Down
Loading