-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -197,6 +197,11 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM, | |
} | ||
|
||
setOperationAction(ISD::UADDO, RegVT, Custom); | ||
setOperationAction(ISD::USUBO, RegVT, Custom); | ||
|
||
// PowerPC uses addo_carry,subo_carry to propagate carry. | ||
setOperationAction(ISD::UADDO_CARRY, RegVT, Custom); | ||
setOperationAction(ISD::USUBO_CARRY, RegVT, Custom); | ||
|
||
// On P10, the default lowering generates better code using the | ||
// setbc instruction. | ||
|
@@ -260,15 +265,6 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM, | |
setIndexedStoreAction(ISD::PRE_INC, MVT::f64, Legal); | ||
} | ||
|
||
// PowerPC uses ADDC/ADDE/SUBC/SUBE 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 (Subtarget.useCRBits()) { | ||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); | ||
|
||
|
@@ -1854,6 +1850,14 @@ const char *PPCTargetLowering::getTargetNodeName(unsigned Opcode) const { | |
return "PPCISD::SETBC"; | ||
case PPCISD::SETBCR: | ||
return "PPCISD::SETBCR"; | ||
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; | ||
} | ||
|
@@ -12013,43 +12017,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 commentThe 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 commentThe 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 |
||
// Default to target independent lowering if there is a logical user of the | ||
// carry-bit. | ||
for (SDNode *U : Op->users()) { | ||
if (U->getOpcode() == ISD::SELECT) | ||
return SDValue(); | ||
if (ISD::isBitwiseLogicOp(U->getOpcode())) { | ||
for (unsigned i = 0, ie = U->getNumOperands(); i != ie; ++i) { | ||
if (U->getOperand(i).getOpcode() != ISD::UADDO && | ||
U->getOperand(i).getOpcode() != ISD::MERGE_VALUES) | ||
return SDValue(); | ||
} | ||
} | ||
} | ||
SDValue LHS = Op.getOperand(0); | ||
SDValue RHS = Op.getOperand(1); | ||
SDLoc dl(Op); | ||
|
||
// Default to target independent lowering for special cases handled there. | ||
if (isOneConstant(RHS) || isAllOnesConstant(RHS)) | ||
return SDValue(); | ||
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); | ||
} | ||
|
||
EVT VT = Op.getNode()->getValueType(0); | ||
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 ADDC; | ||
SDValue Overflow; | ||
SDVTList VTs = Op.getNode()->getVTList(); | ||
SDValue PPCTargetLowering::LowerADDSUBO(SDValue Op, SelectionDAG &DAG) const { | ||
|
||
ADDC = DAG.getNode(ISD::ADDC, dl, DAG.getVTList(VT, MVT::Glue), LHS, RHS); | ||
Overflow = DAG.getNode(ISD::ADDE, dl, DAG.getVTList(VT, MVT::Glue), | ||
DAG.getConstant(0, dl, VT), DAG.getConstant(0, dl, VT), | ||
ADDC.getValue(1)); | ||
SDValue OverflowTrunc = | ||
DAG.getNode(ISD::TRUNCATE, dl, Op.getNode()->getValueType(1), Overflow); | ||
SDValue Res = | ||
DAG.getNode(ISD::MERGE_VALUES, dl, VTs, ADDC.getValue(0), OverflowTrunc); | ||
return Res; | ||
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); | ||
} | ||
|
||
SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const { | ||
|
@@ -12080,8 +12115,8 @@ SDValue PPCTargetLowering::LowerSSUBO(SDValue Op, SelectionDAG &DAG) const { | |
/// | ||
SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { | ||
switch (Op.getOpcode()) { | ||
default: llvm_unreachable("Wasn't expecting to be able to lower this!"); | ||
case ISD::UADDO: return LowerUaddo(Op, DAG); | ||
default: | ||
llvm_unreachable("Wasn't expecting to be able to lower this!"); | ||
case ISD::FPOW: return lowerPow(Op, DAG); | ||
case ISD::FSIN: return lowerSin(Op, DAG); | ||
case ISD::FCOS: return lowerCos(Op, DAG); | ||
|
@@ -12174,6 +12209,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); | ||
} | ||
} | ||
|
||
|
@@ -16109,6 +16150,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; | ||
|
@@ -16897,6 +16953,8 @@ SDValue PPCTargetLowering::PerformDAGCombine(SDNode *N, | |
} | ||
case ISD::BUILD_VECTOR: | ||
return DAGCombineBuildVector(N, DCI); | ||
case PPCISD::ADDC: | ||
return DAGCombineAddc(N, DCI); | ||
} | ||
|
||
return SDValue(); | ||
|
@@ -16950,6 +17008,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; | ||
|
@@ -18219,7 +18287,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)); | ||
|
@@ -18237,11 +18306,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 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_CARRY, DL, DAG.getVTList(MVT::i64, CarryType), | ||
AddOrZ, DAG.getConstant(-1ULL, DL, MVT::i64), | ||
DAG.getConstant(0, DL, CarryType)); | ||
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 | ||
|
@@ -18252,11 +18324,15 @@ 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_CARRY, DL, DAG.getVTList(MVT::i64, CarryType), | ||
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)); | ||
return DAG.getNode(ISD::UADDO_CARRY, DL, VTs, LHS, | ||
DAG.getConstant(0, DL, MVT::i64), Invert); | ||
} | ||
} | ||
|
||
return SDValue(); | ||
|
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 usePPCISD::ADDC/ PPCISD::SUBC
instead ofISD::ADDC/ISD::SUBC
since theISD::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.