Skip to content

Commit

Permalink
Enable STRICT_FP_TO_SINT/UINT on X86 backend
Browse files Browse the repository at this point in the history
This patch is mainly for custom lowering the vector operation.

Differential Revision: https://reviews.llvm.org/D71592
  • Loading branch information
MoringLiu committed Dec 19, 2019
1 parent 97b5d6b commit 2f932b5
Show file tree
Hide file tree
Showing 18 changed files with 6,950 additions and 350 deletions.
31 changes: 26 additions & 5 deletions llvm/lib/CodeGen/SelectionDAG/LegalizeVectorOps.cpp
Expand Up @@ -506,6 +506,8 @@ SDValue VectorLegalizer::Promote(SDValue Op) {
return PromoteINT_TO_FP(Op);
case ISD::FP_TO_UINT:
case ISD::FP_TO_SINT:
case ISD::STRICT_FP_TO_UINT:
case ISD::STRICT_FP_TO_SINT:
// Promote the operation by extending the operand.
return PromoteFP_TO_INT(Op);
}
Expand Down Expand Up @@ -575,6 +577,7 @@ SDValue VectorLegalizer::PromoteINT_TO_FP(SDValue Op) {
SDValue VectorLegalizer::PromoteFP_TO_INT(SDValue Op) {
MVT VT = Op.getSimpleValueType();
MVT NVT = TLI.getTypeToPromoteTo(Op.getOpcode(), VT);
bool IsStrict = Op->isStrictFPOpcode();
assert(NVT.getVectorNumElements() == VT.getVectorNumElements() &&
"Vectors have different number of elements!");

Expand All @@ -585,17 +588,35 @@ SDValue VectorLegalizer::PromoteFP_TO_INT(SDValue Op) {
TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT))
NewOpc = ISD::FP_TO_SINT;

if (NewOpc == ISD::STRICT_FP_TO_UINT &&
TLI.isOperationLegalOrCustom(ISD::STRICT_FP_TO_SINT, NVT))
NewOpc = ISD::STRICT_FP_TO_SINT;

SDLoc dl(Op);
SDValue Promoted = DAG.getNode(NewOpc, dl, NVT, Op.getOperand(0));
SDValue Promoted, Chain;
if (IsStrict) {
Promoted = DAG.getNode(NewOpc, dl, {NVT, MVT::Other},
{Op.getOperand(0), Op.getOperand(1)});
Chain = Promoted.getValue(1);
} else
Promoted = DAG.getNode(NewOpc, dl, NVT, Op.getOperand(0));

// Assert that the converted value fits in the original type. If it doesn't
// (eg: because the value being converted is too big), then the result of the
// original operation was undefined anyway, so the assert is still correct.
Promoted = DAG.getNode(Op->getOpcode() == ISD::FP_TO_UINT ? ISD::AssertZext
: ISD::AssertSext,
dl, NVT, Promoted,
if (Op->getOpcode() == ISD::FP_TO_UINT ||
Op->getOpcode() == ISD::STRICT_FP_TO_UINT)
NewOpc = ISD::AssertZext;
else
NewOpc = ISD::AssertSext;

Promoted = DAG.getNode(NewOpc, dl, NVT, Promoted,
DAG.getValueType(VT.getScalarType()));
return DAG.getNode(ISD::TRUNCATE, dl, VT, Promoted);
Promoted = DAG.getNode(ISD::TRUNCATE, dl, VT, Promoted);
if (IsStrict)
return DAG.getMergeValues({Promoted, Chain}, dl);

return Promoted;
}

SDValue VectorLegalizer::ExpandLoad(SDValue Op) {
Expand Down
24 changes: 20 additions & 4 deletions llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
Expand Up @@ -816,7 +816,9 @@ void X86DAGToDAGISel::PreprocessISelDAG() {

switch (N->getOpcode()) {
case ISD::FP_TO_SINT:
case ISD::FP_TO_UINT: {
case ISD::FP_TO_UINT:
case ISD::STRICT_FP_TO_SINT:
case ISD::STRICT_FP_TO_UINT: {
// Replace vector fp_to_s/uint with their X86 specific equivalent so we
// don't need 2 sets of patterns.
if (!N->getSimpleValueType(0).isVector())
Expand All @@ -825,13 +827,27 @@ void X86DAGToDAGISel::PreprocessISelDAG() {
unsigned NewOpc;
switch (N->getOpcode()) {
default: llvm_unreachable("Unexpected opcode!");
case ISD::STRICT_FP_TO_SINT:
case ISD::FP_TO_SINT: NewOpc = X86ISD::CVTTP2SI; break;
case ISD::STRICT_FP_TO_UINT:
case ISD::FP_TO_UINT: NewOpc = X86ISD::CVTTP2UI; break;
}
SDValue Res = CurDAG->getNode(NewOpc, SDLoc(N), N->getValueType(0),
N->getOperand(0));
SDValue Res;
if (N->isStrictFPOpcode())
Res =
CurDAG->getNode(NewOpc, SDLoc(N), {N->getValueType(0), MVT::Other},
{N->getOperand(0), N->getOperand(1)});
else
Res =
CurDAG->getNode(NewOpc, SDLoc(N), {N->getValueType(0), MVT::Other},
{CurDAG->getEntryNode(), N->getOperand(0)});
--I;
CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), Res);
if (N->isStrictFPOpcode()) {
SDValue From[] = {SDValue(N, 0), SDValue(N, 1)};
SDValue To[] = {Res.getValue(0), Res.getValue(1)};
CurDAG->ReplaceAllUsesOfValuesWith(From, To, 2);
} else
CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), Res);
++I;
CurDAG->DeleteNode(N);
continue;
Expand Down

0 comments on commit 2f932b5

Please sign in to comment.