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

Hal Finkel hfinkel at anl.gov
Fri Feb 1 11:50:26 PST 2013


----- 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";

 -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