Skip to content

Commit 1a540c3

Browse files
authored
[PowerPC] Deprecate uses of ISD::ADDC/ISD::ADDE/ISD::SUBC/ISD::SUBE (#133155)
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.
1 parent 0bec0f5 commit 1a540c3

33 files changed

+718
-435
lines changed

llvm/include/llvm/CodeGen/LivePhysRegs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ void addLiveIns(MachineBasicBlock &MBB, const LivePhysRegs &LiveRegs);
195195
void computeAndAddLiveIns(LivePhysRegs &LiveRegs,
196196
MachineBasicBlock &MBB);
197197

198+
/// Check if physical register \p Reg is used after \p MBI.
199+
bool isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI);
200+
198201
/// Convenience function for recomputing live-in's for a MBB. Returns true if
199202
/// any changes were made.
200203
static inline bool recomputeLiveIns(MachineBasicBlock &MBB) {

llvm/lib/CodeGen/LivePhysRegs.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,3 +338,27 @@ void llvm::computeAndAddLiveIns(LivePhysRegs &LiveRegs,
338338
computeLiveIns(LiveRegs, MBB);
339339
addLiveIns(MBB, LiveRegs);
340340
}
341+
342+
// Returns true if `Reg` is used after this iterator in the rest of the
343+
// basic block or any successors of the basic block.
344+
bool llvm::isPhysRegUsedAfter(Register Reg, MachineBasicBlock::iterator MBI) {
345+
assert(Reg.isPhysical() && "Apply to physical register only");
346+
347+
MachineBasicBlock *MBB = MBI->getParent();
348+
// Scan forward through BB for a use/def of Reg
349+
for (const MachineInstr &MI : llvm::make_range(std::next(MBI), MBB->end())) {
350+
if (MI.readsRegister(Reg, /*TRI=*/nullptr))
351+
return true;
352+
// If we found a def, we can stop searching.
353+
if (MI.definesRegister(Reg, /*TRI=*/nullptr))
354+
return false;
355+
}
356+
357+
// If we hit the end of the block, check whether Reg is live into a
358+
// successor.
359+
for (MachineBasicBlock *Succ : MBB->successors())
360+
if (Succ->isLiveIn(Reg))
361+
return true;
362+
363+
return false;
364+
}

llvm/lib/Target/PowerPC/PPCISelLowering.cpp

Lines changed: 137 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "llvm/ADT/StringRef.h"
3737
#include "llvm/CodeGen/CallingConvLower.h"
3838
#include "llvm/CodeGen/ISDOpcodes.h"
39+
#include "llvm/CodeGen/LivePhysRegs.h"
3940
#include "llvm/CodeGen/MachineBasicBlock.h"
4041
#include "llvm/CodeGen/MachineFrameInfo.h"
4142
#include "llvm/CodeGen/MachineFunction.h"
@@ -197,6 +198,11 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
197198
}
198199

199200
setOperationAction(ISD::UADDO, RegVT, Custom);
201+
setOperationAction(ISD::USUBO, RegVT, Custom);
202+
203+
// PowerPC uses addo_carry,subo_carry to propagate carry.
204+
setOperationAction(ISD::UADDO_CARRY, RegVT, Custom);
205+
setOperationAction(ISD::USUBO_CARRY, RegVT, Custom);
200206

201207
// On P10, the default lowering generates better code using the
202208
// setbc instruction.
@@ -266,15 +272,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
266272
setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal);
267273
}
268274

