[llvm] r173755 - Teach SDISel to combine fsin / fcos into a fsincos node if the following
Benjamin Kramer
benny.kra at gmail.com
Mon Feb 4 10:05:03 PST 2013
On 01.02.2013, at 16:58, "Redmond, Paul" <paul.redmond at intel.com> wrote:
> Thanks for the feedback Hal!
>
> Attached is an updated patch which generally enables the sincos optimization for GNU environments.
Just a note: if we can figure out how the ABI is on the platform it may be better to generate a call to cexp, which returns a complex integer instead of indirection through pointers. That should be equivalent to the sincos_stret trick darwin uses.
- Ben
>
> 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
>>>
>>>
>
> <sincos_opt_gnu2.diff>_______________________________________________
> 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