[llvm] r173755 - Teach SDISel to combine fsin / fcos into a fsincos node if the following
Evan Cheng
evan.cheng at apple.com
Mon Jan 28 21:04:22 PST 2013
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.
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
>>
More information about the llvm-commits
mailing list