269-
// PowerPC uses ADDC/ADDE/SUBC/SUBE to propagate carry.
270-
const MVT ScalarIntVTs[] = { MVT::i32, MVT::i64 };
271-
for (MVT VT : ScalarIntVTs) {
272-
setOperationAction(ISD::ADDC, VT, Legal);
273-
setOperationAction(ISD::ADDE, VT, Legal);
274-
setOperationAction(ISD::SUBC, VT, Legal);
275-
setOperationAction(ISD::SUBE, VT, Legal);
276-
}
277-
278275
if (Subtarget.useCRBits()) {
279276
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
280277

@@ -1864,6 +1861,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const {
18641861
return "PPCISD::SETBC";
18651862
case PPCISD::SETBCR:
18661863
return "PPCISD::SETBCR";
1864+
case PPCISD::ADDC:
1865+
return "PPCISD::ADDC";
1866+
case PPCISD::ADDE:
1867+
return "PPCISD::ADDE";
1868+
case PPCISD::SUBC:
1869+
return "PPCISD::SUBC";
1870+
case PPCISD::SUBE:
1871+
return "PPCISD::SUBE";
18671872
}
18681873
return nullptr;
18691874
}
@@ -12150,43 +12155,74 @@ SDValue PPCTargetLowering::LowerFP_EXTEND(SDValue Op, SelectionDAG &DAG) const {
1215012155
llvm_unreachable("ERROR:Should return for all cases within swtich.");
1215112156
}
1215212157

12153-
SDValue PPCTargetLowering::LowerUaddo(SDValue Op, SelectionDAG &DAG) const {
12154-
// Default to target independent lowering if there is a logical user of the
12155-
// carry-bit.
12156-
for (SDNode *U : Op->users()) {
12157-
if (U->getOpcode() == ISD::SELECT)
12158-
return SDValue();
12159-
if (ISD::isBitwiseLogicOp(U->getOpcode())) {
12160-
for (unsigned i = 0, ie = U->getNumOperands(); i != ie; ++i) {
12161-
if (U->getOperand(i).getOpcode() != ISD::UADDO &&
12162-
U->getOperand(i).getOpcode() != ISD::MERGE_VALUES)
12163-
return SDValue();
12164-
}
12165-
}
12166-
}
12167-
SDValue LHS = Op.getOperand(0);
12168-
SDValue RHS = Op.getOperand(1);
12169-
SDLoc dl(Op);
12170-
12171-
// Default to target independent lowering for special cases handled there.
12172-
if (isOneConstant(RHS) || isAllOnesConstant(RHS))
12173-
return SDValue();
12158+
static SDValue ConvertCarryValueToCarryFlag(EVT SumType, SDValue Value,
12159+
SelectionDAG &DAG,
12160+
const PPCSubtarget &STI) {
12161+
SDLoc DL(Value);
12162+
if (STI.useCRBits())
12163+
Value = DAG.getNode(ISD::SELECT, DL, SumType, Value,
12164+
DAG.getConstant(1, DL, SumType),
12165+
DAG.getConstant(0, DL, SumType));
12166+
else
12167+
Value = DAG.getZExtOrTrunc(Value, DL, SumType);
12168+
SDValue Sum = DAG.getNode(PPCISD::ADDC, DL, DAG.getVTList(SumType, MVT::i32),
12169+
Value, DAG.getAllOnesConstant(DL, SumType));
12170+
return Sum.getValue(1);
12171+
}
1217412172

12175-
EVT VT = Op.getNode()->getValueType(0);
12173+
static SDValue ConvertCarryFlagToCarryValue(EVT SumType, SDValue Flag,
12174+
EVT CarryType, SelectionDAG &DAG,
12175+
const PPCSubtarget &STI) {
12176+
SDLoc DL(Flag);
12177+
SDValue Zero = DAG.getConstant(0, DL, SumType);
12178+
SDValue Carry = DAG.getNode(
12179+
PPCISD::ADDE, DL, DAG.getVTList(SumType, MVT::i32), Zero, Zero, Flag);
12180+
if (STI.useCRBits())
12181+
return DAG.getSetCC(DL, CarryType, Carry, Zero, ISD::SETNE);
12182+
return DAG.getZExtOrTrunc(Carry, DL, CarryType);
12183+
}
1217612184

12177-
SDValue ADDC;
12178-
SDValue Overflow;
12179-
SDVTList VTs = Op.getNode()->getVTList();
12185+
SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const {
1218012186

12181-
ADDC = DAG.getNode(ISD::ADDC, dl, DAG.getVTList(VT, MVT::Glue), LHS, RHS);
12182-
Overflow = DAG.getNode(ISD::ADDE, dl, DAG.getVTList(VT, MVT::Glue),
12183-
DAG.getConstant(0, dl, VT), DAG.getConstant(0, dl, VT),
12184-
ADDC.getValue(1));
12185-
SDValue OverflowTrunc =
12186-
DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow);
12187-
SDValue Res =
12188-
DAG.getNode(ISD::MERGE_VALUES, dl, VTs, ADDC.getValue(0), OverflowTrunc);
12189-
return Res;
12187+
SDLoc DL(Op);
12188+
SDNode *N = Op.getNode();
12189+
EVT VT = N->getValueType(0);
12190+
EVT CarryType = N->getValueType(1);
12191+
unsigned Opc = N->getOpcode();
12192+
bool IsAdd = Opc == ISD::UADDO;
12193+
Opc = IsAdd ? PPCISD::ADDC : PPCISD::SUBC;
12194+
SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12195+
N->getOperand(0), N->getOperand(1));
12196+
SDValue Carry = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType,
12197+
DAG, Subtarget);
12198+
if (!IsAdd)
12199+
Carry = DAG.getNode(ISD::XOR, DL, CarryType, Carry,
12200+
DAG.getConstant(1UL, DL, CarryType));
12201+
return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, Carry);
12202+
}
12203+
12204+
SDValue PPCTargetLowering::LowerADDSUBO_CARRY(SDValue Op,
12205+
SelectionDAG &DAG) const {
12206+
SDLoc DL(Op);
12207+
SDNode *N = Op.getNode();
12208+
unsigned Opc = N->getOpcode();
12209+
EVT VT = N->getValueType(0);
12210+
EVT CarryType = N->getValueType(1);
12211+
SDValue CarryOp = N->getOperand(2);
12212+
bool IsAdd = Opc == ISD::UADDO_CARRY;
12213+
Opc = IsAdd ? PPCISD::ADDE : PPCISD::SUBE;
12214+
if (!IsAdd)
12215+
CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12216+
DAG.getAllOnesConstant(DL, CarryOp.getValueType()));
12217+
CarryOp = ConvertCarryValueToCarryFlag(VT, CarryOp, DAG, Subtarget);
12218+
SDValue Sum = DAG.getNode(Opc, DL, DAG.getVTList(VT, MVT::i32),
12219+
Op.getOperand(0), Op.getOperand(1), CarryOp);
12220+
CarryOp = ConvertCarryFlagToCarryValue(VT, Sum.getValue(1), CarryType, DAG,
12221+
Subtarget);
12222+
if (!IsAdd)
12223+
CarryOp = DAG.getNode(ISD::XOR, DL, CarryOp.getValueType(), CarryOp,
12224+
DAG.getConstant(1UL, DL, CarryOp.getValueType()));
12225+
return DAG.getNode(ISD::MERGE_VALUES, DL, N->getVTList(), Sum, CarryOp);
1219012226
}
1219112227

