[PATCH] SelectionDAG: Expand i64 = FP_TO_SINT i32

Pete Cooper peter_cooper at apple.com
Sun May 25 12:35:00 PDT 2014


Hi Tom

The good looks fine but I'm not sure about the behavior of the algorithm. The original algorithm appears not to handle NaN or infinities. Is that the case?

If so, can you add comments saying this and guard with unsafe math.

Otherwise LGTM.

Thanks
Pete

Sent from my iPhone

> On May 25, 2014, at 12:09 PM, Tom Stellard <tom at stellard.net> wrote:
> 
> Ping.
> 
>> On Thu, May 15, 2014 at 06:26:29AM -0700, Tom Stellard wrote:
>> Ping.
>> 
>>> On Tue, May 06, 2014 at 02:32:35AM -0400, Tom Stellard wrote:
>>> ---
>>> lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 59 ++++++++++++++++++++++++++++++++
>>> lib/Target/R600/AMDGPUISelLowering.cpp   |  2 ++
>>> test/CodeGen/R600/fp_to_sint_i64.ll      | 12 +++++++
>>> 3 files changed, 73 insertions(+)
>>> create mode 100644 test/CodeGen/R600/fp_to_sint_i64.ll
>>> 
>>> diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
>>> index 745ed4a..13c71fc 100644
>>> --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
>>> +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
>>> @@ -3128,6 +3128,65 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
>>>                                 Node->getOperand(0), Node->getValueType(0), dl);
>>>     Results.push_back(Tmp1);
>>>     break;
>>> +  case ISD::FP_TO_SINT: {
>>> +    EVT VT = Node->getOperand(0).getValueType();
>>> +    EVT NVT = Node->getValueType(0);
>>> +
>>> +    // FIXME: Only f32 to i64 conversions are supported.
>>> +    if (VT != MVT::f32 || NVT != MVT::i64)
>>> +      break;
>>> +
>>> +    // Expand f32 -> i64 conversion
>>> +    // This algorithm comes from compiler-rt's implementation of fixsfdi:
>>> +    // https://github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/fixsfdi.c
>>> +    EVT IntVT = EVT::getIntegerVT(*DAG.getContext(),
>>> +                                  VT.getSizeInBits());
>>> +    SDValue ExponentMask = DAG.getConstant(0x7F800000, IntVT);
>>> +    SDValue ExponentLoBit = DAG.getConstant(23, IntVT);
>>> +    SDValue Bias = DAG.getConstant(127, IntVT);
>>> +    SDValue SignMask = DAG.getConstant(APInt::getSignBit(VT.getSizeInBits()),
>>> +                                       IntVT);
>>> +    SDValue SignLowBit = DAG.getConstant(VT.getSizeInBits() - 1, IntVT);
>>> +    SDValue MantissaMask = DAG.getConstant(0x007FFFFF, IntVT);
>>> +
>>> +    SDValue Bits = DAG.getNode(ISD::BITCAST, dl, IntVT, Node->getOperand(0));
>>> +
>>> +    SDValue ExponentBits = DAG.getNode(ISD::SRL, dl, IntVT,
>>> +        DAG.getNode(ISD::AND, dl, IntVT, Bits, ExponentMask),
>>> +        DAG.getZExtOrTrunc(ExponentLoBit, dl, TLI.getShiftAmountTy(IntVT)));
>>> +    SDValue Exponent = DAG.getNode(ISD::SUB, dl, IntVT, ExponentBits, Bias);
>>> +
>>> +    SDValue Sign = DAG.getNode(ISD::SRA, dl, IntVT,
>>> +        DAG.getNode(ISD::AND, dl, IntVT, Bits, SignMask),
>>> +        DAG.getZExtOrTrunc(SignLowBit, dl, TLI.getShiftAmountTy(IntVT)));
>>> +    Sign = DAG.getSExtOrTrunc(Sign, dl, NVT);
>>> +
>>> +    SDValue R = DAG.getNode(ISD::OR, dl, IntVT,
>>> +        DAG.getNode(ISD::AND, dl, IntVT, Bits, MantissaMask),
>>> +        DAG.getConstant(0x00800000, IntVT));
>>> +
>>> +    R = DAG.getZExtOrTrunc(R, dl, NVT);
>>> +
>>> +
>>> +    R = DAG.getSelectCC(dl, Exponent, ExponentLoBit,
>>> +       DAG.getNode(ISD::SHL, dl, NVT, R,
>>> +                   DAG.getZExtOrTrunc(
>>> +                      DAG.getNode(ISD::SUB, dl, IntVT, Exponent, ExponentLoBit),
>>> +                      dl, TLI.getShiftAmountTy(IntVT))),
>>> +       DAG.getNode(ISD::SRL, dl, NVT, R,
>>> +                   DAG.getZExtOrTrunc(
>>> +                      DAG.getNode(ISD::SUB, dl, IntVT, ExponentLoBit, Exponent),
>>> +                      dl, TLI.getShiftAmountTy(IntVT))),
>>> +       ISD::SETGT);
>>> +
>>> +    SDValue Ret = DAG.getNode(ISD::SUB, dl, NVT,
>>> +        DAG.getNode(ISD::XOR, dl, NVT, R, Sign),
>>> +        Sign);
>>> +
>>> +    Results.push_back(DAG.getSelectCC(dl, Exponent, DAG.getConstant(0, IntVT),
>>> +        DAG.getConstant(0, NVT), Ret, ISD::SETLT));
>>> +    break;
>>> +  }
>>>   case ISD::FP_TO_UINT: {
>>>     SDValue True, False;
>>>     EVT VT =  Node->getOperand(0).getValueType();
>>> diff --git a/lib/Target/R600/AMDGPUISelLowering.cpp b/lib/Target/R600/AMDGPUISelLowering.cpp
>>> index 7ee4ccd..50856cd 100644
>>> --- a/lib/Target/R600/AMDGPUISelLowering.cpp
>>> +++ b/lib/Target/R600/AMDGPUISelLowering.cpp
>>> @@ -196,6 +196,8 @@ AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
>>> 
>>>   setOperationAction(ISD::BR_CC, MVT::i1, Expand);
>>> 
>>> +  setOperationAction(ISD::FP_TO_SINT, MVT::i64, Expand);
>>> +
>>>   setOperationAction(ISD::FNEG, MVT::v2f32, Expand);
>>>   setOperationAction(ISD::FNEG, MVT::v4f32, Expand);
>>> 
>>> diff --git a/test/CodeGen/R600/fp_to_sint_i64.ll b/test/CodeGen/R600/fp_to_sint_i64.ll
>>> new file mode 100644
>>> index 0000000..ec3e198
>>> --- /dev/null
>>> +++ b/test/CodeGen/R600/fp_to_sint_i64.ll
>>> @@ -0,0 +1,12 @@
>>> +; FIXME: Merge into fp_to_sint.ll when EG/NI supports 64-bit types
>>> +; RUN: llc < %s -march=r600 -mcpu=SI -verify-machineinstrs | FileCheck --check-prefix=SI %s
>>> +
>>> +; SI-LABEL: @fp_to_sint_i64
>>> +; Check that the compiler doesn't crash with a "cannot select" error
>>> +; SI: S_ENDPGM
>>> +define void @fp_to_sint_i64 (i64 addrspace(1)* %out, float %in) {
>>> +entry:
>>> +  %0 = fptosi float %in to i64
>>> +  store i64 %0, i64 addrspace(1)* %out
>>> +  ret void
>>> +}
>>> -- 
>>> 1.8.1.5
>>> 
>>> _______________________________________________
>>> llvm-commits mailing list
>>> llvm-commits at cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list