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

Redmond, Paul paul.redmond at intel.com
Fri Feb 1 07:58:39 PST 2013


Thanks for the feedback Hal!

Attached is an updated patch which generally enables the sincos optimization for GNU environments.

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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: sincos_opt_gnu2.diff
Type: application/octet-stream
Size: 5296 bytes
Desc: sincos_opt_gnu2.diff
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130201/8ce813ed/attachment.obj>


More information about the llvm-commits mailing list