From 1618bebcf6f9cd19c4e05de3bfffda28c246bb12 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 29 Jul 2005 00:11:56 +0000 Subject: [PATCH] allow a target to request that unknown FP_TO_*INT conversion be promoted to a larger integer destination. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22547 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 75 +++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 144de14aef6..a65e9b58a2b 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -128,6 +128,8 @@ private: SDOperand ExpandLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT); SDOperand PromoteLegalINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT, bool isSigned); + SDOperand PromoteLegalFP_TO_INT(SDOperand LegalOp, MVT::ValueType DestVT, + bool isSigned); bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt, SDOperand &Lo, SDOperand &Hi); @@ -202,7 +204,7 @@ SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0, } /// PromoteLegalUINT_TO_FP - This function is responsible for legalizing a -/// UINT_TO_FP operation of the specified operand when the target requests that +/// *INT_TO_FP operation of the specified operand when the target requests that /// we promote it. At this point, we know that the result and operand types are /// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP /// operation that takes a larger input. @@ -259,6 +261,63 @@ SDOperand SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDOperand LegalOp, NewInTy, LegalOp)); } +/// PromoteLegalFP_TO_INT - This function is responsible for legalizing a +/// FP_TO_*INT operation of the specified operand when the target requests that +/// we promote it. At this point, we know that the result and operand types are +/// legal for the target, and that there is a legal FP_TO_UINT or FP_TO_SINT +/// operation that returns a larger result. +SDOperand SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDOperand LegalOp, + MVT::ValueType DestVT, + bool isSigned) { + // First step, figure out the appropriate FP_TO*INT operation to use. + MVT::ValueType NewOutTy = DestVT; + + unsigned OpToUse = 0; + + // Scan for the appropriate larger type to use. + while (1) { + NewOutTy = (MVT::ValueType)(NewOutTy+1); + assert(MVT::isInteger(NewOutTy) && "Ran out of possibilities!"); + + // If the target supports FP_TO_SINT returning this type, use it. + switch (TLI.getOperationAction(ISD::FP_TO_SINT, NewOutTy)) { + default: break; + case TargetLowering::Legal: + if (!TLI.hasNativeSupportFor(NewOutTy)) + break; // Can't use this datatype. + // FALL THROUGH. + case TargetLowering::Custom: + OpToUse = ISD::FP_TO_SINT; + break; + } + if (OpToUse) break; + + // If the target supports FP_TO_UINT of this type, use it. + switch (TLI.getOperationAction(ISD::FP_TO_UINT, NewOutTy)) { + default: break; + case TargetLowering::Legal: + if (!TLI.hasNativeSupportFor(NewOutTy)) + break; // Can't use this datatype. + // FALL THROUGH. + case TargetLowering::Custom: + OpToUse = ISD::FP_TO_UINT; + break; + } + if (OpToUse) break; + + // Otherwise, try a larger type. + } + + // Make sure to legalize any nodes we create here in the next pass. + NeedsAnotherIteration = true; + + // Okay, we found the operation and type to use. Truncate the result of the + // extended FP_TO_*INT operation to the desired size. + return DAG.getNode(ISD::TRUNCATE, DestVT, + DAG.getNode(OpToUse, NewOutTy, LegalOp)); +} + + void SelectionDAGLegalize::LegalizeDAG() { SDOperand OldRoot = DAG.getRoot(); SDOperand NewRoot = LegalizeOp(OldRoot); @@ -1511,6 +1570,20 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case ISD::FP_TO_UINT: switch (getTypeAction(Node->getOperand(0).getValueType())) { case Legal: + switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))){ + default: assert(0 && "Unknown operation action!"); + case TargetLowering::Expand: + assert(0 && "Cannot expand FP_TO*INT yet"); + case TargetLowering::Promote: + Result = PromoteLegalFP_TO_INT(LegalizeOp(Node->getOperand(0)), + Node->getValueType(0), + Node->getOpcode() == ISD::FP_TO_SINT); + AddLegalizedOperand(Op, Result); + return Result; + case TargetLowering::Legal: + break; + } + Tmp1 = LegalizeOp(Node->getOperand(0)); if (Tmp1 != Node->getOperand(0)) Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);