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

Evan Cheng evan.cheng at apple.com
Mon Feb 4 10:31:08 PST 2013


Just to be clear. I only implemented the optimization for Darwin where it is guaranteed safe. If UnsafeFPMath is required for GNU environments then I agree a target hook is required.

Evan

On Feb 1, 2013, at 12:27 PM, Hal Finkel <hfinkel at anl.gov> 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 2:17:43 PM
>> Subject: Re: [llvm] r173755 - Teach SDISel to combine fsin / fcos into a	fsincos	node if the following
>> 
>> 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.
> 
> Good point.
> 
>> 
>> Any suggestions?
> 
> Add TLI.isFPMathLibcallUnsafe(LC) and use that in conjuction with the UnsafeFPMath check. This seems generally useful.
> 
> Thanks again,
> Hal
> 
>> 
>> 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