[llvm] r178480 - Add more PPC floating-point conversion instructions

Hal Finkel hfinkel at anl.gov
Mon Apr 1 20:33:24 PDT 2013



----- Original Message -----
> From: "Bill Schmidt" <wschmidt at linux.vnet.ibm.com>
> To: "Hal Finkel" <hfinkel at anl.gov>
> Cc: llvm-commits at cs.uiuc.edu
> Sent: Monday, April 1, 2013 7:40:09 PM
> Subject: Re: [llvm] r178480 - Add more PPC floating-point conversion instructions
> 
> Hi Hal,
> 
> On Mon, 2013-04-01 at 17:52 +0000, Hal Finkel wrote:
> > Author: hfinkel
> > Date: Mon Apr  1 12:52:07 2013
> > New Revision: 178480
> > 
> > URL: http://llvm.org/viewvc/llvm-project?rev=178480&view=rev
> > Log:
> > Add more PPC floating-point conversion instructions
> > 
> > The P7 and A2 have additional floating-point conversion
> > instructions which
> > allow a direct two-instruction sequence (plus load/store) to
> > convert from all
> > combinations (signed/unsigned i32/i64) <--> (float/double) (on
> > previous cores,
> > only some combinations were directly available).
> > 
> > Added:
> >     llvm/trunk/test/CodeGen/PowerPC/float-to-int.ll
> >     llvm/trunk/test/CodeGen/PowerPC/i64-to-float.ll
> > Modified:
> >     llvm/trunk/lib/Target/PowerPC/PPC.td
> >     llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
> >     llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
> >     llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
> >     llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
> >     llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp
> >     llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h
> >     llvm/trunk/test/CodeGen/PowerPC/i32-to-float.ll
> >     llvm/trunk/test/CodeGen/PowerPC/i64_fp_round.ll
> >     llvm/trunk/test/CodeGen/PowerPC/stfiwx-2.ll
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPC.td
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPC.td?rev=178480&r1=178479&r2=178480&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPC.td (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPC.td Mon Apr  1 12:52:07 2013
> > @@ -63,6 +63,8 @@ def FeatureLFIWAX    : SubtargetFeature<
> >                                          "Enable the lfiwax
> >                                          instruction">;
> >  def FeatureFPRND     : SubtargetFeature<"fprnd", "HasFPRND",
> >  "true",
> >                                          "Enable the fri[mnpz]
> >                                          instructions">;
> > +def FeatureFPCVT     : SubtargetFeature<"fpcvt", "HasFPCVT",
> > "true",
> > +  "Enable fc[ft]* (unsigned and single-precision) and lfiwzx
> > instructions">;
> >  def FeatureISEL      : SubtargetFeature<"isel","HasISEL", "true",
> >                                          "Enable the isel
> >                                          instruction">;
> >  def FeaturePOPCNTD   : SubtargetFeature<"popcntd","HasPOPCNTD",
> >  "true",
> > @@ -79,10 +81,8 @@ def FeatureQPX       : SubtargetFeature<
> >  //
> >  // CMPB         p6, p6x, p7        cmpb
> >  // DFP          p6, p6x, p7        decimal floating-point
> >  instructions
> > -// FLT_CVT      p7                 fcfids, fcfidu, fcfidus,
> > fcfiduz, fctiwuz
> >  // FRE          p5 through p7      fre (vs. fres, available since
> >  p3)
> >  // FRSQRTES     p5 through p7      frsqrtes (vs. frsqrte,
> >  available since p3)
> > -// LFIWZX       p7                 lfiwzx
> >  // POPCNTB      p5 through p7      popcntb and related
> >  instructions
> >  // RECIP_PREC   p6, p6x, p7        higher precision reciprocal
> >  estimates
> >  // VSX          p7                 vector-scalar instruction set
> > @@ -135,14 +135,15 @@ def : ProcessorModel<"e5500", PPCE5500Mo
> >  def : Processor<"a2", PPCA2Itineraries,
> >                    [DirectiveA2, FeatureBookE, FeatureMFOCRF,
> >                     FeatureFSqrt, FeatureSTFIWX, FeatureLFIWAX,
> > -                   FeatureFPRND, FeatureISEL, FeaturePOPCNTD,
> > -                   FeatureLDBRX, Feature64Bit /*, Feature64BitRegs
> > */]>;
> > +                   FeatureFPRND, FeatureFPCVT, FeatureISEL,
> > +                   FeaturePOPCNTD, FeatureLDBRX, Feature64Bit
> > +               /*, Feature64BitRegs */]>;
> >  def : Processor<"a2q", PPCA2Itineraries,
> >                    [DirectiveA2, FeatureBookE, FeatureMFOCRF,
> >                     FeatureFSqrt, FeatureSTFIWX, FeatureLFIWAX,
> > -                   FeatureFPRND, FeatureISEL, FeaturePOPCNTD,
> > -                   FeatureLDBRX, Feature64Bit /*, Feature64BitRegs
> > */,
> > -                   FeatureQPX]>;
> > +                   FeatureFPRND, FeatureFPCVT, FeatureISEL,
> > +                   FeaturePOPCNTD, FeatureLDBRX, Feature64Bit
> > +               /*, Feature64BitRegs */, FeatureQPX]>;
> >  def : Processor<"pwr3", G5Itineraries,
> >                    [DirectivePwr3, FeatureAltivec, FeatureMFOCRF,
> >                     FeatureSTFIWX, Feature64Bit]>;
> > @@ -168,9 +169,9 @@ def : Processor<"pwr6x", G5Itineraries,
> >  def : Processor<"pwr7", G5Itineraries,
> >                    [DirectivePwr7, FeatureAltivec,
> >                     FeatureMFOCRF, FeatureFSqrt, FeatureSTFIWX,
> > -                   FeatureLFIWAX, FeatureFPRND, FeatureISEL,
> > -                   FeaturePOPCNTD, FeatureLDBRX, Feature64Bit
> > -               /*, Feature64BitRegs */]>;
> > +                   FeatureLFIWAX, FeatureFPRND, FeatureFPCVT,
> > +                   FeatureISEL, FeaturePOPCNTD, FeatureLDBRX,
> > +                   Feature64Bit /*, Feature64BitRegs */]>;
> >  def : Processor<"ppc", G3Itineraries, [Directive32]>;
> >  def : Processor<"ppc64", G5Itineraries,
> >                    [Directive64, FeatureAltivec,
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=178480&r1=178479&r2=178480&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Mon Apr  1
> > 12:52:07 2013
> > @@ -326,13 +326,28 @@ PPCTargetLowering::PPCTargetLowering(PPC
> >      // We cannot do this with Promote because i64 is not a legal
> >      type.
> >      setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
> > 
> > -    if (Subtarget->isPPC64())
> > +    if (PPCSubTarget.hasLFIWAX() || Subtarget->isPPC64())
> >        setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
> >    } else {
> >      // PowerPC does not have FP_TO_UINT on 32-bit implementations.
> >      setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
> >    }
> > 
> > +  // With the instructions enabled under FPCVT, we can do
> > everything.
> > +  if (PPCSubTarget.hasFPCVT()) {
> > +    if (Subtarget->has64BitSupport()) {
> > +      setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
> > +      setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom);
> > +      setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom);
> > +      setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom);
> > +    }
> > +
> > +    setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
> > +    setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom);
> > +    setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom);
> > +    setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom);
> > +  }
> > +
> >    if (Subtarget->use64BitRegs()) {
> >      // 64-bit PowerPC implementations can support i64 types
> >      directly
> >      addRegisterClass(MVT::i64, &PPC::G8RCRegClass);
> > @@ -4716,37 +4731,72 @@ SDValue PPCTargetLowering::LowerFP_TO_IN
> >    default: llvm_unreachable("Unhandled FP_TO_INT type in custom
> >    expander!");
> >    case MVT::i32:
> >      Tmp = DAG.getNode(Op.getOpcode()==ISD::FP_TO_SINT ?
> >      PPCISD::FCTIWZ :
> > -
> >                                                         PPCISD::FCTIDZ,
> > +                        (PPCSubTarget.hasFPCVT() ? PPCISD::FCTIWUZ
> > :
> > +
> >                                                   PPCISD::FCTIDZ),
> >                        dl, MVT::f64, Src);
> >      break;
> >    case MVT::i64:
> > -    Tmp = DAG.getNode(PPCISD::FCTIDZ, dl, MVT::f64, Src);
> > +    assert((Op.getOpcode() == ISD::SINT_TO_FP ||
> > PPCSubTarget.hasFPCVT()) &&
> > +           "i64 UINT_TO_FP is supported only with FPCVT");
> > +    Tmp = DAG.getNode(Op.getOpcode()==ISD::FP_TO_SINT ?
> > PPCISD::FCTIDZ :
> > +
> >                                                        PPCISD::FCTIDUZ,
> > +                      dl, MVT::f64, Src);
> >      break;
> >    }
> > 
> >    // Convert the FP value to an int value through memory.
> > -  SDValue FIPtr = DAG.CreateStackTemporary(MVT::f64);
> > +  bool i32Stack = Op.getValueType() == MVT::i32 &&
> > PPCSubTarget.hasSTFIWX() &&
> > +    (Op.getOpcode() == ISD::FP_TO_SINT ||
> > PPCSubTarget.hasFPCVT());
> > +  SDValue FIPtr = DAG.CreateStackTemporary(i32Stack ? MVT::i32 :
> > MVT::f64);
> > +  int FI = cast<FrameIndexSDNode>(FIPtr)->getIndex();
> > +  MachinePointerInfo MPI = MachinePointerInfo::getFixedStack(FI);
> > 
> >    // Emit a store to the stack slot.
> > -  SDValue Chain = DAG.getStore(DAG.getEntryNode(), dl, Tmp, FIPtr,
> > -                               MachinePointerInfo(), false, false,
> > 0);
> > +  SDValue Chain;
> > +  if (i32Stack) {
> > +    MachineFunction &MF = DAG.getMachineFunction();
> > +    MachineMemOperand *MMO =
> > +      MF.getMachineMemOperand(MPI, MachineMemOperand::MOStore, 4,
> > 4);
> > +    SDValue Ops[] = { DAG.getEntryNode(), Tmp, FIPtr };
> > +    Chain = DAG.getMemIntrinsicNode(PPCISD::STFIWX, dl,
> > +              DAG.getVTList(MVT::Other), Ops, array_lengthof(Ops),
> > +              MVT::i32, MMO);
> > +  } else
> > +    Chain = DAG.getStore(DAG.getEntryNode(), dl, Tmp, FIPtr,
> > +                         MPI, false, false, 0);
> > 
> >    // Result is a load from the stack slot.  If loading 4 bytes,
> >    make sure to
> >    // add in a bias.
> > -  if (Op.getValueType() == MVT::i32)
> > +  if (Op.getValueType() == MVT::i32 && !i32Stack) {
> >      FIPtr = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr,
> >                          DAG.getConstant(4, FIPtr.getValueType()));
> > -  return DAG.getLoad(Op.getValueType(), dl, Chain, FIPtr,
> > MachinePointerInfo(),
> > +    MPI = MachinePointerInfo();
> > +  }
> > +
> > +  return DAG.getLoad(Op.getValueType(), dl, Chain, FIPtr, MPI,
> >                       false, false, false, 0);
> >  }
> > 
> > -SDValue PPCTargetLowering::LowerSINT_TO_FP(SDValue Op,
> > +SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
> >                                             SelectionDAG &DAG)
> >                                             const {
> >    DebugLoc dl = Op.getDebugLoc();
> >    // Don't handle ppc_fp128 here; let it be lowered to a libcall.
> >    if (Op.getValueType() != MVT::f32 && Op.getValueType() !=
> >    MVT::f64)
> >      return SDValue();
> > 
> > +  assert((Op.getOpcode() == ISD::SINT_TO_FP ||
> > PPCSubTarget.hasFPCVT()) &&
> > +         "UINT_TO_FP is supported only with FPCVT");
> > +
> > +  // If we have FCFIDS, then use it when converting to
> > single-precision.
> > +  // Otherwise, convert to double-prcision and then round.
> 
> Typo: precision

r178521, thanks!

> 
> > +  unsigned FCFOp = (PPCSubTarget.hasFPCVT() && Op.getValueType()
> > == MVT::f32) ?
> > +                   (Op.getOpcode() == ISD::UINT_TO_FP ?
> > +                    PPCISD::FCFIDUS : PPCISD::FCFIDS) :
> > +                   (Op.getOpcode() == ISD::UINT_TO_FP ?
> > +                    PPCISD::FCFIDU : PPCISD::FCFID);
> > +  MVT      FCFTy = (PPCSubTarget.hasFPCVT() && Op.getValueType()
> > == MVT::f32) ?
> > +                   MVT::f32 : MVT::f64;
> > +
> >    if (Op.getOperand(0).getValueType() == MVT::i64) {
> >      SDValue SINT = Op.getOperand(0);
> >      // When converting to single-precision, we actually need to
> >      convert
> > @@ -4760,6 +4810,7 @@ SDValue PPCTargetLowering::LowerSINT_TO_
> >      // However, if -enable-unsafe-fp-math is in effect, accept
> >      double
> >      // rounding to avoid the extra overhead.
> >      if (Op.getValueType() == MVT::f32 &&
> > +        !PPCSubTarget.hasFPCVT() &&
> >          !DAG.getTarget().Options.UnsafeFPMath) {
> > 
> >        // Twiddle input to make sure the low 11 bits are zero.  (If
> >        this
> > @@ -4793,16 +4844,18 @@ SDValue PPCTargetLowering::LowerSINT_TO_
> > 
> >        SINT = DAG.getNode(ISD::SELECT, dl, MVT::i64, Cond, Round,
> >        SINT);
> >      }
> > +
> >      SDValue Bits = DAG.getNode(ISD::BITCAST, dl, MVT::f64, SINT);
> > -    SDValue FP = DAG.getNode(PPCISD::FCFID, dl, MVT::f64, Bits);
> > -    if (Op.getValueType() == MVT::f32)
> > +    SDValue FP = DAG.getNode(FCFOp, dl, FCFTy, Bits);
> > +
> > +    if (Op.getValueType() == MVT::f32 && !PPCSubTarget.hasFPCVT())
> >        FP = DAG.getNode(ISD::FP_ROUND, dl,
> >                         MVT::f32, FP, DAG.getIntPtrConstant(0));
> >      return FP;
> >    }
> > 
> >    assert(Op.getOperand(0).getValueType() == MVT::i32 &&
> > -         "Unhandled SINT_TO_FP type in custom expander!");
> > +         "Unhandled INT_TO_FP type in custom expander!");
> >    // Since we only generate this in 64-bit mode, we can take
> >    advantage of
> >    // 64-bit registers.  In particular, sign extend the input value
> >    into the
> >    // 64-bit register with extsw, store the WHOLE 64-bit value into
> >    the stack
> > @@ -4812,7 +4865,7 @@ SDValue PPCTargetLowering::LowerSINT_TO_
> >    EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
> > 
> >    SDValue Ld;
> > -  if (PPCSubTarget.hasLFIWAX()) {
> > +  if (PPCSubTarget.hasLFIWAX() || PPCSubTarget.hasFPCVT()) {
> 
> Incorrect, see below...
> 
> >      int FrameIdx = FrameInfo->CreateStackObject(4, 4, false);
> >      SDValue FIdx = DAG.getFrameIndex(FrameIdx, PtrVT);
> > 
> > @@ -4826,10 +4879,14 @@ SDValue PPCTargetLowering::LowerSINT_TO_
> >        MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx),
> >                                MachineMemOperand::MOLoad, 4, 4);
> >      SDValue Ops[] = { Store, FIdx };
> > -    Ld = DAG.getMemIntrinsicNode(PPCISD::LFIWAX, dl,
> > -                                 DAG.getVTList(MVT::f64,
> > MVT::Other), Ops, 2,
> > -                                 MVT::i32, MMO);
> > +    Ld = DAG.getMemIntrinsicNode(Op.getOpcode() == ISD::UINT_TO_FP
> > ?
> > +                                   PPCISD::LFIWZX :
> > PPCISD::LFIWAX,
> > +                                 dl, DAG.getVTList(MVT::f64,
> > MVT::Other),
> > +                                 Ops, 2, MVT::i32, MMO);
> 
> This code can be entered if hasLFIWAX() is true and hasFPCVT() is
> false.
> In that case, if the opcode is UINT_TO_FP, code will be generated to
> use
> LFIWZX even though hasFPCVT() is false.  This will generate illegal
> code
> on P6 and P6+.

