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

Hal Finkel hfinkel at anl.gov
Fri Feb 1 12:27:39 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 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