1219212228
SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
@@ -12217,8 +12253,8 @@ SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const {
1221712253
///
1221812254
SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1221912255
switch (Op.getOpcode()) {
12220-
default: llvm_unreachable("Wasn't expecting to be able to lower this!");
12221-
case ISD::UADDO: return LowerUaddo(Op, DAG);
12256+
default:
12257+
llvm_unreachable("Wasn't expecting to be able to lower this!");
1222212258
case ISD::FPOW: return lowerPow(Op, DAG);
1222312259
case ISD::FSIN: return lowerSin(Op, DAG);
1222412260
case ISD::FCOS: return lowerCos(Op, DAG);
@@ -12311,6 +12347,12 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
1231112347
return LowerATOMIC_LOAD_STORE(Op, DAG);
1231212348
case ISD::IS_FPCLASS:
1231312349
return LowerIS_FPCLASS(Op, DAG);
12350+
case ISD::UADDO:
12351+
case ISD::USUBO:
12352+
return LowerADDSUBO(Op, DAG);
12353+
case ISD::UADDO_CARRY:
12354+
case ISD::USUBO_CARRY:
12355+
return LowerADDSUBO_CARRY(Op, DAG);
1231412356
}
1231512357
}
1231612358

@@ -13393,6 +13435,11 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
1339313435
F->insert(It, copy0MBB);
1339413436
F->insert(It, sinkMBB);
1339513437

