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

Hal Finkel hfinkel at anl.gov
Mon Jan 28 21:24:58 PST 2013


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

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



More information about the llvm-commits mailing list