mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 06:30:16 +00:00
Add SDNodes for umin, umax, smin and smax.
This adds new SDNodes for signed/unsigned min/max. These nodes are built from select/icmp pairs matched at SDAGBuilder stage. This patch adds the nodes, as well as legalization support and sets them to be "expand" for all targets. NFC for now; this will be tested when I switch AArch64 to using these new nodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237423 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1cf942cb4f
commit
4fa71b66a8
@ -308,6 +308,10 @@ namespace ISD {
|
||||
/// part.
|
||||
MULHU, MULHS,
|
||||
|
||||
/// [US]{MIN/MAX} - Binary minimum or maximum or signed or unsigned
|
||||
/// integers.
|
||||
SMIN, SMAX, UMIN, UMAX,
|
||||
|
||||
/// Bitwise operators - logical and, logical or, logical xor.
|
||||
AND, OR, XOR,
|
||||
|
||||
|
@ -380,6 +380,10 @@ def subc : SDNode<"ISD::SUBC" , SDTIntBinOp,
|
||||
[SDNPOutGlue]>;
|
||||
def sube : SDNode<"ISD::SUBE" , SDTIntBinOp,
|
||||
[SDNPOutGlue, SDNPInGlue]>;
|
||||
def smin : SDNode<"ISD::SMIN" , SDTIntBinOp>;
|
||||
def smax : SDNode<"ISD::SMAX" , SDTIntBinOp>;
|
||||
def umin : SDNode<"ISD::UMIN" , SDTIntBinOp>;
|
||||
def umax : SDNode<"ISD::UMAX" , SDTIntBinOp>;
|
||||
|
||||
def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
|
||||
def bswap : SDNode<"ISD::BSWAP" , SDTIntUnaryOp>;
|
||||
|
@ -3299,6 +3299,26 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
|
||||
Results.push_back(Tmp1);
|
||||
break;
|
||||
}
|
||||
case ISD::SMIN:
|
||||
case ISD::SMAX:
|
||||
case ISD::UMIN:
|
||||
case ISD::UMAX: {
|
||||
// Expand Y = MAX(A, B) -> Y = (A > B) ? A : B
|
||||
ISD::CondCode Pred;
|
||||
switch (Node->getOpcode()) {
|
||||
default: llvm_unreachable("How did we get here?");
|
||||
case ISD::SMAX: Pred = ISD::SETGT; break;
|
||||
case ISD::SMIN: Pred = ISD::SETLT; break;
|
||||
case ISD::UMAX: Pred = ISD::SETUGT; break;
|
||||
case ISD::UMIN: Pred = ISD::SETULT; break;
|
||||
}
|
||||
Tmp1 = Node->getOperand(0);
|
||||
Tmp2 = Node->getOperand(1);
|
||||
Tmp1 = DAG.getSelectCC(dl, Tmp1, Tmp2, Tmp1, Tmp2, Pred);
|
||||
Results.push_back(Tmp1);
|
||||
break;
|
||||
}
|
||||
|
||||
case ISD::FMINNUM:
|
||||
Results.push_back(ExpandFPLibCall(Node, RTLIB::FMIN_F32, RTLIB::FMIN_F64,
|
||||
RTLIB::FMIN_F80, RTLIB::FMIN_F128,
|
||||
|
@ -71,6 +71,10 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
|
||||
case ISD::VSELECT: Res = PromoteIntRes_VSELECT(N); break;
|
||||
case ISD::SELECT_CC: Res = PromoteIntRes_SELECT_CC(N); break;
|
||||
case ISD::SETCC: Res = PromoteIntRes_SETCC(N); break;
|
||||
case ISD::SMIN:
|
||||
case ISD::SMAX:
|
||||
case ISD::UMIN:
|
||||
case ISD::UMAX: Res = PromoteIntRes_SimpleIntBinOp(N); break;
|
||||
case ISD::SHL: Res = PromoteIntRes_SHL(N); break;
|
||||
case ISD::SIGN_EXTEND_INREG:
|
||||
Res = PromoteIntRes_SIGN_EXTEND_INREG(N); break;
|
||||
|
@ -322,6 +322,10 @@ SDValue VectorLegalizer::LegalizeOp(SDValue Op) {
|
||||
case ISD::ANY_EXTEND_VECTOR_INREG:
|
||||
case ISD::SIGN_EXTEND_VECTOR_INREG:
|
||||
case ISD::ZERO_EXTEND_VECTOR_INREG:
|
||||
case ISD::SMIN:
|
||||
case ISD::SMAX:
|
||||
case ISD::UMIN:
|
||||
case ISD::UMAX:
|
||||
QueryType = Node->getValueType(0);
|
||||
break;
|
||||
case ISD::FP_ROUND_INREG:
|
||||
|
@ -671,6 +671,10 @@ void DAGTypeLegalizer::SplitVectorResult(SDNode *N, unsigned ResNo) {
|
||||
case ISD::UREM:
|
||||
case ISD::SREM:
|
||||
case ISD::FREM:
|
||||
case ISD::SMIN:
|
||||
case ISD::SMAX:
|
||||
case ISD::UMIN:
|
||||
case ISD::UMAX:
|
||||
SplitVecRes_BinOp(N, Lo, Hi);
|
||||
break;
|
||||
case ISD::FMA:
|
||||
|
@ -2257,19 +2257,47 @@ void SelectionDAGBuilder::visitSelect(const User &I) {
|
||||
|
||||
SmallVector<SDValue, 4> Values(NumValues);
|
||||
SDValue Cond = getValue(I.getOperand(0));
|
||||
SDValue TrueVal = getValue(I.getOperand(1));
|
||||
SDValue FalseVal = getValue(I.getOperand(2));
|
||||
SDValue LHSVal = getValue(I.getOperand(1));
|
||||
SDValue RHSVal = getValue(I.getOperand(2));
|
||||
auto BaseOps = {Cond};
|
||||
ISD::NodeType OpCode = Cond.getValueType().isVector() ?
|
||||
ISD::VSELECT : ISD::SELECT;
|
||||
|
||||
for (unsigned i = 0; i != NumValues; ++i)
|
||||
// Min/max matching is only viable if all output VTs are the same.
|
||||
if (std::equal(ValueVTs.begin(), ValueVTs.end(), ValueVTs.begin())) {
|
||||
Value *LHS, *RHS;
|
||||
SelectPatternFlavor SPF = matchSelectPattern(const_cast<User*>(&I), LHS, RHS);
|
||||
ISD::NodeType Opc = ISD::DELETED_NODE;
|
||||
switch (SPF) {
|
||||
case SPF_UMAX: Opc = ISD::UMAX; break;
|
||||
case SPF_UMIN: Opc = ISD::UMIN; break;
|
||||
case SPF_SMAX: Opc = ISD::SMAX; break;
|
||||
case SPF_SMIN: Opc = ISD::SMIN; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
EVT VT = ValueVTs[0];
|
||||
LLVMContext &Ctx = *DAG.getContext();
|
||||
while (DAG.getTargetLoweringInfo().getTypeToTransformTo(Ctx, VT) != VT)
|
||||
VT = DAG.getTargetLoweringInfo().getTypeToTransformTo(Ctx, VT);
|
||||
|
||||
if (Opc != ISD::DELETED_NODE &&
|
||||
DAG.getTargetLoweringInfo().isOperationLegalOrCustom(Opc, VT)) {
|
||||
OpCode = Opc;
|
||||
LHSVal = getValue(LHS);
|
||||
RHSVal = getValue(RHS);
|
||||
BaseOps = {};
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i != NumValues; ++i) {
|
||||
SmallVector<SDValue, 3> Ops(BaseOps.begin(), BaseOps.end());
|
||||
Ops.push_back(SDValue(LHSVal.getNode(), LHSVal.getResNo() + i));
|
||||
Ops.push_back(SDValue(RHSVal.getNode(), RHSVal.getResNo() + i));
|
||||
Values[i] = DAG.getNode(OpCode, getCurSDLoc(),
|
||||
TrueVal.getNode()->getValueType(TrueVal.getResNo()+i),
|
||||
Cond,
|
||||
SDValue(TrueVal.getNode(),
|
||||
TrueVal.getResNo() + i),
|
||||
SDValue(FalseVal.getNode(),
|
||||
FalseVal.getResNo() + i));
|
||||
LHSVal.getNode()->getValueType(LHSVal.getResNo()+i),
|
||||
Ops);
|
||||
}
|
||||
|
||||
setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurSDLoc(),
|
||||
DAG.getVTList(ValueVTs), Values));
|
||||
|
@ -193,6 +193,10 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
case ISD::FCOPYSIGN: return "fcopysign";
|
||||
case ISD::FGETSIGN: return "fgetsign";
|
||||
case ISD::FPOW: return "fpow";
|
||||
case ISD::SMIN: return "smin";
|
||||
case ISD::SMAX: return "smax";
|
||||
case ISD::UMIN: return "umin";
|
||||
case ISD::UMAX: return "umax";
|
||||
|
||||
case ISD::FPOWI: return "fpowi";
|
||||
case ISD::SETCC: return "setcc";
|
||||
|
@ -811,6 +811,10 @@ void TargetLoweringBase::initActions() {
|
||||
setOperationAction(ISD::FMINNUM, VT, Expand);
|
||||
setOperationAction(ISD::FMAXNUM, VT, Expand);
|
||||
setOperationAction(ISD::FMAD, VT, Expand);
|
||||
setOperationAction(ISD::SMIN, VT, Expand);
|
||||
setOperationAction(ISD::SMAX, VT, Expand);
|
||||
setOperationAction(ISD::UMIN, VT, Expand);
|
||||
setOperationAction(ISD::UMAX, VT, Expand);
|
||||
|
||||
// Overflow operations default to expand
|
||||
setOperationAction(ISD::SADDO, VT, Expand);
|
||||
|
Loading…
x
Reference in New Issue
Block a user