[llvm] r173755 - Teach SDISel to combine fsin / fcos into a fsincos node if the following
Nadav Rotem
nrotem at apple.com
Thu Jan 31 15:53:55 PST 2013
Evan,
I am getting this error on Cab. It only happens after 173755 and it still happens on ToT.
/Users/nadav/devel/build/Debug+Asserts/bin/clang++ -o Output/462.libquantum.simple Output/classic.llvm.o Output/complex.llvm.o Output/decoherence.llvm.o Output/expn.llvm.o Output/gates.llvm.o Output/matrix.llvm.o Output/measure.llvm.o Output/oaddn.llvm.o Output/objcode.llvm.o Output/omuln.llvm.o Output/qec.llvm.o Output/qft.llvm.o Output/qureg.llvm.o Output/shor.llvm.o Output/specrand.llvm.o Output/version.llvm.o -lm
Undefined symbols for architecture x86_64:
"___sincos_stret", referenced from:
_quantum_cexp in complex.llvm.o
_quantum_r_x in gates.llvm.o
_quantum_r_y in gates.llvm.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: [Output/462.libquantum.simple] Error 1 (ignored)
Thanks,
Nadav
On Jan 28, 2013, at 6:32 PM, Evan Cheng <evan.cheng at apple.com> wrote:
> 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
More information about the llvm-commits
mailing list