[llvm] r173755 - Teach SDISel to combine fsin / fcos into a fsincos node if the following

Redmond, Paul paul.redmond at intel.com
Fri Feb 1 12:17:43 PST 2013


Hi Hal,

On 2013-02-01, at 2:50 PM, Hal Finkel wrote:

> ----- Original Message -----
>> From: "Paul Redmond" <paul.redmond at intel.com>
>> To: "Hal Finkel" <hfinkel at anl.gov>
>> Cc: "Evan Cheng" <evan.cheng at apple.com>, "llvm-commits" <llvm-commits at cs.uiuc.edu>
>> Sent: Friday, February 1, 2013 9:58:39 AM
>> Subject: Re: [llvm] r173755 - Teach SDISel to combine fsin / fcos into a	fsincos	node if the following
>> 
>> Thanks for the feedback Hal!
>> 
>> Attached is an updated patch which generally enables the sincos
>> optimization for GNU environments.
> 
> Thanks!
> 
>     if ((TLI.isOperationLegalOrCustom(ISD::FSINCOS, VT) ||
> -         isSinCosLibcallAvailable(Node, TLI))
> +        (TM.Options.UnsafeFPMath && isSinCosLibcallAvailable(Node, TLI)))
>         && useSinCos(Node)) {
> 
> It looks like this makes it so that any target that can use this in non-fast math mode *needs* to do custom lowering. I don't think that is the indended effect. Can you move the UnsafeFPMath check to here:
> 
> +  if (Triple(TM.getTargetTriple()).getEnvironment() == Triple::GNU) {
> +    Names[RTLIB::SINCOS_F32] = "sincosf";
> 

The reason I didn't do this is because the UnsafeFPMath option is only necessary for the optimization. UnsafeFPMath doesn't mean the functions isn't available in the runtime library. I realize sincos is only generated by the optimization but that may not always be true.

Any suggestions?

paul

> -Hal
> 
>> 
>> Paul
>> 
>> 
>> On 2013-01-31, at 5:45 PM, Hal Finkel wrote:
>> 
>>> ----- Original Message -----
>>>> From: "Paul Redmond" <paul.redmond at intel.com>
>>>> To: "Hal Finkel" <hfinkel at anl.gov>
>>>> Cc: "Evan Cheng" <evan.cheng at apple.com>,
>>>> "<llvm-commits at cs.uiuc.edu>" <llvm-commits at cs.uiuc.edu>
>>>> Sent: Thursday, January 31, 2013 4:35:34 PM
>>>> Subject: Re: [llvm] r173755 - Teach SDISel to combine fsin / fcos
>>>> into a     fsincos node if the following
>>>> 
>>>> Hi,
>>>> 
>>>> The attached patch enables this optimization for GNU environments.
>>>> Please review.
>>> 
>>> Why are you only making this change for X86? Can we make it more
>>> generally for GNU environments? glibc is glibc, right? ;)
>>> 
>>>> 
>>>> PS. I'm not sure if the UnsafeFPMath check needs to be added to
>>>> the
>>>> OSX case as well..?
>>> 
>>> I think we need it for the GNU case because the GNU version does
>>> not set errno.
>>> 
>>> -Hal
>>> 
>>>> 
>>>> paul
>>>> 
>>>> 
>>>> 
>>>> On 2013-01-29, at 12:51 AM, Hal Finkel wrote:
>>>> 
>>>>> ----- Original Message -----
>>>>>> From: "Hal Finkel" <hfinkel at anl.gov>
>>>>>> To: "Evan Cheng" <evan.cheng at apple.com>
>>>>>> Cc: llvm-commits at cs.uiuc.edu
>>>>>> Sent: Monday, January 28, 2013 11:24:58 PM
>>>>>> Subject: Re: [llvm] r173755 - Teach SDISel to combine fsin /
>>>>>> fcos
>>>>>> into a     fsincos node if the following
>>>>>> 
>>>>>> ----- Original Message -----
>>>>>>> From: "Evan Cheng" <evan.cheng at apple.com>
>>>>>>> To: "Hal Finkel" <hfinkel at anl.gov>
>>>>>>> Cc: llvm-commits at cs.uiuc.edu
>>>>>>> Sent: Monday, January 28, 2013 11:04:22 PM
>>>>>>> Subject: Re: [llvm] r173755 - Teach SDISel to combine fsin /
>>>>>>> fcos
>>>>>>> into a fsincos      node if the following
>>>>>>> 
>>>>>>> 
>>>>>>> 
>>>>>>> Sent from my iPad
>>>>>>> 
>>>>>>> On Jan 28, 2013, at 8:01 PM, Hal Finkel <hfinkel at anl.gov>
>>>>>>> wrote:
>>>>>>> 
>>>>>>>> ----- Original Message -----
>>>>>>>>> From: "Hal Finkel" <hfinkel at anl.gov>
>>>>>>>>> To: "Evan Cheng" <evan.cheng at apple.com>
>>>>>>>>> Cc: llvm-commits at cs.uiuc.edu
>>>>>>>>> Sent: Monday, January 28, 2013 9:13:43 PM
>>>>>>>>> Subject: Re: [llvm] r173755 - Teach SDISel to combine fsin /
>>>>>>>>> fcos
>>>>>>>>> into a    fsincos    node if the following
>>>>>>>>> 
>>>>>>>>> Evan, et al.,
>>>>>>>>> 
>>>>>>>>> glibc provides sincos() (and sincosf, sincosl), so would it
>>>>>>>>> make
>>>>>>>>> sense to enable this on systems with -gnu- in the triple?
>>>>>>>> 
>>>>>>>> Also, is there a difference in how errno is set?
>>>>>>> 
>>>>>>> I am going to let other folks to add the optimization to gnu
>>>>>>> platforms. I can test it so I'm not going to do it blindly. On
>>>>>>> Apple
>>>>>>> platforms, there is no change to how errno is set.
>>>>>> 
>>>>>> According to the glibc man page, sincos() does not set errno at
>>>>>> all.
>>>>>> Can we do this in a fast-math predicated way?
>>>>> 
>>>>> Never mind ;) -- making this conditional on UnsafeFPMath should
>>>>> be
>>>>> easy. I forgot that this is not (yet?) a function attribute.
>>>>> 
>>>>> -Hal
>>>>> 
>>>>>> 
>>>>>> Thanks again,
>>>>>> Hal
>>>>>> 
>>>>>>> 
>>>>>>> Evan
>>>>>>> 
>>>>>>>> 
>>>>>>>> -Hal
>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Thanks again,
>>>>>>>>> Hal
>>>>>>>>> 
>>>>>>>>> ----- Original Message -----
>>>>>>>>>> From: "Evan Cheng" <evan.cheng at apple.com>
>>>>>>>>>> To: llvm-commits at cs.uiuc.edu
>>>>>>>>>> Sent: Monday, January 28, 2013 8:32:37 PM
>>>>>>>>>> Subject: [llvm] r173755 - Teach SDISel to combine fsin /
>>>>>>>>>> fcos
>>>>>>>>>> into
>>>>>>>>>> a fsincos    node if the following
>>>>>>>>>> 
>>>>>>>>>> Author: evancheng
>>>>>>>>>> Date: Mon Jan 28 20:32:37 2013
>>>>>>>>>> New Revision: 173755
>>>>>>>>>> 
>>>>>>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=173755&view=rev
>>>>>>>>>> Log:
>>>>>>>>>> Teach SDISel to combine fsin / fcos into a fsincos node if
>>>>>>>>>> the
>>>>>>>>>> following
>>>>>>>>>> conditions are met:
>>>>>>>>>> 1. They share the same operand and are in the same BB.
>>>>>>>>>> 2. Both outputs are used.
>>>>>>>>>> 3. The target has a native instruction that maps to
>>>>>>>>>> ISD::FSINCOS
>>>>>>>>>> node
>>>>>>>>>> or
>>>>>>>>>> the target provides a sincos library call.
>>>>>>>>>> 
>>>>>>>>>> Implemented the generic optimization in sdisel and enabled
>>>>>>>>>> it
>>>>>>>>>> for
>>>>>>>>>> Mac OSX. Also added an additional optimization for x86_64
>>>>>>>>>> Mac
>>>>>>>>>> OSX
>>>>>>>>>> by
>>>>>>>>>> using an alternative entry point __sincos_stret which
>>>>>>>>>> returns
>>>>>>>>>> the
>>>>>>>>>> two
>>>>>>>>>> results in xmm0 / xmm1.
>>>>>>>>>> 
>>>>>>>>>> rdar://13087969
>>>>>>>>>> PR13204
>>>>>>>>>> 
>>>>>>>>>> Modified:
>>>>>>>>>> llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h
>>>>>>>>>> llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h
>>>>>>>>>> llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
>>>>>>>>>> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
>>>>>>>>>> llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp
>>>>>>>>>> llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
>>>>>>>>>> llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
>>>>>>>>>> llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp
>>>>>>>>>> llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
>>>>>>>>>> llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
>>>>>>>>>> llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
>>>>>>>>>> llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>>>>>>>>>> llvm/trunk/lib/Target/X86/X86ISelLowering.h
>>>>>>>>>> llvm/trunk/lib/Target/X86/X86Subtarget.cpp
>>>>>>>>>> llvm/trunk/lib/Target/X86/X86Subtarget.h
>>>>>>>>>> 
>>>>>>>>>> Modified: llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h (original)
>>>>>>>>>> +++ llvm/trunk/include/llvm/CodeGen/ISDOpcodes.h Mon Jan 28
>>>>>>>>>> 20:32:37
>>>>>>>>>> 2013
>>>>>>>>>> @@ -455,6 +455,9 @@ namespace ISD {
>>>>>>>>>>  FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
>>>>>>>>>>  FLOG, FLOG2, FLOG10, FEXP, FEXP2,
>>>>>>>>>>  FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR,
>>>>>>>>>> +
>>>>>>>>>> +    /// FSINCOS - Compute both fsin and fcos as a single
>>>>>>>>>> operation.
>>>>>>>>>> +    FSINCOS,
>>>>>>>>>> 
>>>>>>>>>>  /// LOAD and STORE have token chains as their first
>>>>>>>>>>  operand,
>>>>>>>>>>  then the same
>>>>>>>>>>  /// operands as an LLVM load/store instruction, then an
>>>>>>>>>>  offset
>>>>>>>>>>  node that
>>>>>>>>>> 
>>>>>>>>>> Modified: llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h
>>>>>>>>>> (original)
>>>>>>>>>> +++ llvm/trunk/include/llvm/CodeGen/RuntimeLibcalls.h Mon
>>>>>>>>>> Jan
>>>>>>>>>> 28
>>>>>>>>>> 20:32:37 2013
>>>>>>>>>> @@ -158,6 +158,11 @@ namespace RTLIB {
>>>>>>>>>>  COS_F80,
>>>>>>>>>>  COS_F128,
>>>>>>>>>>  COS_PPCF128,
>>>>>>>>>> +    SINCOS_F32,
>>>>>>>>>> +    SINCOS_F64,
>>>>>>>>>> +    SINCOS_F80,
>>>>>>>>>> +    SINCOS_F128,
>>>>>>>>>> +    SINCOS_PPCF128,
>>>>>>>>>>  POW_F32,
>>>>>>>>>>  POW_F64,
>>>>>>>>>>  POW_F80,
>>>>>>>>>> 
>>>>>>>>>> Modified:
>>>>>>>>>> llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
>>>>>>>>>> (original)
>>>>>>>>>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Mon
>>>>>>>>>> Jan
>>>>>>>>>> 28
>>>>>>>>>> 20:32:37 2013
>>>>>>>>>> @@ -102,7 +102,8 @@ private:
>>>>>>>>>>                                               SDNode *Node,
>>>>>>>>>>                                               bool
>>>>>>>>>>                                               isSigned);
>>>>>>>>>> SDValue ExpandFPLibCall(SDNode *Node, RTLIB::Libcall
>>>>>>>>>> Call_F32,
>>>>>>>>>>                        RTLIB::Libcall Call_F64,
>>>>>>>>>>                        RTLIB::Libcall
>>>>>>>>>>                        Call_F80,
>>>>>>>>>> -                          RTLIB::Libcall Call_F128,
>>>>>>>>>> RTLIB::Libcall
>>>>>>>>>> Call_PPCF128);
>>>>>>>>>> +                          RTLIB::Libcall Call_F128,
>>>>>>>>>> +                          RTLIB::Libcall Call_PPCF128);
>>>>>>>>>> SDValue ExpandIntLibCall(SDNode *Node, bool isSigned,
>>>>>>>>>>                         RTLIB::Libcall Call_I8,
>>>>>>>>>>                         RTLIB::Libcall Call_I16,
>>>>>>>>>> @@ -110,6 +111,7 @@ private:
>>>>>>>>>>                         RTLIB::Libcall Call_I64,
>>>>>>>>>>                         RTLIB::Libcall Call_I128);
>>>>>>>>>> void ExpandDivRemLibCall(SDNode *Node,
>>>>>>>>>> SmallVectorImpl<SDValue>
>>>>>>>>>> &Results);
>>>>>>>>>> +  void ExpandSinCosLibCall(SDNode *Node,
>>>>>>>>>> SmallVectorImpl<SDValue>
>>>>>>>>>> &Results);
>>>>>>>>>> 
>>>>>>>>>> SDValue EmitStackConvert(SDValue SrcOp, EVT SlotVT, EVT
>>>>>>>>>> DestVT,
>>>>>>>>>> DebugLoc dl);
>>>>>>>>>> SDValue ExpandBUILD_VECTOR(SDNode *Node);
>>>>>>>>>> @@ -2095,6 +2097,106 @@
>>>>>>>>>> SelectionDAGLegalize::ExpandDivRemLibCal
>>>>>>>>>> Results.push_back(Rem);
>>>>>>>>>> }
>>>>>>>>>> 
>>>>>>>>>> +/// isSinCosLibcallAvailable - Return true if sincos
>>>>>>>>>> libcall
>>>>>>>>>> is
>>>>>>>>>> available.
>>>>>>>>>> +static bool isSinCosLibcallAvailable(SDNode *Node, const
>>>>>>>>>> TargetLowering &TLI) {
>>>>>>>>>> +  RTLIB::Libcall LC;
>>>>>>>>>> +  switch (Node->getValueType(0).getSimpleVT().SimpleTy) {
>>>>>>>>>> +  default: llvm_unreachable("Unexpected request for
>>>>>>>>>> libcall!");
>>>>>>>>>> +  case MVT::f32:     LC = RTLIB::SINCOS_F32; break;
>>>>>>>>>> +  case MVT::f64:     LC = RTLIB::SINCOS_F64; break;
>>>>>>>>>> +  case MVT::f80:     LC = RTLIB::SINCOS_F80; break;
>>>>>>>>>> +  case MVT::f128:    LC = RTLIB::SINCOS_F128; break;
>>>>>>>>>> +  case MVT::ppcf128: LC = RTLIB::SINCOS_PPCF128; break;
>>>>>>>>>> +  }
>>>>>>>>>> +  return TLI.getLibcallName(LC) != 0;
>>>>>>>>>> +}
>>>>>>>>>> +
>>>>>>>>>> +/// useSinCos - Only issue sincos libcall if both sin and
>>>>>>>>>> cos
>>>>>>>>>> are
>>>>>>>>>> +/// needed.
>>>>>>>>>> +static bool useSinCos(SDNode *Node) {
>>>>>>>>>> +  unsigned OtherOpcode = Node->getOpcode() == ISD::FSIN
>>>>>>>>>> +    ? ISD::FCOS : ISD::FSIN;
>>>>>>>>>> +
>>>>>>>>>> +  SDValue Op0 = Node->getOperand(0);
>>>>>>>>>> +  for (SDNode::use_iterator UI =
>>>>>>>>>> Op0.getNode()->use_begin(),
>>>>>>>>>> +       UE = Op0.getNode()->use_end(); UI != UE; ++UI) {
>>>>>>>>>> +    SDNode *User = *UI;
>>>>>>>>>> +    if (User == Node)
>>>>>>>>>> +      continue;
>>>>>>>>>> +    // The other user might have been turned into sincos
>>>>>>>>>> already.
>>>>>>>>>> +    if (User->getOpcode() == OtherOpcode ||
>>>>>>>>>> User->getOpcode()
>>>>>>>>>> ==
>>>>>>>>>> ISD::FSINCOS)
>>>>>>>>>> +      return true;
>>>>>>>>>> +  }
>>>>>>>>>> +  return false;
>>>>>>>>>> +}
>>>>>>>>>> +
>>>>>>>>>> +/// ExpandSinCosLibCall - Issue libcalls to sincos to
>>>>>>>>>> compute
>>>>>>>>>> sin
>>>>>>>>>> /
>>>>>>>>>> cos
>>>>>>>>>> +/// pairs.
>>>>>>>>>> +void
>>>>>>>>>> +SelectionDAGLegalize::ExpandSinCosLibCall(SDNode *Node,
>>>>>>>>>> +
>>>>>>>>>>                                       SmallVectorImpl<SDValue>
>>>>>>>>>> &Results) {
>>>>>>>>>> +  RTLIB::Libcall LC;
>>>>>>>>>> +  switch (Node->getValueType(0).getSimpleVT().SimpleTy) {
>>>>>>>>>> +  default: llvm_unreachable("Unexpected request for
>>>>>>>>>> libcall!");
>>>>>>>>>> +  case MVT::f32:     LC = RTLIB::SINCOS_F32; break;
>>>>>>>>>> +  case MVT::f64:     LC = RTLIB::SINCOS_F64; break;
>>>>>>>>>> +  case MVT::f80:     LC = RTLIB::SINCOS_F80; break;
>>>>>>>>>> +  case MVT::f128:    LC = RTLIB::SINCOS_F128; break;
>>>>>>>>>> +  case MVT::ppcf128: LC = RTLIB::SINCOS_PPCF128; break;
>>>>>>>>>> +  }
>>>>>>>>>> +
>>>>>>>>>> +  // The input chain to this libcall is the entry node of
>>>>>>>>>> the
>>>>>>>>>> function.
>>>>>>>>>> +  // Legalizing the call will automatically add the
>>>>>>>>>> previous
>>>>>>>>>> call
>>>>>>>>>> to
>>>>>>>>>> the
>>>>>>>>>> +  // dependence.
>>>>>>>>>> +  SDValue InChain = DAG.getEntryNode();
>>>>>>>>>> +
>>>>>>>>>> +  EVT RetVT = Node->getValueType(0);
>>>>>>>>>> +  Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext());
>>>>>>>>>> +
>>>>>>>>>> +  TargetLowering::ArgListTy Args;
>>>>>>>>>> +  TargetLowering::ArgListEntry Entry;
>>>>>>>>>> +
>>>>>>>>>> +  // Pass the argument.
>>>>>>>>>> +  Entry.Node = Node->getOperand(0);
>>>>>>>>>> +  Entry.Ty = RetTy;
>>>>>>>>>> +  Entry.isSExt = false;
>>>>>>>>>> +  Entry.isZExt = false;
>>>>>>>>>> +  Args.push_back(Entry);
>>>>>>>>>> +
>>>>>>>>>> +  // Pass the return address of sin.
>>>>>>>>>> +  SDValue SinPtr = DAG.CreateStackTemporary(RetVT);
>>>>>>>>>> +  Entry.Node = SinPtr;
>>>>>>>>>> +  Entry.Ty = RetTy->getPointerTo();
>>>>>>>>>> +  Entry.isSExt = false;
>>>>>>>>>> +  Entry.isZExt = false;
>>>>>>>>>> +  Args.push_back(Entry);
>>>>>>>>>> +
>>>>>>>>>> +  // Also pass the return address of the cos.
>>>>>>>>>> +  SDValue CosPtr = DAG.CreateStackTemporary(RetVT);
>>>>>>>>>> +  Entry.Node = CosPtr;
>>>>>>>>>> +  Entry.Ty = RetTy->getPointerTo();
>>>>>>>>>> +  Entry.isSExt = false;
>>>>>>>>>> +  Entry.isZExt = false;
>>>>>>>>>> +  Args.push_back(Entry);
>>>>>>>>>> +
>>>>>>>>>> +  SDValue Callee =
>>>>>>>>>> DAG.getExternalSymbol(TLI.getLibcallName(LC),
>>>>>>>>>> +
>>>>>>>>>>                                        TLI.getPointerTy());
>>>>>>>>>> +
>>>>>>>>>> +  DebugLoc dl = Node->getDebugLoc();
>>>>>>>>>> +  TargetLowering::
>>>>>>>>>> +  CallLoweringInfo CLI(InChain,
>>>>>>>>>> Type::getVoidTy(*DAG.getContext()),
>>>>>>>>>> +                       false, false, false, false,
>>>>>>>>>> +                       0, TLI.getLibcallCallingConv(LC),
>>>>>>>>>> /*isTailCall=*/false,
>>>>>>>>>> +                       /*doesNotReturn=*/false,
>>>>>>>>>> /*isReturnValueUsed=*/true,
>>>>>>>>>> +                       Callee, Args, DAG, dl);
>>>>>>>>>> +  std::pair<SDValue, SDValue> CallInfo =
>>>>>>>>>> TLI.LowerCallTo(CLI);
>>>>>>>>>> +
>>>>>>>>>> +  Results.push_back(DAG.getLoad(RetVT, dl, CallInfo.second,
>>>>>>>>>> SinPtr,
>>>>>>>>>> +                                MachinePointerInfo(),
>>>>>>>>>> false,
>>>>>>>>>> false,
>>>>>>>>>> false, 0));
>>>>>>>>>> +  Results.push_back(DAG.getLoad(RetVT, dl, CallInfo.second,
>>>>>>>>>> CosPtr,
>>>>>>>>>> +                                MachinePointerInfo(),
>>>>>>>>>> false,
>>>>>>>>>> false,
>>>>>>>>>> false, 0));
>>>>>>>>>> +}
>>>>>>>>>> +
>>>>>>>>>> /// ExpandLegalINT_TO_FP - This function is responsible for
>>>>>>>>>> legalizing a
>>>>>>>>>> /// INT_TO_FP operation of the specified operand when the
>>>>>>>>>> target
>>>>>>>>>> requests that
>>>>>>>>>> /// we expand it.  At this point, we know that the result
>>>>>>>>>> and
>>>>>>>>>> operand types are
>>>>>>>>>> @@ -3041,14 +3143,33 @@ void
>>>>>>>>>> SelectionDAGLegalize::ExpandNode(SD
>>>>>>>>>>                                    RTLIB::SQRT_PPCF128));
>>>>>>>>>>  break;
>>>>>>>>>> case ISD::FSIN:
>>>>>>>>>> -    Results.push_back(ExpandFPLibCall(Node, RTLIB::SIN_F32,
>>>>>>>>>> RTLIB::SIN_F64,
>>>>>>>>>> -                                      RTLIB::SIN_F80,
>>>>>>>>>> RTLIB::SIN_F128,
>>>>>>>>>> -                                      RTLIB::SIN_PPCF128));
>>>>>>>>>> -    break;
>>>>>>>>>> -  case ISD::FCOS:
>>>>>>>>>> -    Results.push_back(ExpandFPLibCall(Node, RTLIB::COS_F32,
>>>>>>>>>> RTLIB::COS_F64,
>>>>>>>>>> -                                      RTLIB::COS_F80,
>>>>>>>>>> RTLIB::COS_F128,
>>>>>>>>>> -                                      RTLIB::COS_PPCF128));
>>>>>>>>>> +  case ISD::FCOS: {
>>>>>>>>>> +    EVT VT = Node->getValueType(0);
>>>>>>>>>> +    bool isSIN = Node->getOpcode() == ISD::FSIN;
>>>>>>>>>> +    // Turn fsin / fcos into ISD::FSINCOS node if there are
>>>>>>>>>> a
>>>>>>>>>> pair
>>>>>>>>>> of fsin /
>>>>>>>>>> +    // fcos which share the same operand and both are used.
>>>>>>>>>> +    if ((TLI.isOperationLegalOrCustom(ISD::FSINCOS, VT) ||
>>>>>>>>>> +         isSinCosLibcallAvailable(Node, TLI))
>>>>>>>>>> +        && useSinCos(Node)) {
>>>>>>>>>> +      SDVTList VTs = DAG.getVTList(VT, VT);
>>>>>>>>>> +      Tmp1 = DAG.getNode(ISD::FSINCOS, dl, VTs,
>>>>>>>>>> Node->getOperand(0));
>>>>>>>>>> +      if (!isSIN)
>>>>>>>>>> +        Tmp1 = Tmp1.getValue(1);
>>>>>>>>>> +      Results.push_back(Tmp1);
>>>>>>>>>> +    } else if (isSIN) {
>>>>>>>>>> +      Results.push_back(ExpandFPLibCall(Node,
>>>>>>>>>> RTLIB::SIN_F32,
>>>>>>>>>> RTLIB::SIN_F64,
>>>>>>>>>> +                                        RTLIB::SIN_F80,
>>>>>>>>>> RTLIB::SIN_F128,
>>>>>>>>>> +
>>>>>>>>>>                                       RTLIB::SIN_PPCF128));
>>>>>>>>>> +    } else {
>>>>>>>>>> +      Results.push_back(ExpandFPLibCall(Node,
>>>>>>>>>> RTLIB::COS_F32,
>>>>>>>>>> RTLIB::COS_F64,
>>>>>>>>>> +                                        RTLIB::COS_F80,
>>>>>>>>>> RTLIB::COS_F128,
>>>>>>>>>> +
>>>>>>>>>>                                       RTLIB::COS_PPCF128));
>>>>>>>>>> +    }
>>>>>>>>>> +    break;
>>>>>>>>>> +  }
>>>>>>>>>> +  case ISD::FSINCOS:
>>>>>>>>>> +    // Expand into sincos libcall.
>>>>>>>>>> +    ExpandSinCosLibCall(Node, Results);
>>>>>>>>>>  break;
>>>>>>>>>> case ISD::FLOG:
>>>>>>>>>>  Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG_F32,
>>>>>>>>>>  RTLIB::LOG_F64,
>>>>>>>>>> @@ -3181,7 +3302,6 @@ void
>>>>>>>>>> SelectionDAGLegalize::ExpandNode(SD
>>>>>>>>>> case ISD::UREM:
>>>>>>>>>> case ISD::SREM: {
>>>>>>>>>>  EVT VT = Node->getValueType(0);
>>>>>>>>>> -    SDVTList VTs = DAG.getVTList(VT, VT);
>>>>>>>>>>  bool isSigned = Node->getOpcode() == ISD::SREM;
>>>>>>>>>>  unsigned DivOpc = isSigned ? ISD::SDIV : ISD::UDIV;
>>>>>>>>>>  unsigned DivRemOpc = isSigned ? ISD::SDIVREM :
>>>>>>>>>>  ISD::UDIVREM;
>>>>>>>>>> @@ -3192,6 +3312,7 @@ void
>>>>>>>>>> SelectionDAGLegalize::ExpandNode(SD
>>>>>>>>>>       // If div is legal, it's better to do the normal
>>>>>>>>>>       expansion
>>>>>>>>>>       !TLI.isOperationLegalOrCustom(DivOpc,
>>>>>>>>>>       Node->getValueType(0)) &&
>>>>>>>>>>       useDivRem(Node, isSigned, false))) {
>>>>>>>>>> +      SDVTList VTs = DAG.getVTList(VT, VT);
>>>>>>>>>>    Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Tmp2,
>>>>>>>>>>    Tmp3).getValue(1);
>>>>>>>>>>  } else if (TLI.isOperationLegalOrCustom(DivOpc, VT)) {
>>>>>>>>>>    // X % Y -> X-X/Y*Y
>>>>>>>>>> 
>>>>>>>>>> Modified:
>>>>>>>>>> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> ---
>>>>>>>>>> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
>>>>>>>>>> (original)
>>>>>>>>>> +++
>>>>>>>>>> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp
>>>>>>>>>> Mon
>>>>>>>>>> Jan 28 20:32:37 2013
>>>>>>>>>> @@ -140,6 +140,7 @@ std::string SDNode::getOperationName(con
>>>>>>>>>> case ISD::FSQRT:                      return "fsqrt";
>>>>>>>>>> case ISD::FSIN:                       return "fsin";
>>>>>>>>>> case ISD::FCOS:                       return "fcos";
>>>>>>>>>> +  case ISD::FSINCOS:                    return "fsincos";
>>>>>>>>>> case ISD::FTRUNC:                     return "ftrunc";
>>>>>>>>>> case ISD::FFLOOR:                     return "ffloor";
>>>>>>>>>> case ISD::FCEIL:                      return "fceil";
>>>>>>>>>> 
>>>>>>>>>> Modified: llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp (original)
>>>>>>>>>> +++ llvm/trunk/lib/CodeGen/TargetLoweringBase.cpp Mon Jan 28
>>>>>>>>>> 20:32:37
>>>>>>>>>> 2013
>>>>>>>>>> @@ -340,6 +340,13 @@ static void InitLibcallNames(const char
>>>>>>>>>> Names[RTLIB::SYNC_FETCH_AND_NAND_2] =
>>>>>>>>>> "__sync_fetch_and_nand_2";
>>>>>>>>>> Names[RTLIB::SYNC_FETCH_AND_NAND_4] =
>>>>>>>>>> "__sync_fetch_and_nand_4";
>>>>>>>>>> Names[RTLIB::SYNC_FETCH_AND_NAND_8] =
>>>>>>>>>> "__sync_fetch_and_nand_8";
>>>>>>>>>> +
>>>>>>>>>> +  // These are generally not available.
>>>>>>>>>> +  Names[RTLIB::SINCOS_F32] = 0;
>>>>>>>>>> +  Names[RTLIB::SINCOS_F64] = 0;
>>>>>>>>>> +  Names[RTLIB::SINCOS_F80] = 0;
>>>>>>>>>> +  Names[RTLIB::SINCOS_F128] = 0;
>>>>>>>>>> +  Names[RTLIB::SINCOS_PPCF128] = 0;
>>>>>>>>>> }
>>>>>>>>>> 
>>>>>>>>>> /// InitLibcallCallingConvs - Set default libcall
>>>>>>>>>> CallingConvs.
>>>>>>>>>> 
>>>>>>>>>> Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
>>>>>>>>>> +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Jan 28
>>>>>>>>>> 20:32:37
>>>>>>>>>> 2013
>>>>>>>>>> @@ -781,6 +781,8 @@ ARMTargetLowering::ARMTargetLowering(Tar
>>>>>>>>>> setOperationAction(ISD::FSIN,      MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FCOS,      MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FCOS,      MVT::f64, Expand);
>>>>>>>>>> +  setOperationAction(ISD::FSINCOS,   MVT::f64, Expand);
>>>>>>>>>> +  setOperationAction(ISD::FSINCOS,   MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FREM,      MVT::f64, Expand);
>>>>>>>>>> setOperationAction(ISD::FREM,      MVT::f32, Expand);
>>>>>>>>>> if (!TM.Options.UseSoftFloat && Subtarget->hasVFP2() &&
>>>>>>>>>> 
>>>>>>>>>> Modified:
>>>>>>>>>> llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
>>>>>>>>>> (original)
>>>>>>>>>> +++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp
>>>>>>>>>> Mon
>>>>>>>>>> Jan
>>>>>>>>>> 28
>>>>>>>>>> 20:32:37 2013
>>>>>>>>>> @@ -1364,6 +1364,8 @@
>>>>>>>>>> HexagonTargetLowering::HexagonTargetLowe
>>>>>>>>>>  setOperationAction(ISD::FSIN , MVT::f32, Expand);
>>>>>>>>>>  setOperationAction(ISD::FCOS , MVT::f32, Expand);
>>>>>>>>>>  setOperationAction(ISD::FREM , MVT::f32, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
>>>>>>>>>>  setOperationAction(ISD::CTPOP, MVT::i32, Expand);
>>>>>>>>>>  setOperationAction(ISD::CTTZ , MVT::i32, Expand);
>>>>>>>>>>  setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32,
>>>>>>>>>>  Expand);
>>>>>>>>>> 
>>>>>>>>>> Modified:
>>>>>>>>>> llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp
>>>>>>>>>> (original)
>>>>>>>>>> +++ llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp Mon
>>>>>>>>>> Jan
>>>>>>>>>> 28
>>>>>>>>>> 20:32:37 2013
>>>>>>>>>> @@ -81,6 +81,7 @@ MBlazeTargetLowering::MBlazeTargetLoweri
>>>>>>>>>> setOperationAction(ISD::FCOPYSIGN,  MVT::f64, Expand);
>>>>>>>>>> setOperationAction(ISD::FSIN,       MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FCOS,       MVT::f32, Expand);
>>>>>>>>>> +  setOperationAction(ISD::FSINCOS,    MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FPOWI,      MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FPOW,       MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FLOG,       MVT::f32, Expand);
>>>>>>>>>> 
>>>>>>>>>> Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp
>>>>>>>>>> (original)
>>>>>>>>>> +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon Jan
>>>>>>>>>> 28
>>>>>>>>>> 20:32:37 2013
>>>>>>>>>> @@ -421,6 +421,8 @@ MipsTargetLowering(MipsTargetMachine &TM
>>>>>>>>>> setOperationAction(ISD::FSIN,              MVT::f64,
>>>>>>>>>>  Expand);
>>>>>>>>>> setOperationAction(ISD::FCOS,              MVT::f32,
>>>>>>>>>>  Expand);
>>>>>>>>>> setOperationAction(ISD::FCOS,              MVT::f64,
>>>>>>>>>>  Expand);
>>>>>>>>>> +  setOperationAction(ISD::FSINCOS,           MVT::f32,
>>>>>>>>>> Expand);
>>>>>>>>>> +  setOperationAction(ISD::FSINCOS,           MVT::f64,
>>>>>>>>>> Expand);
>>>>>>>>>> setOperationAction(ISD::FPOWI,             MVT::f32,
>>>>>>>>>>  Expand);
>>>>>>>>>> setOperationAction(ISD::FPOW,              MVT::f32,
>>>>>>>>>>  Expand);
>>>>>>>>>> setOperationAction(ISD::FPOW,              MVT::f64,
>>>>>>>>>>  Expand);
>>>>>>>>>> 
>>>>>>>>>> Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
>>>>>>>>>> (original)
>>>>>>>>>> +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Mon
>>>>>>>>>> Jan
>>>>>>>>>> 28
>>>>>>>>>> 20:32:37 2013
>>>>>>>>>> @@ -132,11 +132,13 @@
>>>>>>>>>> PPCTargetLowering::PPCTargetLowering(PPC
>>>>>>>>>> // We don't support sin/cos/sqrt/fmod/pow
>>>>>>>>>> setOperationAction(ISD::FSIN , MVT::f64, Expand);
>>>>>>>>>> setOperationAction(ISD::FCOS , MVT::f64, Expand);
>>>>>>>>>> +  setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
>>>>>>>>>> setOperationAction(ISD::FREM , MVT::f64, Expand);
>>>>>>>>>> setOperationAction(ISD::FPOW , MVT::f64, Expand);
>>>>>>>>>> setOperationAction(ISD::FMA  , MVT::f64, Legal);
>>>>>>>>>> setOperationAction(ISD::FSIN , MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FCOS , MVT::f32, Expand);
>>>>>>>>>> +  setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FREM , MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FPOW , MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FMA  , MVT::f32, Legal);
>>>>>>>>>> 
>>>>>>>>>> Modified: llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp
>>>>>>>>>> (original)
>>>>>>>>>> +++ llvm/trunk/lib/Target/Sparc/SparcISelLowering.cpp Mon
>>>>>>>>>> Jan
>>>>>>>>>> 28
>>>>>>>>>> 20:32:37 2013
>>>>>>>>>> @@ -759,10 +759,12 @@
>>>>>>>>>> SparcTargetLowering::SparcTargetLowering
>>>>>>>>>> 
>>>>>>>>>> setOperationAction(ISD::FSIN , MVT::f64, Expand);
>>>>>>>>>> setOperationAction(ISD::FCOS , MVT::f64, Expand);
>>>>>>>>>> +  setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
>>>>>>>>>> setOperationAction(ISD::FREM , MVT::f64, Expand);
>>>>>>>>>> setOperationAction(ISD::FMA  , MVT::f64, Expand);
>>>>>>>>>> setOperationAction(ISD::FSIN , MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FCOS , MVT::f32, Expand);
>>>>>>>>>> +  setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FREM , MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::FMA  , MVT::f32, Expand);
>>>>>>>>>> setOperationAction(ISD::CTPOP, MVT::i32, Expand);
>>>>>>>>>> 
>>>>>>>>>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
>>>>>>>>>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Jan 28
>>>>>>>>>> 20:32:37
>>>>>>>>>> 2013
>>>>>>>>>> @@ -605,10 +605,12 @@
>>>>>>>>>> X86TargetLowering::X86TargetLowering(X86
>>>>>>>>>>  setOperationAction(ISD::FGETSIGN, MVT::i32, Custom);
>>>>>>>>>> 
>>>>>>>>>>  // We don't support sin/cos/fmod
>>>>>>>>>> -    setOperationAction(ISD::FSIN , MVT::f64, Expand);
>>>>>>>>>> -    setOperationAction(ISD::FCOS , MVT::f64, Expand);
>>>>>>>>>> -    setOperationAction(ISD::FSIN , MVT::f32, Expand);
>>>>>>>>>> -    setOperationAction(ISD::FCOS , MVT::f32, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FSIN   , MVT::f64, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FCOS   , MVT::f64, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FSIN   , MVT::f32, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FCOS   , MVT::f32, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
>>>>>>>>>> 
>>>>>>>>>>  // Expand FP immediates into loads from the stack, except
>>>>>>>>>>  for
>>>>>>>>>>  the special
>>>>>>>>>>  // cases we handle.
>>>>>>>>>> @@ -633,8 +635,9 @@ X86TargetLowering::X86TargetLowering(X86
>>>>>>>>>>  setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
>>>>>>>>>> 
>>>>>>>>>>  // We don't support sin/cos/fmod
>>>>>>>>>> -    setOperationAction(ISD::FSIN , MVT::f32, Expand);
>>>>>>>>>> -    setOperationAction(ISD::FCOS , MVT::f32, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FSIN   , MVT::f32, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FCOS   , MVT::f32, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
>>>>>>>>>> 
>>>>>>>>>>  // Special cases we handle for FP constants.
>>>>>>>>>>  addLegalFPImmediate(APFloat(+0.0f)); // xorps
>>>>>>>>>> @@ -644,8 +647,9 @@ X86TargetLowering::X86TargetLowering(X86
>>>>>>>>>>  addLegalFPImmediate(APFloat(-1.0)); // FLD1/FCHS
>>>>>>>>>> 
>>>>>>>>>>  if (!TM.Options.UnsafeFPMath) {
>>>>>>>>>> -      setOperationAction(ISD::FSIN           , MVT::f64  ,
>>>>>>>>>> Expand);
>>>>>>>>>> -      setOperationAction(ISD::FCOS           , MVT::f64  ,
>>>>>>>>>> Expand);
>>>>>>>>>> +      setOperationAction(ISD::FSIN   , MVT::f64, Expand);
>>>>>>>>>> +      setOperationAction(ISD::FCOS   , MVT::f64, Expand);
>>>>>>>>>> +      setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
>>>>>>>>>>  }
>>>>>>>>>> } else if (!TM.Options.UseSoftFloat) {
>>>>>>>>>>  // f32 and f64 in x87.
>>>>>>>>>> @@ -659,10 +663,12 @@
>>>>>>>>>> X86TargetLowering::X86TargetLowering(X86
>>>>>>>>>>  setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
>>>>>>>>>> 
>>>>>>>>>>  if (!TM.Options.UnsafeFPMath) {
>>>>>>>>>> -      setOperationAction(ISD::FSIN           , MVT::f32  ,
>>>>>>>>>> Expand);
>>>>>>>>>> -      setOperationAction(ISD::FSIN           , MVT::f64  ,
>>>>>>>>>> Expand);
>>>>>>>>>> -      setOperationAction(ISD::FCOS           , MVT::f32  ,
>>>>>>>>>> Expand);
>>>>>>>>>> -      setOperationAction(ISD::FCOS           , MVT::f64  ,
>>>>>>>>>> Expand);
>>>>>>>>>> +      setOperationAction(ISD::FSIN   , MVT::f64, Expand);
>>>>>>>>>> +      setOperationAction(ISD::FSIN   , MVT::f32, Expand);
>>>>>>>>>> +      setOperationAction(ISD::FCOS   , MVT::f64, Expand);
>>>>>>>>>> +      setOperationAction(ISD::FCOS   , MVT::f32, Expand);
>>>>>>>>>> +      setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
>>>>>>>>>> +      setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
>>>>>>>>>>  }
>>>>>>>>>>  addLegalFPImmediate(APFloat(+0.0)); // FLD0
>>>>>>>>>>  addLegalFPImmediate(APFloat(+1.0)); // FLD1
>>>>>>>>>> @@ -699,8 +705,9 @@ X86TargetLowering::X86TargetLowering(X86
>>>>>>>>>>  }
>>>>>>>>>> 
>>>>>>>>>>  if (!TM.Options.UnsafeFPMath) {
>>>>>>>>>> -      setOperationAction(ISD::FSIN           , MVT::f80  ,
>>>>>>>>>> Expand);
>>>>>>>>>> -      setOperationAction(ISD::FCOS           , MVT::f80  ,
>>>>>>>>>> Expand);
>>>>>>>>>> +      setOperationAction(ISD::FSIN   , MVT::f80, Expand);
>>>>>>>>>> +      setOperationAction(ISD::FCOS   , MVT::f80, Expand);
>>>>>>>>>> +      setOperationAction(ISD::FSINCOS, MVT::f80, Expand);
>>>>>>>>>>  }
>>>>>>>>>> 
>>>>>>>>>>  setOperationAction(ISD::FFLOOR, MVT::f80, Expand);
>>>>>>>>>> @@ -748,7 +755,9 @@ X86TargetLowering::X86TargetLowering(X86
>>>>>>>>>>  setOperationAction(ISD::INSERT_SUBVECTOR, VT,Expand);
>>>>>>>>>>  setOperationAction(ISD::FABS, VT, Expand);
>>>>>>>>>>  setOperationAction(ISD::FSIN, VT, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FSINCOS, VT, Expand);
>>>>>>>>>>  setOperationAction(ISD::FCOS, VT, Expand);
>>>>>>>>>> +    setOperationAction(ISD::FSINCOS, VT, Expand);
>>>>>>>>>>  setOperationAction(ISD::FREM, VT, Expand);
>>>>>>>>>>  setOperationAction(ISD::FMA,  VT, Expand);
>>>>>>>>>>  setOperationAction(ISD::FPOWI, VT, Expand);
>>>>>>>>>> @@ -1281,6 +1290,19 @@
>>>>>>>>>> X86TargetLowering::X86TargetLowering(X86
>>>>>>>>>>  setLibcallName(RTLIB::SRA_I128, 0);
>>>>>>>>>> }
>>>>>>>>>> 
>>>>>>>>>> +  // Combine sin / cos into one node or libcall if
>>>>>>>>>> possible.
>>>>>>>>>> +  if (Subtarget->hasSinCos()) {
>>>>>>>>>> +    setLibcallName(RTLIB::SINCOS_F32, "sincosf");
>>>>>>>>>> +    setLibcallName(RTLIB::SINCOS_F64, "sincos");
>>>>>>>>>> +    if (Subtarget->isTargetDarwin() &&
>>>>>>>>>> Subtarget->is64Bit())
>>>>>>>>>> {
>>>>>>>>>> +      // For MacOSX, we don't want to the normal expansion
>>>>>>>>>> of
>>>>>>>>>> a
>>>>>>>>>> libcall to
>>>>>>>>>> +      // sincos. We want to issue a libcall to
>>>>>>>>>> __sincos_stret
>>>>>>>>>> to
>>>>>>>>>> avoid memory
>>>>>>>>>> +      // traffic.
>>>>>>>>>> +      setOperationAction(ISD::FSINCOS, MVT::f64, Custom);
>>>>>>>>>> +      setOperationAction(ISD::FSINCOS, MVT::f32, Custom);
>>>>>>>>>> +    }
>>>>>>>>>> +  }
>>>>>>>>>> +
>>>>>>>>>> // We have target-specific dag combine patterns for the
>>>>>>>>>> following
>>>>>>>>>> nodes:
>>>>>>>>>> setTargetDAGCombine(ISD::VECTOR_SHUFFLE);
>>>>>>>>>> setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT);
>>>>>>>>>> @@ -12014,6 +12036,50 @@ static SDValue
>>>>>>>>>> LowerADDC_ADDE_SUBC_SUBE(
>>>>>>>>>>                   Op.getOperand(1), Op.getOperand(2));
>>>>>>>>>> }
>>>>>>>>>> 
>>>>>>>>>> +SDValue X86TargetLowering::LowerFSINCOS(SDValue Op,
>>>>>>>>>> SelectionDAG
>>>>>>>>>> &DAG) const {
>>>>>>>>>> +  assert(Subtarget->isTargetDarwin());
>>>>>>>>>> +
>>>>>>>>>> +  // For MacOSX, we want to call an alternative entry
>>>>>>>>>> point:
>>>>>>>>>> __sincos_stret,
>>>>>>>>>> +  // which returns the values in two XMM registers.
>>>>>>>>>> +  DebugLoc dl = Op.getDebugLoc();
>>>>>>>>>> +  SDValue Arg = Op.getOperand(0);
>>>>>>>>>> +  EVT ArgVT = Arg.getValueType();
>>>>>>>>>> +  Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
>>>>>>>>>> +
>>>>>>>>>> +  ArgListTy Args;
>>>>>>>>>> +  ArgListEntry Entry;
>>>>>>>>>> +
>>>>>>>>>> +  Entry.Node = Arg;
>>>>>>>>>> +  Entry.Ty = ArgTy;
>>>>>>>>>> +  Entry.isSExt = false;
>>>>>>>>>> +  Entry.isZExt = false;
>>>>>>>>>> +  Args.push_back(Entry);
>>>>>>>>>> +
>>>>>>>>>> +  const char *LibcallName = (ArgVT == MVT::f64)
>>>>>>>>>> +    ? "__sincos_stret" : "__sincosf_stret";
>>>>>>>>>> +  SDValue Callee = DAG.getExternalSymbol(LibcallName,
>>>>>>>>>> getPointerTy());
>>>>>>>>>> +
>>>>>>>>>> +  StructType *RetTy = StructType::get(ArgTy, ArgTy, NULL);
>>>>>>>>>> +  TargetLowering::
>>>>>>>>>> +  CallLoweringInfo CLI(DAG.getEntryNode(), RetTy,
>>>>>>>>>> +                       false, false, false, false, 0,
>>>>>>>>>> +                       CallingConv::C,
>>>>>>>>>> /*isTaillCall=*/false,
>>>>>>>>>> +                       /*doesNotRet=*/false,
>>>>>>>>>> /*isReturnValueUsed*/true,
>>>>>>>>>> +                       Callee, Args, DAG, dl);
>>>>>>>>>> +  std::pair<SDValue, SDValue> CallResult =
>>>>>>>>>> LowerCallTo(CLI);
>>>>>>>>>> +#if 1
>>>>>>>>>> +  return CallResult.first;
>>>>>>>>>> +#else
>>>>>>>>>> +  SDValue RetSin = DAG.getNode(ISD::EXTRACT_ELEMENT, dl,
>>>>>>>>>> ArgVT,
>>>>>>>>>> +                               CallResult.first,
>>>>>>>>>> DAG.getIntPtrConstant(0));
>>>>>>>>>> +  SDValue RetCos = DAG.getNode(ISD::EXTRACT_ELEMENT, dl,
>>>>>>>>>> ArgVT,
>>>>>>>>>> +                               CallResult.first,
>>>>>>>>>> DAG.getIntPtrConstant(1));
>>>>>>>>>> +
>>>>>>>>>> +  SDVTList Tys = DAG.getVTList(ArgVT, ArgVT);
>>>>>>>>>> +  return DAG.getNode(ISD::MERGE_VALUES, dl, Tys, RetSin,
>>>>>>>>>> RetCos);
>>>>>>>>>> +#endif
>>>>>>>>>> +}
>>>>>>>>>> +
>>>>>>>>>> /// LowerOperation - Provide custom lowering hooks for some
>>>>>>>>>> operations.
>>>>>>>>>> ///
>>>>>>>>>> SDValue X86TargetLowering::LowerOperation(SDValue Op,
>>>>>>>>>> SelectionDAG
>>>>>>>>>> &DAG) const {
>>>>>>>>>> @@ -12096,6 +12162,7 @@ SDValue
>>>>>>>>>> X86TargetLowering::LowerOperatio
>>>>>>>>>> case ISD::ADD:                return LowerADD(Op, DAG);
>>>>>>>>>> case ISD::SUB:                return LowerSUB(Op, DAG);
>>>>>>>>>> case ISD::SDIV:               return LowerSDIV(Op, DAG);
>>>>>>>>>> +  case ISD::FSINCOS:            return LowerFSINCOS(Op,
>>>>>>>>>> DAG);
>>>>>>>>>> }
>>>>>>>>>> }
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
>>>>>>>>>> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Mon Jan 28
>>>>>>>>>> 20:32:37
>>>>>>>>>> 2013
>>>>>>>>>> @@ -838,8 +838,8 @@ namespace llvm {
>>>>>>>>>>  SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG)
>>>>>>>>>>  const;
>>>>>>>>>>  SDValue LowerShift(SDValue Op, SelectionDAG &DAG) const;
>>>>>>>>>>  SDValue LowerSDIV(SDValue Op, SelectionDAG &DAG) const;
>>>>>>>>>> -
>>>>>>>>>>  SDValue LowerSIGN_EXTEND_INREG(SDValue Op, SelectionDAG
>>>>>>>>>>  &DAG)
>>>>>>>>>>  const;
>>>>>>>>>> +    SDValue LowerFSINCOS(SDValue Op, SelectionDAG &DAG)
>>>>>>>>>> const;
>>>>>>>>>> 
>>>>>>>>>>  // Utility functions to help LowerVECTOR_SHUFFLE &
>>>>>>>>>>  LowerBUILD_VECTOR
>>>>>>>>>>  SDValue LowerVectorBroadcast(SDValue Op, SelectionDAG
>>>>>>>>>>  &DAG)
>>>>>>>>>>  const;
>>>>>>>>>> 
>>>>>>>>>> Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original)
>>>>>>>>>> +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Mon Jan 28
>>>>>>>>>> 20:32:37
>>>>>>>>>> 2013
>>>>>>>>>> @@ -155,6 +155,11 @@ const char
>>>>>>>>>> *X86Subtarget::getBZeroEntry(
>>>>>>>>>> return 0;
>>>>>>>>>> }
>>>>>>>>>> 
>>>>>>>>>> +bool X86Subtarget::hasSinCos() const {
>>>>>>>>>> +  return getTargetTriple().isMacOSX() &&
>>>>>>>>>> +    !getTargetTriple().isMacOSXVersionLT(10, 9);
>>>>>>>>>> +}
>>>>>>>>>> +
>>>>>>>>>> /// IsLegalToCallImmediateAddr - Return true if the
>>>>>>>>>> subtarget
>>>>>>>>>> allows
>>>>>>>>>> calls
>>>>>>>>>> /// to immediate address.
>>>>>>>>>> bool X86Subtarget::IsLegalToCallImmediateAddr(const
>>>>>>>>>> TargetMachine
>>>>>>>>>> &TM) const {
>>>>>>>>>> 
>>>>>>>>>> Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h
>>>>>>>>>> URL:
>>>>>>>>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=173755&r1=173754&r2=173755&view=diff
>>>>>>>>>> ==============================================================================
>>>>>>>>>> --- llvm/trunk/lib/Target/X86/X86Subtarget.h (original)
>>>>>>>>>> +++ llvm/trunk/lib/Target/X86/X86Subtarget.h Mon Jan 28
>>>>>>>>>> 20:32:37
>>>>>>>>>> 2013
>>>>>>>>>> @@ -328,6 +328,10 @@ public:
>>>>>>>>>> /// memset with zero passed as the second argument.
>>>>>>>>>> Otherwise
>>>>>>>>>> it
>>>>>>>>>> /// returns null.
>>>>>>>>>> const char *getBZeroEntry() const;
>>>>>>>>>> +
>>>>>>>>>> +  /// This function returns true if the target has sincos()
>>>>>>>>>> routine
>>>>>>>>>> in its
>>>>>>>>>> +  /// compiler runtime or math libraries.
>>>>>>>>>> +  bool hasSinCos() const;
>>>>>>>>>> 
>>>>>>>>>> /// enablePostRAScheduler - run for Atom optimization.
>>>>>>>>>> bool enablePostRAScheduler(CodeGenOpt::Level OptLevel,
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> _______________________________________________
>>>>>>>>>> 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
>>>>>> 
>>>>> _______________________________________________
>>>>> 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