No, this entire function is not used in that case (UINT_TO_FP is marked as Expand). To check this, I placed this assert at the top of the function:

  assert((Op.getOpcode() == ISD::SINT_TO_FP || PPCSubTarget.hasFPCVT()) &&
         "UINT_TO_FP is supported only with FPCVT");

Thanks again,
Hal

> 
> Otherwise, looks fine from here!
> 
> Thanks,
> Bill
> 
> >    } else {
> > +    assert(PPCSubTarget.isPPC64() &&
> > +           "i32->FP without LFIWAX supported only on PPC64");
> > +
> >      int FrameIdx = FrameInfo->CreateStackObject(8, 8, false);
> >      SDValue FIdx = DAG.getFrameIndex(FrameIdx, PtrVT);
> > 
> > @@ -4848,8 +4905,8 @@ SDValue PPCTargetLowering::LowerSINT_TO_
> >    }
> > 
> >    // FCFID it and return it.
> > -  SDValue FP = DAG.getNode(PPCISD::FCFID, dl, MVT::f64, Ld);
> > -  if (Op.getValueType() == MVT::f32)
> > +  SDValue FP = DAG.getNode(FCFOp, dl, FCFTy, Ld);
> > +  if (Op.getValueType() == MVT::f32 && !PPCSubTarget.hasFPCVT())
> >      FP = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, FP,
> >      DAG.getIntPtrConstant(0));
> >    return FP;
> >  }
> > @@ -5651,7 +5708,8 @@ SDValue PPCTargetLowering::LowerOperatio
> >    case ISD::FP_TO_UINT:
> >    case ISD::FP_TO_SINT:         return LowerFP_TO_INT(Op, DAG,
> >                                                         Op.getDebugLoc());
> > -  case ISD::SINT_TO_FP:         return LowerSINT_TO_FP(Op, DAG);
> > +  case ISD::UINT_TO_FP:
> > +  case ISD::SINT_TO_FP:         return LowerINT_TO_FP(Op, DAG);
> >    case ISD::FLT_ROUNDS_:        return LowerFLT_ROUNDS_(Op, DAG);
> > 
> >    // Lower 64-bit shifts.
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=178480&r1=178479&r2=178480&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Mon Apr  1
> > 12:52:07 2013
> > @@ -36,11 +36,19 @@ namespace llvm {
> >        /// was temporarily in the f64 operand.
> >        FCFID,
> > 
> > +      /// Newer FCFID[US] integer-to-floating-point conversion
> > instructions for
> > +      /// unsigned integers and single-precision outputs.
> > +      FCFIDU, FCFIDS, FCFIDUS,
> > +
> >        /// FCTI[D,W]Z - The FCTIDZ and FCTIWZ instructions, taking
> >        an f32 or f64
> >        /// operand, producing an f64 value containing the integer
> >        representation
> >        /// of that FP value.
> >        FCTIDZ, FCTIWZ,
> > 
> > +      /// Newer FCTI[D,W]UZ floating-point-to-integer conversion
> > instructions for
> > +      /// unsigned integers.
> > +      FCTIDUZ, FCTIWUZ,
> > +
> >        // VMADDFP, VNMSUBFP - The VMADDFP and VNMSUBFP
> >        instructions, taking
> >        // three v4f32 operands and producing a v4f32 result.
> >        VMADDFP, VNMSUBFP,
> > @@ -247,6 +255,11 @@ namespace llvm {
> >        /// destination 64-bit register.
> >        LFIWAX,
> > 
> > +      /// GPRC, CHAIN = LFIWZX CHAIN, Ptr - This is a
> > floating-point
> > +      /// load which zero-extends from a 32-bit integer value into
> > the
> > +      /// destination 64-bit register.
> > +      LFIWZX,
> > +
> >        /// G8RC = ADDIS_TOC_HA %X2, Symbol - For medium and large
> >        code model,
> >        /// produces an ADDIS8 instruction that adds the TOC base
> >        register to
> >        /// sym at toc@ha.
> > @@ -494,7 +507,7 @@ namespace llvm {
> >                                        const PPCSubtarget
> >                                        &Subtarget) const;
> >      SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
> >      SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG, DebugLoc
> >      dl) const;
> > -    SDValue LowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
> > +    SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
> >      SDValue LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) const;
> >      SDValue LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) const;
> >      SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const;
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td?rev=178480&r1=178479&r2=178480&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCInstr64Bit.td Mon Apr  1
> > 12:52:07 2013
> > @@ -859,6 +859,22 @@ def FCFID  : XForm_26<63, 846, (outs F8R
> >  def FCTIDZ : XForm_26<63, 815, (outs F8RC:$frD), (ins F8RC:$frB),
> >                        "fctidz $frD, $frB", FPGeneral,
> >                        [(set f64:$frD, (PPCfctidz f64:$frB))]>,
> >                        isPPC64;
> > +
> > +def FCFIDU  : XForm_26<63, 974, (outs F8RC:$frD), (ins F8RC:$frB),
> > +                      "fcfidu $frD, $frB", FPGeneral,
> > +                      [(set f64:$frD, (PPCfcfidu f64:$frB))]>,
> > isPPC64;
> > +def FCFIDS  : XForm_26<59, 846, (outs F4RC:$frD), (ins F8RC:$frB),
> > +                      "fcfids $frD, $frB", FPGeneral,
> > +                      [(set f32:$frD, (PPCfcfids f64:$frB))]>,
> > isPPC64;
> > +def FCFIDUS : XForm_26<59, 974, (outs F4RC:$frD), (ins F8RC:$frB),
> > +                      "fcfidus $frD, $frB", FPGeneral,
> > +                      [(set f32:$frD, (PPCfcfidus f64:$frB))]>,
> > isPPC64;
> > +def FCTIDUZ : XForm_26<63, 943, (outs F8RC:$frD), (ins F8RC:$frB),
> > +                      "fctiduz $frD, $frB", FPGeneral,
> > +                      [(set f64:$frD, (PPCfctiduz f64:$frB))]>,
> > isPPC64;
> > +def FCTIWUZ : XForm_26<63, 143, (outs F8RC:$frD), (ins F8RC:$frB),
> > +                      "fctiwuz $frD, $frB", FPGeneral,
> > +                      [(set f64:$frD, (PPCfctiwuz f64:$frB))]>,
> > isPPC64;
> >  }
> > 
> > 
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td?rev=178480&r1=178479&r2=178480&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCInstrInfo.td Mon Apr  1
> > 12:52:07 2013
> > @@ -20,7 +20,7 @@ include "PPCInstrFormats.td"
> >  def SDT_PPCstfiwx : SDTypeProfile<0, 2, [ // stfiwx
> >    SDTCisVT<0, f64>, SDTCisPtrTy<1>
> >  ]>;
> > -def SDT_PPClfiwax : SDTypeProfile<1, 1, [ // lfiwax
> > +def SDT_PPClfiwx : SDTypeProfile<1, 1, [ // lfiw[az]x
> >    SDTCisVT<0, f64>, SDTCisPtrTy<1>
> >  ]>;
> > 
> > @@ -62,12 +62,19 @@ def SDT_PPCTC_ret : SDTypeProfile<0, 2,
> >  // PowerPC specific DAG Nodes.
> >  //
> > 
> > -def PPCfcfid  : SDNode<"PPCISD::FCFID" , SDTFPUnaryOp, []>;
> > +def PPCfcfid  : SDNode<"PPCISD::FCFID",   SDTFPUnaryOp, []>;
> > +def PPCfcfidu : SDNode<"PPCISD::FCFIDU",  SDTFPUnaryOp, []>;
> > +def PPCfcfids : SDNode<"PPCISD::FCFIDS",  SDTFPRoundOp, []>;
> > +def PPCfcfidus: SDNode<"PPCISD::FCFIDUS", SDTFPRoundOp, []>;
> >  def PPCfctidz : SDNode<"PPCISD::FCTIDZ", SDTFPUnaryOp, []>;
> >  def PPCfctiwz : SDNode<"PPCISD::FCTIWZ", SDTFPUnaryOp, []>;
> > +def PPCfctiduz: SDNode<"PPCISD::FCTIDUZ",SDTFPUnaryOp, []>;
> > +def PPCfctiwuz: SDNode<"PPCISD::FCTIWUZ",SDTFPUnaryOp, []>;
> >  def PPCstfiwx : SDNode<"PPCISD::STFIWX", SDT_PPCstfiwx,
> >                         [SDNPHasChain, SDNPMayStore]>;
> > -def PPClfiwax : SDNode<"PPCISD::LFIWAX", SDT_PPClfiwax,
> > +def PPClfiwax : SDNode<"PPCISD::LFIWAX", SDT_PPClfiwx,
> > +                       [SDNPHasChain, SDNPMayLoad]>;
> > +def PPClfiwzx : SDNode<"PPCISD::LFIWZX", SDT_PPClfiwx,
> >                         [SDNPHasChain, SDNPMayLoad]>;
> > 
> >  // Extract FPSCR (not modeled at the DAG level).
> > @@ -853,6 +860,9 @@ def LFDX   : XForm_25<31, 599, (outs F8R
> >  def LFIWAX : XForm_25<31, 855, (outs F8RC:$frD), (ins memrr:$src),
> >                        "lfiwax $frD, $src", LdStLFD,
> >                        [(set f64:$frD, (PPClfiwax xoaddr:$src))]>;
> > +def LFIWZX : XForm_25<31, 887, (outs F8RC:$frD), (ins memrr:$src),
> > +                      "lfiwzx $frD, $src", LdStLFD,
> > +                      [(set f64:$frD, (PPClfiwzx xoaddr:$src))]>;
> >  }
> > 
> >  //===----------------------------------------------------------------------===//
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=178480&r1=178479&r2=178480&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp Mon Apr  1
> > 12:52:07 2013
> > @@ -41,6 +41,7 @@ PPCSubtarget::PPCSubtarget(const std::st
> >    , HasSTFIWX(false)
> >    , HasLFIWAX(false)
> >    , HasFPRND(false)
> > +  , HasFPCVT(false)
> >    , HasISEL(false)
> >    , HasPOPCNTD(false)
> >    , HasLDBRX(false)
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h?rev=178480&r1=178479&r2=178480&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h Mon Apr  1
> > 12:52:07 2013
> > @@ -80,6 +80,7 @@ protected:
> >    bool HasSTFIWX;
> >    bool HasLFIWAX;
> >    bool HasFPRND;
> > +  bool HasFPCVT;
> >    bool HasISEL;
> >    bool HasPOPCNTD;
> >    bool HasLDBRX;
> > @@ -161,6 +162,7 @@ public:
> >    bool hasSTFIWX() const { return HasSTFIWX; }
> >    bool hasLFIWAX() const { return HasLFIWAX; }
> >    bool hasFPRND() const { return HasFPRND; }
> > +  bool hasFPCVT() const { return HasFPCVT; }
> >    bool hasAltivec() const { return HasAltivec; }
> >    bool hasQPX() const { return HasQPX; }
> >    bool hasMFOCRF() const { return HasMFOCRF; }
> > 
> > Added: llvm/trunk/test/CodeGen/PowerPC/float-to-int.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/float-to-int.ll?rev=178480&view=auto
> > ==============================================================================
> > --- llvm/trunk/test/CodeGen/PowerPC/float-to-int.ll (added)
> > +++ llvm/trunk/test/CodeGen/PowerPC/float-to-int.ll Mon Apr  1
> > 12:52:07 2013
> > @@ -0,0 +1,92 @@
> > +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=a2 |
> > FileCheck %s
> > +target datalayout =
> > "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
> > +target triple = "powerpc64-unknown-linux-gnu"
> > +
> > +define i64 @foo(float %a) nounwind {
> > +  %x = fptosi float %a to i64
> > +  ret i64 %x
> > +
> > +; CHECK: @foo
> > +; CHECK: fctidz [[REG:[0-9]+]], 1
> > +; CHECK: stfd [[REG]],
> > +; CHECK: ld 3,
> > +; CHECK: blr
> > +}
> > +
> > +define i64 @foo2(double %a) nounwind {
> > +  %x = fptosi double %a to i64
> > +  ret i64 %x
> > +
> > +; CHECK: @foo2
> > +; CHECK: fctidz [[REG:[0-9]+]], 1
> > +; CHECK: stfd [[REG]],
> > +; CHECK: ld 3,
> > +; CHECK: blr
> > +}
> > +
> > +define i64 @foo3(float %a) nounwind {
> > +  %x = fptoui float %a to i64
> > +  ret i64 %x
> > +
> > +; CHECK: @foo3
> > +; CHECK: fctiduz [[REG:[0-9]+]], 1
> > +; CHECK: stfd [[REG]],
> > +; CHECK: ld 3,
> > +; CHECK: blr
> > +}
> > +
> > +define i64 @foo4(double %a) nounwind {
> > +  %x = fptoui double %a to i64
> > +  ret i64 %x
> > +
> > +; CHECK: @foo4
> > +; CHECK: fctiduz [[REG:[0-9]+]], 1
> > +; CHECK: stfd [[REG]],
> > +; CHECK: ld 3,
> > +; CHECK: blr
> > +}
> > +
> > +define i32 @goo(float %a) nounwind {
> > +  %x = fptosi float %a to i32
> > +  ret i32 %x
> > +
> > +; CHECK: @goo
> > +; CHECK: fctiwz [[REG:[0-9]+]], 1
> > +; CHECK: stfiwx [[REG]],
> > +; CHECK: lwz 3,
> > +; CHECK: blr
> > +}
> > +
> > +define i32 @goo2(double %a) nounwind {
> > +  %x = fptosi double %a to i32
> > +  ret i32 %x
> > +
> > +; CHECK: @goo2
> > +; CHECK: fctiwz [[REG:[0-9]+]], 1
> > +; CHECK: stfiwx [[REG]],
> > +; CHECK: lwz 3,
> > +; CHECK: blr
> > +}
> > +
> > +define i32 @goo3(float %a) nounwind {
> > +  %x = fptoui float %a to i32
> > +  ret i32 %x
> > +
> > +; CHECK: @goo3
> > +; CHECK: fctiwuz [[REG:[0-9]+]], 1
> > +; CHECK: stfiwx [[REG]],
> > +; CHECK: lwz 3,
> > +; CHECK: blr
> > +}
> > +
> > +define i32 @goo4(double %a) nounwind {
> > +  %x = fptoui double %a to i32
> > +  ret i32 %x
> > +
> > +; CHECK: @goo4
> > +; CHECK: fctiwuz [[REG:[0-9]+]], 1
> > +; CHECK: stfiwx [[REG]],
> > +; CHECK: lwz 3,
> > +; CHECK: blr
> > +}
> > +
> > 
> > Modified: llvm/trunk/test/CodeGen/PowerPC/i32-to-float.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/i32-to-float.ll?rev=178480&r1=178479&r2=178480&view=diff
> > ==============================================================================
> > --- llvm/trunk/test/CodeGen/PowerPC/i32-to-float.ll (original)
> > +++ llvm/trunk/test/CodeGen/PowerPC/i32-to-float.ll Mon Apr  1
> > 12:52:07 2013
> > @@ -1,4 +1,5 @@
> >  ; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=g5 |
> >  FileCheck %s
> > +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=pwr6 |
> > FileCheck -check-prefix=CHECK-PWR6 %s
> >  ; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=a2 |
> >  FileCheck -check-prefix=CHECK-A2 %s
> >  target datalayout =
> >  "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
> >  target triple = "powerpc64-unknown-linux-gnu"
> > @@ -16,11 +17,17 @@ entry:
> >  ; CHECK: frsp 1, [[REG3]]
> >  ; CHECK: blr
> > 
> > +; CHECK-PWR6: @foo
> > +; CHECK-PWR6: stw 3,
> > +; CHECK-PWR6: lfiwax [[REG:[0-9]+]],
> > +; CHECK-PWR6: fcfid [[REG2:[0-9]+]], [[REG]]
> > +; CHECK-PWR6: frsp 1, [[REG2]]
> > +; CHECK-PWR6: blr
> > +
> >  ; CHECK-A2: @foo
> >  ; CHECK-A2: stw 3,
> >  ; CHECK-A2: lfiwax [[REG:[0-9]+]],
> > -; CHECK-A2: fcfid [[REG2:[0-9]+]], [[REG]]
> > -; CHECK-A2: frsp 1, [[REG2]]
> > +; CHECK-A2: fcfids 1, [[REG]]
> >  ; CHECK-A2: blr
> >  }
> > 
> > @@ -36,6 +43,12 @@ entry:
> >  ; CHECK: fcfid 1, [[REG2]]
> >  ; CHECK: blr
> > 
> > +; CHECK-PWR6: @goo
> > +; CHECK-PWR6: stw 3,
> > +; CHECK-PWR6: lfiwax [[REG:[0-9]+]],
> > +; CHECK-PWR6: fcfid 1, [[REG]]
> > +; CHECK-PWR6: blr
> > +
> >  ; CHECK-A2: @goo
> >  ; CHECK-A2: stw 3,
> >  ; CHECK-A2: lfiwax [[REG:[0-9]+]],
> > @@ -43,3 +56,27 @@ entry:
> >  ; CHECK-A2: blr
> >  }
> > 
> > +define float @foou(i32 %a) nounwind {
> > +entry:
> > +  %x = uitofp i32 %a to float
> > +  ret float %x
> > +
> > +; CHECK-A2: @foou
> > +; CHECK-A2: stw 3,
> > +; CHECK-A2: lfiwzx [[REG:[0-9]+]],
> > +; CHECK-A2: fcfidus 1, [[REG]]
> > +; CHECK-A2: blr
> > +}
> > +
> > +define double @goou(i32 %a) nounwind {
> > +entry:
> > +  %x = uitofp i32 %a to double
> > +  ret double %x
> > +
> > +; CHECK-A2: @goou
> > +; CHECK-A2: stw 3,
> > +; CHECK-A2: lfiwzx [[REG:[0-9]+]],
> > +; CHECK-A2: fcfidu 1, [[REG]]
> > +; CHECK-A2: blr
> > +}
> > +
> > 
> > Added: llvm/trunk/test/CodeGen/PowerPC/i64-to-float.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/i64-to-float.ll?rev=178480&view=auto
> > ==============================================================================
> > --- llvm/trunk/test/CodeGen/PowerPC/i64-to-float.ll (added)
> > +++ llvm/trunk/test/CodeGen/PowerPC/i64-to-float.ll Mon Apr  1
> > 12:52:07 2013
> > @@ -0,0 +1,52 @@
> > +; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -mcpu=a2 |
> > FileCheck %s
> > +target datalayout =
> > "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64"
> > +target triple = "powerpc64-unknown-linux-gnu"
> > +
> > +define float @foo(i64 %a) nounwind {
> > +entry:
> > +  %x = sitofp i64 %a to float
> > +  ret float %x
> > +
> > +; CHECK: @foo
> > +; CHECK: std 3,
> > +; CHECK: lfd [[REG:[0-9]+]],
> > +; CHECK: fcfids 1, [[REG]]
> > +; CHECK: blr
> > +}
> > +
> > +define double @goo(i64 %a) nounwind {
> > +entry:
> > +  %x = sitofp i64 %a to double
> > +  ret double %x
> > +
> > +; CHECK: @goo
> > +; CHECK: std 3,
> > +; CHECK: lfd [[REG:[0-9]+]],
> > +; CHECK: fcfid 1, [[REG]]
> > +; CHECK: blr
> > +}
> > +
> > +define float @foou(i64 %a) nounwind {
> > +entry:
> > +  %x = uitofp i64 %a to float
> > +  ret float %x
> > +
> > +; CHECK: @foou
> > +; CHECK: std 3,
> > +; CHECK: lfd [[REG:[0-9]+]],
> > +; CHECK: fcfidus 1, [[REG]]
> > +; CHECK: blr
> > +}
> > +
> > +define double @goou(i64 %a) nounwind {
> > +entry:
> > +  %x = uitofp i64 %a to double
> > +  ret double %x
> > +
> > +; CHECK: @goou
> > +; CHECK: std 3,
> > +; CHECK: lfd [[REG:[0-9]+]],
> > +; CHECK: fcfidu 1, [[REG]]
> > +; CHECK: blr
> > +}
> > +
> > 
> > Modified: llvm/trunk/test/CodeGen/PowerPC/i64_fp_round.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/i64_fp_round.ll?rev=178480&r1=178479&r2=178480&view=diff
> > ==============================================================================
> > --- llvm/trunk/test/CodeGen/PowerPC/i64_fp_round.ll (original)
> > +++ llvm/trunk/test/CodeGen/PowerPC/i64_fp_round.ll Mon Apr  1
> > 12:52:07 2013
> > @@ -1,4 +1,4 @@
> > -; RUN: llc -mcpu=pwr7 < %s | FileCheck %s
> > +; RUN: llc -mcpu=pwr7 -mattr=-fpcvt < %s | FileCheck %s
> >  target datalayout =
> >  "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
> >  target triple = "powerpc64-unknown-linux-gnu"
> > 
> > @@ -22,6 +22,6 @@ entry:
> >  ; Also check that with -enable-unsafe-fp-math we do not get that
> >  extra
> >  ; code sequence.  Simply verify that there is no "isel" present.
> > 
> > -; RUN: llc -mcpu=pwr7 -enable-unsafe-fp-math < %s | FileCheck %s
> > -check-prefix=UNSAFE
> > +; RUN: llc -mcpu=pwr7 -mattr=-fpcvt -enable-unsafe-fp-math < %s |
> > FileCheck %s -check-prefix=UNSAFE
> >  ; CHECK-UNSAFE-NOT: isel
> > 
> > 
> > Modified: llvm/trunk/test/CodeGen/PowerPC/stfiwx-2.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/stfiwx-2.ll?rev=178480&r1=178479&r2=178480&view=diff
> > ==============================================================================
> > --- llvm/trunk/test/CodeGen/PowerPC/stfiwx-2.ll (original)
> > +++ llvm/trunk/test/CodeGen/PowerPC/stfiwx-2.ll Mon Apr  1 12:52:07
> > 2013
> > @@ -1,11 +1,14 @@
> > -; This cannot be a stfiwx
> > -; RUN: llc < %s -march=ppc32 -mcpu=g5 | grep stb
> > -; RUN: llc < %s -march=ppc32 -mcpu=g5 | not grep stfiwx
> > +; RUN: llc < %s -march=ppc32 -mcpu=g5 | FileCheck %s
> > 
> >  define void @test(float %F, i8* %P) {
> >  	%I = fptosi float %F to i32
> >  	%X = trunc i32 %I to i8
> >  	store i8 %X, i8* %P
> >  	ret void
> > +; CHECK: fctiwz 0, 1
> > +; CHECK: stfiwx 0, 0, 4
> > +; CHECK: lwz 4, 12(1)
> > +; CHECK: stb 4, 0(3)
> > +; CHECK: blr
> >  }
> > 
> > 
> > 
> > _______________________________________________
> > 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