13438+
if (isPhysRegUsedAfter(PPC::CARRY, MI.getIterator())) {
13439+
copy0MBB->addLiveIn(PPC::CARRY);
13440+
sinkMBB->addLiveIn(PPC::CARRY);
13441+
}
13442+
1339613443
// Set the call frame size on entry to the new basic blocks.
1339713444
// See https://reviews.llvm.org/D156113.
1339813445
unsigned CallFrameSize = TII->getCallFrameSizeAt(MI);
@@ -16245,6 +16292,21 @@ static bool isStoreConditional(SDValue Intrin, unsigned &StoreWidth) {
1624516292
return true;
1624616293
}
1624716294

16295+
static SDValue DAGCombineAddc(SDNode *N,
16296+
llvm::PPCTargetLowering::DAGCombinerInfo &DCI) {
16297+
if (N->getOpcode() == PPCISD::ADDC && N->hasAnyUseOfValue(1)) {
16298+
// (ADDC (ADDE 0, 0, C), -1) -> C
16299+
SDValue LHS = N->getOperand(0);
16300+
SDValue RHS = N->getOperand(1);
16301+
if (LHS->getOpcode() == PPCISD::ADDE &&
16302+
isNullConstant(LHS->getOperand(0)) &&
16303+
isNullConstant(LHS->getOperand(1)) && isAllOnesConstant(RHS)) {
16304+
return DCI.CombineTo(N, SDValue(N, 0), LHS->getOperand(2));
16305+
}
16306+
}
16307+
return SDValue();
16308+
}
16309+
1624816310
SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1624916311
DAGCombinerInfo &DCI) const {
1625016312
SelectionDAG &DAG = DCI.DAG;
@@ -17033,6 +17095,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N,
1703317095
}
1703417096
case ISD::BUILD_VECTOR:
1703517097
return DAGCombineBuildVector(N, DCI);
17098+
case PPCISD::ADDC:
17099+
return DAGCombineAddc(N, DCI);
1703617100
}
1703717101

1703817102
return SDValue();
@@ -17086,6 +17150,16 @@ void PPCTargetLowering::computeKnownBitsForTargetNode(const SDValue Op,
1708617150
Known.Zero = 0xFFFF0000;
1708717151
break;
1708817152
}
17153+
case PPCISD::ADDE: {
17154+
if (Op.getResNo() == 0) {
17155+
// (0|1), _ = ADDE 0, 0, CARRY
17156+
SDValue LHS = Op.getOperand(0);
17157+
SDValue RHS = Op.getOperand(1);
17158+
if (isNullConstant(LHS) && isNullConstant(RHS))
17159+
Known.Zero = ~1ULL;
17160+
}
17161+
break;
17162+
}
1708917163
case ISD::INTRINSIC_WO_CHAIN: {
1709017164
switch (Op.getConstantOperandVal(0)) {
1709117165
default: break;
@@ -18355,7 +18429,8 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1835518429
return SDValue();
1835618430

1835718431
SDLoc DL(N);
18358-
SDVTList VTs = DAG.getVTList(MVT::i64, MVT::Glue);
18432+
EVT CarryType = Subtarget.useCRBits() ? MVT::i1 : MVT::i32;
18433+
SDVTList VTs = DAG.getVTList(MVT::i64, CarryType);
1835918434
SDValue Cmp = RHS.getOperand(0);
1836018435
SDValue Z = Cmp.getOperand(0);
1836118436
auto *Constant = cast<ConstantSDNode>(Cmp.getOperand(1));
@@ -18373,11 +18448,14 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1837318448
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1837418449
DAG.getConstant(NegConstant, DL, MVT::i64));
1837518450
SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18376-
SDValue Addc = DAG.getNode(ISD::ADDC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18377-
AddOrZ, DAG.getAllOnesConstant(DL, MVT::i64));
18378-
return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18451+
SDValue Addc =
18452+
DAG.getNode(ISD::UADDO_CARRY, DL, DAG.getVTList(MVT::i64, CarryType),
18453+
AddOrZ, DAG.getAllOnesConstant(DL, MVT::i64),
18454+
DAG.getConstant(0, DL, CarryType));
18455+
return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18456+
DAG.getConstant(0, DL, MVT::i64),
1837918457
SDValue(Addc.getNode(), 1));
18380-
}
18458+
}
1838118459
case ISD::SETEQ: {
1838218460
// when C == 0
1838318461
// --> addze X, (subfic Z, 0).carry
@@ -18388,11 +18466,15 @@ static SDValue combineADDToADDZE(SDNode *N, SelectionDAG &DAG,
1838818466
SDValue Add = DAG.getNode(ISD::ADD, DL, MVT::i64, Z,
1838918467
DAG.getConstant(NegConstant, DL, MVT::i64));
1839018468
SDValue AddOrZ = NegConstant != 0 ? Add : Z;
18391-
SDValue Subc = DAG.getNode(ISD::SUBC, DL, DAG.getVTList(MVT::i64, MVT::Glue),
18392-
DAG.getConstant(0, DL, MVT::i64), AddOrZ);
18393-
return DAG.getNode(ISD::ADDE, DL, VTs, LHS, DAG.getConstant(0, DL, MVT::i64),
18394-
SDValue(Subc.getNode(), 1));
18395-
}
18469+
SDValue Subc =
18470+
DAG.getNode(ISD::USUBO_CARRY, DL, DAG.getVTList(MVT::i64, CarryType),
18471+
DAG.getConstant(0, DL, MVT::i64), AddOrZ,
18472+
DAG.getConstant(0, DL, CarryType));
18473+
SDValue Invert = DAG.getNode(ISD::XOR, DL, CarryType, Subc.getValue(1),
18474+
DAG.getConstant(1UL, DL, CarryType));
18475+
return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS,
18476+
DAG.getConstant(0, DL, MVT::i64), Invert);
18477+
}
1839618478
}
1839718479

1839818480
return SDValue();

llvm/lib/Target/PowerPC/PPCISelLowering.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ namespace llvm {
161161
SRA,
162162
SHL,
163163

164+
/// These nodes represent PPC arithmetic operations with carry.
165+
ADDC,
166+
ADDE,
167+
SUBC,
168+
SUBE,
169+
164170
/// FNMSUB - Negated multiply-subtract instruction.
165171
FNMSUB,
166172

@@ -1280,7 +1286,6 @@ namespace llvm {
12801286
SDValue LowerGlobalTLSAddressLinux(SDValue Op, SelectionDAG &DAG) const;
12811287
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
12821288
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
1283-
SDValue LowerUaddo(SDValue Op, SelectionDAG &DAG) const;
12841289
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
12851290
SDValue LowerSSUBO(SDValue Op, SelectionDAG &DAG) const;
12861291
SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
@@ -1316,6 +1321,8 @@ namespace llvm {
13161321
SDValue LowerBSWAP(SDValue Op, SelectionDAG &DAG) const;
13171322
SDValue LowerATOMIC_CMP_SWAP(SDValue Op, SelectionDAG &DAG) const;
13181323
SDValue LowerIS_FPCLASS(SDValue Op, SelectionDAG &DAG) const;
1324+
SDValue LowerADDSUBO_CARRY(SDValue Op, SelectionDAG &DAG) const;
1325+
SDValue LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const;
13191326
SDValue lowerToLibCall(const char *LibCallName, SDValue Op,
13201327
SelectionDAG &DAG) const;
13211328
SDValue lowerLibCallBasedOnType(const char *LibCallFloatName,

0 commit comments

Comments
 (0)