[llvm] r234682 - Add direct moves to/from VSR and exploit them for FP/INT conversions

Hal Finkel hfinkel at anl.gov
Sat Apr 11 06:06:18 PDT 2015


----- Original Message -----
> From: "Hal Finkel" <hfinkel at anl.gov>
> To: "Nemanja Ivanovic" <nemanja.i.ibm at gmail.com>
> Cc: llvm-commits at cs.uiuc.edu
> Sent: Saturday, April 11, 2015 7:38:09 AM
> Subject: Re: [llvm] r234682 - Add direct moves to/from VSR and exploit them	for	FP/INT conversions
> 
> ----- Original Message -----
> > From: "Nemanja Ivanovic" <nemanja.i.ibm at gmail.com>
> > To: llvm-commits at cs.uiuc.edu
> > Sent: Saturday, April 11, 2015 5:40:43 AM
> > Subject: [llvm] r234682 - Add direct moves to/from VSR and exploit
> > them for	FP/INT conversions
> > 
> > Author: nemanjai
> > Date: Sat Apr 11 05:40:42 2015
> > New Revision: 234682
> > 
> > URL: http://llvm.org/viewvc/llvm-project?rev=234682&view=rev
> > Log:
> > Add direct moves to/from VSR and exploit them for FP/INT
> > conversions
> > 
> > This patch corresponds to review:
> > http://reviews.llvm.org/D8928
> > 
> > It adds direct move instructions to/from VSX registers to GPR's.
> > These are
> > exploited for FP <-> INT conversions.
> > 
> > Added:
> >     llvm/trunk/test/CodeGen/PowerPC/fp-int-conversions-direct-moves.ll
> > Modified:
> >     llvm/trunk/lib/Target/PowerPC/PPC.td
> >     llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp
> >     llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
> >     llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
> >     llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td
> >     llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td
> >     llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp
> >     llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h
> >     llvm/trunk/test/MC/Disassembler/PowerPC/vsx.txt
> >     llvm/trunk/test/MC/PowerPC/vsx.s
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPC.td
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPC.td?rev=234682&r1=234681&r2=234682&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPC.td (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPC.td Sat Apr 11 05:40:42 2015
> > @@ -122,6 +122,10 @@ def FeatureP8Crypto : SubtargetFeature<"
> >  def FeatureP8Vector  : SubtargetFeature<"power8-vector",
> >  "HasP8Vector", "true",
> >                                          "Enable POWER8 vector
> >                                          instructions",
> >                                          [FeatureVSX,
> >                                          FeatureP8Altivec]>;
> > +def FeatureDirectMove :
> > +  SubtargetFeature<"direct-move", "HasDirectMove", "true",
> > +                   "Enable Power8 direct move instructions",
> > +                   [FeatureVSX]>;
> >  def FeaturePartwordAtomic : SubtargetFeature<"partword-atomics",
> >                                               "HasPartwordAtomics",
> >                                               "true",
> >                                               "Enable l[bh]arx and
> >                                               st[bh]cx.">;
> > @@ -164,7 +168,7 @@ def ProcessorFeatures {
> >         DeprecatedMFTB, DeprecatedDST];
> >    list<SubtargetFeature> Power8SpecificFeatures =
> >        [DirectivePwr8, FeatureP8Altivec, FeatureP8Vector,
> >        FeatureP8Crypto,
> > -       FeatureHTM, FeatureICBT];
> > +       FeatureHTM, FeatureDirectMove, FeatureICBT];
> >    list<SubtargetFeature> Power8FeatureList =
> >        !listconcat(Power7FeatureList, Power8SpecificFeatures);
> >  }
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp?rev=234682&r1=234681&r2=234682&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCFastISel.cpp Sat Apr 11
> > 05:40:42
> > 2015
> > @@ -958,6 +958,8 @@ unsigned PPCFastISel::PPCMoveToFPReg(MVT
> >  }
> >  
> >  // Attempt to fast-select an integer-to-floating-point conversion.
> > +// FIXME: Once fast-isel has better support for VSX, conversions
> > using
> > +//        direct moves should be implemented.
> >  bool PPCFastISel::SelectIToFP(const Instruction *I, bool IsSigned)
> >  {
> >    MVT DstVT;
> >    Type *DstTy = I->getType();
> > @@ -1065,6 +1067,8 @@ unsigned PPCFastISel::PPCMoveToIntReg(co
> >  }
> >  
> >  // Attempt to fast-select a floating-point-to-integer conversion.
> > +// FIXME: Once fast-isel has better support for VSX, conversions
> > using
> > +//        direct moves should be implemented.
> >  bool PPCFastISel::SelectFPToI(const Instruction *I, bool IsSigned)
> >  {
> >    MVT DstVT, SrcVT;
> >    Type *DstTy = I->getType();
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=234682&r1=234681&r2=234682&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Sat Apr 11
> > 05:40:42 2015
> > @@ -996,6 +996,9 @@ const char *PPCTargetLowering::getTarget
> >    case PPCISD::EH_SJLJ_SETJMP:  return "PPCISD::EH_SJLJ_SETJMP";
> >    case PPCISD::EH_SJLJ_LONGJMP: return "PPCISD::EH_SJLJ_LONGJMP";
> >    case PPCISD::MFOCRF:          return "PPCISD::MFOCRF";
> > +  case PPCISD::MFVSR:           return "PPCISD::MFVSR";
> > +  case PPCISD::MTVSRA:          return "PPCISD::MTVSRA";
> > +  case PPCISD::MTVSRZ:          return "PPCISD::MTVSRZ";
> >    case PPCISD::VCMP:            return "PPCISD::VCMP";
> >    case PPCISD::VCMPo:           return "PPCISD::VCMPo";
> >    case PPCISD::LBRX:            return "PPCISD::LBRX";
> > @@ -5911,8 +5914,46 @@ void PPCTargetLowering::LowerFP_TO_INTFo
> >    RLI.MPI = MPI;
> >  }
> >  
> > +/// \brief Custom lowers floating point to integer conversions to
> > use
> > +/// the direct move instructions available in ISA 2.07 to avoid
> > the
> > +/// need for load/store combinations.
> > +SDValue PPCTargetLowering::LowerFP_TO_INTDirectMove(SDValue Op,
> > +                                                    SelectionDAG
> > &DAG,
> > +                                                    SDLoc dl)
> > const
> > {
> > +  assert(Op.getOperand(0).getValueType().isFloatingPoint());
> > +  SDValue Src = Op.getOperand(0);
> > +
> > +  if (Src.getValueType() == MVT::f32)
> > +    Src = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Src);
> > +
> > +  SDValue Tmp;
> > +  switch (Op.getSimpleValueType().SimpleTy) {
> > +  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
> > +            : (Subtarget.hasFPCVT() ? PPCISD::FCTIWUZ :
> > PPCISD::FCTIDZ),
> > +        dl, MVT::f64, Src);
> > +    Tmp = DAG.getNode(PPCISD::MFVSR, dl, MVT::i32, Tmp);
> > +    break;
> > +  case MVT::i64:
> > +    assert((Op.getOpcode() == ISD::FP_TO_SINT ||
> > Subtarget.hasFPCVT()) &&
> > +           "i64 FP_TO_UINT is supported only with FPCVT");
> > +    Tmp = DAG.getNode(Op.getOpcode()==ISD::FP_TO_SINT ?
> > PPCISD::FCTIDZ :
> > +
> >                                                        PPCISD::FCTIDUZ,
> > +                      dl, MVT::f64, Src);
> > +    Tmp = DAG.getNode(PPCISD::MFVSR, dl, MVT::i64, Tmp);
> > +    break;
> > +  }
> > +  return Tmp;
> > +}
> > +
> >  SDValue PPCTargetLowering::LowerFP_TO_INT(SDValue Op, SelectionDAG
> >  &DAG,
> >                                            SDLoc dl) const {
> > +  if (Subtarget.hasDirectMove() && Subtarget.isPPC64())
> > +    return LowerFP_TO_INTDirectMove(Op, DAG, dl);
> > +
> >    ReuseLoadInfo RLI;
> >    LowerFP_TO_INTForReuse(Op, RLI, DAG, dl);
> >  
> > @@ -5990,6 +6031,38 @@ void PPCTargetLowering::spliceIntoChain(
> >    DAG.UpdateNodeOperands(TF.getNode(), ResChain, NewResChain);
> >  }
> >  
> > +/// \brief Custom lowers integer to floating point conversions to
> > use
> > +/// the direct move instructions available in ISA 2.07 to avoid
> > the
> > +/// need for load/store combinations.
> > +SDValue PPCTargetLowering::LowerINT_TO_FPDirectMove(SDValue Op,
> > +                                                    SelectionDAG
> > &DAG,
> > +                                                    SDLoc dl)
> > const
> > {
> > +  assert((Op.getValueType() == MVT::f32 ||
> > +          Op.getValueType() == MVT::f64) &&
> > +         "Invalid floating point type as target of conversion");
> > +  assert(Subtarget.hasFPCVT() &&
> > +         "Int to FP conversions with direct moves require FPCVT");
> > +  SDValue FP;
> > +  SDValue Src = Op.getOperand(0);
> > +  bool SinglePrec = Op.getValueType() == MVT::f32;
> > +  bool WordInt = Src.getSimpleValueType().SimpleTy == MVT::i32;
> > +  bool Signed = Op.getOpcode() == ISD::SINT_TO_FP;
> > +  unsigned ConvOp = Signed ? (SinglePrec ? PPCISD::FCFIDS :
> > PPCISD::FCFID) :
> > +                             (SinglePrec ? PPCISD::FCFIDUS :
> > PPCISD::FCFIDU);
> > +
> > +  if (WordInt) {
> > +    FP = DAG.getNode(Signed ? PPCISD::MTVSRA : PPCISD::MTVSRZ,
> > +                     dl, MVT::f64, Src);
> > +    FP = DAG.getNode(ConvOp, dl, SinglePrec ? MVT::f32 : MVT::f64,
> > FP);
> > +  }
> > +  else {
> > +    FP = DAG.getNode(PPCISD::MTVSRA, dl, MVT::f64, Src);
> > +    FP = DAG.getNode(ConvOp, dl, SinglePrec ? MVT::f32 : MVT::f64,
> > FP);
> > +  }
> > +
> > +  return FP;
> > +}
> > +
> >  SDValue PPCTargetLowering::LowerINT_TO_FP(SDValue Op,
> >                                            SelectionDAG &DAG) const
> >                                            {
> >    SDLoc dl(Op);
> > @@ -6025,6 +6098,11 @@ SDValue PPCTargetLowering::LowerINT_TO_F
> >                         DAG.getConstantFP(1.0, Op.getValueType()),
> >                         DAG.getConstantFP(0.0, Op.getValueType()));
> >  
> > +  // If we have direct moves, we can do all the conversion, skip
> > the
> > store/load
> > +  // however, without FPCVT we can't do most conversions.
> > +  if (Subtarget.hasDirectMove() && Subtarget.isPPC64() &&
> > Subtarget.hasFPCVT())
> > +    return LowerINT_TO_FPDirectMove(Op, DAG, dl);
> > +
> >    assert((Op.getOpcode() == ISD::SINT_TO_FP ||
> >    Subtarget.hasFPCVT())
> >    &&
> >           "UINT_TO_FP is supported only with FPCVT");
> >  
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=234682&r1=234681&r2=234682&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Sat Apr 11
> > 05:40:42 2015
> > @@ -119,6 +119,15 @@ namespace llvm {
> >        /// resultant GPR.  Bits corresponding to other CR regs are
> >        undefined.
> >        MFOCRF,
> >  
> > +      /// Direct move from a VSX register to a GPR
> > +      MFVSR,
> > +
> > +      /// Direct move from a GPR to a VSX register (algebraic)
> > +      MTVSRA,
> > +
> > +      /// Direct move from a GPR to a VSX register (zero)
> > +      MTVSRZ,
> > +
> >        // FIXME: Remove these once the ANDI glue bug is fixed:
> >        /// i1 = ANDIo_1_[EQ|GT]_BIT(i32 or i64 x) - Represents the
> >        result of the
> >        /// eq or gt bit of CR0 after executing andi. x, 1. This is
> >        used to
> > @@ -645,6 +654,10 @@ namespace llvm {
> >  
> >      void LowerFP_TO_INTForReuse(SDValue Op, ReuseLoadInfo &RLI,
> >                                  SelectionDAG &DAG, SDLoc dl)
> >                                  const;
> > +    SDValue LowerFP_TO_INTDirectMove(SDValue Op, SelectionDAG
> > &DAG,
> > +                                     SDLoc dl) const;
> > +    SDValue LowerINT_TO_FPDirectMove(SDValue Op, SelectionDAG
> > &DAG,
> > +                                     SDLoc dl) const;
> >  
> >      SDValue getFramePointerFrameIndex(SelectionDAG & DAG) const;
> >      SDValue getReturnAddrFrameIndex(SelectionDAG & DAG) const;
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td?rev=234682&r1=234681&r2=234682&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCInstrFormats.td Sat Apr 11
> > 05:40:42 2015
> > @@ -764,6 +764,12 @@ class XX1Form<bits<6> opcode, bits<10> x
> >    let Inst{31}    = XT{5};
> >  }
> >  
> > +class XX1_RS6_RD5_XO<bits<6> opcode, bits<10> xo, dag OOL, dag
> > IOL,
> > +                     string asmstr, InstrItinClass itin, list<dag>
> > pattern>
> > +  : XX1Form<opcode, xo, OOL, IOL, asmstr, itin, pattern> {
> > +  let B = 0;
> > +}
> > +
> >  class XX2Form<bits<6> opcode, bits<9> xo, dag OOL, dag IOL, string
> >  asmstr,
> >                InstrItinClass itin, list<dag> pattern>
> >    : I<opcode, OOL, IOL, asmstr, itin> {
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td?rev=234682&r1=234681&r2=234682&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCInstrVSX.td Sat Apr 11
> > 05:40:42
> > 2015
> > @@ -41,6 +41,9 @@ def PPClxvd2x  : SDNode<"PPCISD::LXVD2X"
> >  def PPCstxvd2x : SDNode<"PPCISD::STXVD2X", SDT_PPCstxvd2x,
> >                          [SDNPHasChain, SDNPMayStore]>;
> >  def PPCxxswapd : SDNode<"PPCISD::XXSWAPD", SDT_PPCxxswapd,
> >  [SDNPHasChain]>;
> > +def PPCmfvsr : SDNode<"PPCISD::MFVSR", SDTUnaryOp, []>;
> > +def PPCmtvsra : SDNode<"PPCISD::MTVSRA", SDTUnaryOp, []>;
> > +def PPCmtvsrz : SDNode<"PPCISD::MTVSRZ", SDTUnaryOp, []>;
> >  
> >  multiclass XX3Form_Rcr<bits<6> opcode, bits<7> xo, dag OOL, dag
> >  IOL,
> >                      string asmbase, string asmstr, InstrItinClass
> >                      itin,
> > @@ -946,6 +949,7 @@ def : Pat<(int_ppc_vsx_xvdivdp v2f64:$A,
> >     when the elements are larger than i32.
> >  */
> >  def HasP8Vector : Predicate<"PPCSubTarget->hasP8Vector()">;
> > +def HasDirectMove : Predicate<"PPCSubTarget->hasDirectMove()">;
> >  let Predicates = [HasP8Vector] in {
> >  let AddedComplexity = 400 in { // Prefer VSX patterns over non-VSX
> >  patterns.
> >  let isCommutable = 1 in {
> > @@ -965,3 +969,24 @@ def XXLORC : XX3Form<60, 170,
> >                       [(set v4i32:$XT, (or v4i32:$XA, (vnot_ppc
> >                       v4i32:$XB)))]>;
> >  } // AddedComplexity = 500
> >  } // HasP8Vector
> > +
> > +let Predicates = [HasDirectMove, HasVSX] in {
> 
> Since the target-specific DAG nodes are only generated when
> HasDirectMove is true, we don't need the predicate here. You can
> remove it, and are these really VSX instructions? Is IIC_VecGeneral
> right? I think it would be more natural to have them in
> PPCInstr64Bit.td because they don't operate on VSX registers.

As you pointed out to me on IRC, these do operate on VSX registers, do you can ignore that part of my comment ;)

 -Hal

> 
>  -Hal
> 
> > +// VSX direct move instructions
> > +def MFVSRD : XX1_RS6_RD5_XO<31, 51, (outs g8rc:$rA), (ins
> > vsfrc:$XT),
> > +                            "mfvsrd $rA, $XT", IIC_VecGeneral,
> > +                            [(set i64:$rA, (PPCmfvsr f64:$XT))]>,
> > +    Requires<[In64BitMode]>;
> > +def MFVSRWZ : XX1_RS6_RD5_XO<31, 115, (outs gprc:$rA), (ins
> > vsfrc:$XT),
> > +                             "mfvsrwz $rA, $XT", IIC_VecGeneral,
> > +                             [(set i32:$rA, (PPCmfvsr f64:$XT))]>;
> > +def MTVSRD : XX1_RS6_RD5_XO<31, 179, (outs vsfrc:$XT), (ins
> > g8rc:$rA),
> > +                            "mtvsrd $XT, $rA", IIC_VecGeneral,
> > +                            [(set f64:$XT, (PPCmtvsra i64:$rA))]>,
> > +    Requires<[In64BitMode]>;
> > +def MTVSRWA : XX1_RS6_RD5_XO<31, 211, (outs vsfrc:$XT), (ins
> > gprc:$rA),
> > +                             "mtvsrwa $XT, $rA", IIC_VecGeneral,
> > +                             [(set f64:$XT, (PPCmtvsra
> > i32:$rA))]>;
> > +def MTVSRWZ : XX1_RS6_RD5_XO<31, 243, (outs vsfrc:$XT), (ins
> > gprc:$rA),
> > +                             "mtvsrwz $XT, $rA", IIC_VecGeneral,
> > +                             [(set f64:$XT, (PPCmtvsrz
> > i32:$rA))]>;
> > +} // HasDirectMove, HasVSX
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp?rev=234682&r1=234681&r2=234682&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.cpp Sat Apr 11
> > 05:40:42 2015
> > @@ -97,6 +97,7 @@ void PPCSubtarget::initializeEnvironment
> >    HasICBT = false;
> >    HasInvariantFunctionDescriptors = false;
> >    HasPartwordAtomics = false;
> > +  HasDirectMove = false;
> >    IsQPXStackUnaligned = false;
> >    HasHTM = false;
> >  }
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h?rev=234682&r1=234681&r2=234682&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCSubtarget.h Sat Apr 11
> > 05:40:42
> > 2015
> > @@ -117,6 +117,7 @@ protected:
> >    bool HasICBT;
> >    bool HasInvariantFunctionDescriptors;
> >    bool HasPartwordAtomics;
> > +  bool HasDirectMove;
> >    bool HasHTM;
> >  
> >    /// When targeting QPX running a stock PPC64 Linux kernel where
> >    the stack
> > @@ -243,6 +244,7 @@ public:
> >      return HasInvariantFunctionDescriptors;
> >    }
> >    bool hasPartwordAtomics() const { return HasPartwordAtomics; }
> > +  bool hasDirectMove() const { return HasDirectMove; }
> >  
> >    bool isQPXStackUnaligned() const { return IsQPXStackUnaligned; }
> >    unsigned getPlatformStackAlignment() const {
> > 
> > Added:
> > llvm/trunk/test/CodeGen/PowerPC/fp-int-conversions-direct-moves.ll
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/fp-int-conversions-direct-moves.ll?rev=234682&view=auto
> > ==============================================================================
> > ---
> > llvm/trunk/test/CodeGen/PowerPC/fp-int-conversions-direct-moves.ll
> > (added)
> > +++
> > llvm/trunk/test/CodeGen/PowerPC/fp-int-conversions-direct-moves.ll
> > Sat Apr 11 05:40:42 2015
> > @@ -0,0 +1,426 @@
> > +; RUN: llc -mcpu=pwr8 -mtriple=powerpc64-unknown-unknown < %s |
> > FileCheck %s
> > +; RUN: llc -mcpu=pwr8 -mtriple=powerpc64le-unknown-unknown < %s |
> > FileCheck %s
> > +
> > +; Function Attrs: nounwind
> > +define zeroext i8 @_Z6testcff(float %arg) {
> > +entry:
> > +  %arg.addr = alloca float, align 4
> > +  store float %arg, float* %arg.addr, align 4
> > +  %0 = load float, float* %arg.addr, align 4
> > +  %conv = fptoui float %0 to i8
> > +  ret i8 %conv
> > +; CHECK-LABEL: @_Z6testcff
> > +; CHECK: xscvdpsxws [[CONVREG01:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG01]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define float @_Z6testfcc(i8 zeroext %arg) {
> > +entry:
> > +  %arg.addr = alloca i8, align 1
> > +  store i8 %arg, i8* %arg.addr, align 1
> > +  %0 = load i8, i8* %arg.addr, align 1
> > +  %conv = uitofp i8 %0 to float
> > +  ret float %conv
> > +; CHECK-LABEL: @_Z6testfcc
> > +; CHECK: mtvsrwz [[MOVEREG01:[0-9]+]], 3
> > +; FIXME: Once we have XSCVUXDSP implemented, this will change
> > +; CHECK: fcfidus 1, [[MOVEREG01]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define zeroext i8 @_Z6testcdd(double %arg) {
> > +entry:
> > +  %arg.addr = alloca double, align 8
> > +  store double %arg, double* %arg.addr, align 8
> > +  %0 = load double, double* %arg.addr, align 8
> > +  %conv = fptoui double %0 to i8
> > +  ret i8 %conv
> > +; CHECK-LABEL: @_Z6testcdd
> > +; CHECK: xscvdpsxws [[CONVREG02:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG02]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define double @_Z6testdcc(i8 zeroext %arg) {
> > +entry:
> > +  %arg.addr = alloca i8, align 1
> > +  store i8 %arg, i8* %arg.addr, align 1
> > +  %0 = load i8, i8* %arg.addr, align 1
> > +  %conv = uitofp i8 %0 to double
> > +  ret double %conv
> > +; CHECK-LABEL: @_Z6testdcc
> > +; CHECK: mtvsrwz [[MOVEREG02:[0-9]+]], 3
> > +; CHECK: xscvuxddp 1, [[MOVEREG02]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define zeroext i8 @_Z7testucff(float %arg) {
> > +entry:
> > +  %arg.addr = alloca float, align 4
> > +  store float %arg, float* %arg.addr, align 4
> > +  %0 = load float, float* %arg.addr, align 4
> > +  %conv = fptoui float %0 to i8
> > +  ret i8 %conv
> > +; CHECK-LABEL: @_Z7testucff
> > +; CHECK: xscvdpsxws [[CONVREG03:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG03]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define float @_Z7testfuch(i8 zeroext %arg) {
> > +entry:
> > +  %arg.addr = alloca i8, align 1
> > +  store i8 %arg, i8* %arg.addr, align 1
> > +  %0 = load i8, i8* %arg.addr, align 1
> > +  %conv = uitofp i8 %0 to float
> > +  ret float %conv
> > +; CHECK-LABEL: @_Z7testfuch
> > +; CHECK: mtvsrwz [[MOVEREG03:[0-9]+]], 3
> > +; FIXME: Once we have XSCVUXDSP implemented, this will change
> > +; CHECK: fcfidus 1, [[MOVEREG03]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define zeroext i8 @_Z7testucdd(double %arg) {
> > +entry:
> > +  %arg.addr = alloca double, align 8
> > +  store double %arg, double* %arg.addr, align 8
> > +  %0 = load double, double* %arg.addr, align 8
> > +  %conv = fptoui double %0 to i8
> > +  ret i8 %conv
> > +; CHECK-LABEL: @_Z7testucdd
> > +; CHECK: xscvdpsxws [[CONVREG04:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG04]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define double @_Z7testduch(i8 zeroext %arg) {
> > +entry:
> > +  %arg.addr = alloca i8, align 1
> > +  store i8 %arg, i8* %arg.addr, align 1
> > +  %0 = load i8, i8* %arg.addr, align 1
> > +  %conv = uitofp i8 %0 to double
> > +  ret double %conv
> > +; CHECK-LABEL: @_Z7testduch
> > +; CHECK: mtvsrwz [[MOVEREG04:[0-9]+]], 3
> > +; CHECK: xscvuxddp 1, [[MOVEREG04]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define signext i16 @_Z6testsff(float %arg) {
> > +entry:
> > +  %arg.addr = alloca float, align 4
> > +  store float %arg, float* %arg.addr, align 4
> > +  %0 = load float, float* %arg.addr, align 4
> > +  %conv = fptosi float %0 to i16
> > +  ret i16 %conv
> > +; CHECK-LABEL: @_Z6testsff
> > +; CHECK: xscvdpsxws [[CONVREG05:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG05]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define float @_Z6testfss(i16 signext %arg) {
> > +entry:
> > +  %arg.addr = alloca i16, align 2
> > +  store i16 %arg, i16* %arg.addr, align 2
> > +  %0 = load i16, i16* %arg.addr, align 2
> > +  %conv = sitofp i16 %0 to float
> > +  ret float %conv
> > +; CHECK-LABEL: @_Z6testfss
> > +; CHECK: mtvsrwa [[MOVEREG05:[0-9]+]], 3
> > +; FIXME: Once we have XSCVSXDSP implemented, this will change
> > +; CHECK: fcfids 1, [[MOVEREG05]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define signext i16 @_Z6testsdd(double %arg) {
> > +entry:
> > +  %arg.addr = alloca double, align 8
> > +  store double %arg, double* %arg.addr, align 8
> > +  %0 = load double, double* %arg.addr, align 8
> > +  %conv = fptosi double %0 to i16
> > +  ret i16 %conv
> > +; CHECK-LABEL: @_Z6testsdd
> > +; CHECK: xscvdpsxws [[CONVREG06:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG06]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define double @_Z6testdss(i16 signext %arg) {
> > +entry:
> > +  %arg.addr = alloca i16, align 2
> > +  store i16 %arg, i16* %arg.addr, align 2
> > +  %0 = load i16, i16* %arg.addr, align 2
> > +  %conv = sitofp i16 %0 to double
> > +  ret double %conv
> > +; CHECK-LABEL: @_Z6testdss
> > +; CHECK: mtvsrwa [[MOVEREG06:[0-9]+]], 3
> > +; CHECK: xscvsxddp 1, [[MOVEREG06]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define zeroext i16 @_Z7testusff(float %arg) {
> > +entry:
> > +  %arg.addr = alloca float, align 4
> > +  store float %arg, float* %arg.addr, align 4
> > +  %0 = load float, float* %arg.addr, align 4
> > +  %conv = fptoui float %0 to i16
> > +  ret i16 %conv
> > +; CHECK-LABEL: @_Z7testusff
> > +; CHECK: xscvdpsxws [[CONVREG07:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG07]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define float @_Z7testfust(i16 zeroext %arg) {
> > +entry:
> > +  %arg.addr = alloca i16, align 2
> > +  store i16 %arg, i16* %arg.addr, align 2
> > +  %0 = load i16, i16* %arg.addr, align 2
> > +  %conv = uitofp i16 %0 to float
> > +  ret float %conv
> > +; CHECK-LABEL: @_Z7testfust
> > +; CHECK: mtvsrwz [[MOVEREG07:[0-9]+]], 3
> > +; FIXME: Once we have XSCVUXDSP implemented, this will change
> > +; CHECK: fcfidus 1, [[MOVEREG07]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define zeroext i16 @_Z7testusdd(double %arg) {
> > +entry:
> > +  %arg.addr = alloca double, align 8
> > +  store double %arg, double* %arg.addr, align 8
> > +  %0 = load double, double* %arg.addr, align 8
> > +  %conv = fptoui double %0 to i16
> > +  ret i16 %conv
> > +; CHECK-LABEL: @_Z7testusdd
> > +; CHECK: xscvdpsxws [[CONVREG08:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG08]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define double @_Z7testdust(i16 zeroext %arg) {
> > +entry:
> > +  %arg.addr = alloca i16, align 2
> > +  store i16 %arg, i16* %arg.addr, align 2
> > +  %0 = load i16, i16* %arg.addr, align 2
> > +  %conv = uitofp i16 %0 to double
> > +  ret double %conv
> > +; CHECK-LABEL: @_Z7testdust
> > +; CHECK: mtvsrwz [[MOVEREG08:[0-9]+]], 3
> > +; CHECK: xscvuxddp 1, [[MOVEREG08]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define signext i32 @_Z6testiff(float %arg) {
> > +entry:
> > +  %arg.addr = alloca float, align 4
> > +  store float %arg, float* %arg.addr, align 4
> > +  %0 = load float, float* %arg.addr, align 4
> > +  %conv = fptosi float %0 to i32
> > +  ret i32 %conv
> > +; CHECK-LABEL: @_Z6testiff
> > +; CHECK: xscvdpsxws [[CONVREG09:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG09]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define float @_Z6testfii(i32 signext %arg) {
> > +entry:
> > +  %arg.addr = alloca i32, align 4
> > +  store i32 %arg, i32* %arg.addr, align 4
> > +  %0 = load i32, i32* %arg.addr, align 4
> > +  %conv = sitofp i32 %0 to float
> > +  ret float %conv
> > +; CHECK-LABEL: @_Z6testfii
> > +; CHECK: mtvsrwa [[MOVEREG09:[0-9]+]], 3
> > +; FIXME: Once we have XSCVSXDSP implemented, this will change
> > +; CHECK: fcfids 1, [[MOVEREG09]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define signext i32 @_Z6testidd(double %arg) {
> > +entry:
> > +  %arg.addr = alloca double, align 8
> > +  store double %arg, double* %arg.addr, align 8
> > +  %0 = load double, double* %arg.addr, align 8
> > +  %conv = fptosi double %0 to i32
> > +  ret i32 %conv
> > +; CHECK-LABEL: @_Z6testidd
> > +; CHECK: xscvdpsxws [[CONVREG10:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG10]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define double @_Z6testdii(i32 signext %arg) {
> > +entry:
> > +  %arg.addr = alloca i32, align 4
> > +  store i32 %arg, i32* %arg.addr, align 4
> > +  %0 = load i32, i32* %arg.addr, align 4
> > +  %conv = sitofp i32 %0 to double
> > +  ret double %conv
> > +; CHECK-LABEL: @_Z6testdii
> > +; CHECK: mtvsrwa [[MOVEREG10:[0-9]+]], 3
> > +; CHECK: xscvsxddp 1, [[MOVEREG10]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define zeroext i32 @_Z7testuiff(float %arg) {
> > +entry:
> > +  %arg.addr = alloca float, align 4
> > +  store float %arg, float* %arg.addr, align 4
> > +  %0 = load float, float* %arg.addr, align 4
> > +  %conv = fptoui float %0 to i32
> > +  ret i32 %conv
> > +; CHECK-LABEL: @_Z7testuiff
> > +; CHECK: xscvdpuxws [[CONVREG11:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG11]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define float @_Z7testfuij(i32 zeroext %arg) {
> > +entry:
> > +  %arg.addr = alloca i32, align 4
> > +  store i32 %arg, i32* %arg.addr, align 4
> > +  %0 = load i32, i32* %arg.addr, align 4
> > +  %conv = uitofp i32 %0 to float
> > +  ret float %conv
> > +; CHECK-LABEL: @_Z7testfuij
> > +; CHECK: mtvsrwz [[MOVEREG11:[0-9]+]], 3
> > +; FIXME: Once we have XSCVUXDSP implemented, this will change
> > +; CHECK: fcfidus 1, [[MOVEREG11]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define zeroext i32 @_Z7testuidd(double %arg) {
> > +entry:
> > +  %arg.addr = alloca double, align 8
> > +  store double %arg, double* %arg.addr, align 8
> > +  %0 = load double, double* %arg.addr, align 8
> > +  %conv = fptoui double %0 to i32
> > +  ret i32 %conv
> > +; CHECK-LABEL: @_Z7testuidd
> > +; CHECK: xscvdpuxws [[CONVREG12:[0-9]+]], 1
> > +; CHECK: mfvsrwz 3, [[CONVREG12]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define double @_Z7testduij(i32 zeroext %arg) {
> > +entry:
> > +  %arg.addr = alloca i32, align 4
> > +  store i32 %arg, i32* %arg.addr, align 4
> > +  %0 = load i32, i32* %arg.addr, align 4
> > +  %conv = uitofp i32 %0 to double
> > +  ret double %conv
> > +; CHECK-LABEL: @_Z7testduij
> > +; CHECK: mtvsrwz [[MOVEREG12:[0-9]+]], 3
> > +; CHECK: xscvuxddp 1, [[MOVEREG12]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define i64 @_Z7testllff(float %arg) {
> > +entry:
> > +  %arg.addr = alloca float, align 4
> > +  store float %arg, float* %arg.addr, align 4
> > +  %0 = load float, float* %arg.addr, align 4
> > +  %conv = fptosi float %0 to i64
> > +  ret i64 %conv
> > +; CHECK-LABEL: @_Z7testllff
> > +; CHECK: xscvdpsxds [[CONVREG13:[0-9]+]], 1
> > +; CHECK: mfvsrd 3, [[CONVREG13]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define float @_Z7testfllx(i64 %arg) {
> > +entry:
> > +  %arg.addr = alloca i64, align 8
> > +  store i64 %arg, i64* %arg.addr, align 8
> > +  %0 = load i64, i64* %arg.addr, align 8
> > +  %conv = sitofp i64 %0 to float
> > +  ret float %conv
> > +; CHECK-LABEL:@_Z7testfllx
> > +; CHECK: mtvsrd [[MOVEREG13:[0-9]+]], 3
> > +; FIXME: Once we have XSCVSXDSP implemented, this will change
> > +; CHECK: fcfids 1, [[MOVEREG13]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define i64 @_Z7testlldd(double %arg) {
> > +entry:
> > +  %arg.addr = alloca double, align 8
> > +  store double %arg, double* %arg.addr, align 8
> > +  %0 = load double, double* %arg.addr, align 8
> > +  %conv = fptosi double %0 to i64
> > +  ret i64 %conv
> > +; CHECK-LABEL: @_Z7testlldd
> > +; CHECK: xscvdpsxds [[CONVREG14:[0-9]+]], 1
> > +; CHECK: mfvsrd 3, [[CONVREG14]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define double @_Z7testdllx(i64 %arg) {
> > +entry:
> > +  %arg.addr = alloca i64, align 8
> > +  store i64 %arg, i64* %arg.addr, align 8
> > +  %0 = load i64, i64* %arg.addr, align 8
> > +  %conv = sitofp i64 %0 to double
> > +  ret double %conv
> > +; CHECK-LABEL: @_Z7testdllx
> > +; CHECK: mtvsrd [[MOVEREG14:[0-9]+]], 3
> > +; CHECK: xscvsxddp 1, [[MOVEREG14]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define i64 @_Z8testullff(float %arg) {
> > +entry:
> > +  %arg.addr = alloca float, align 4
> > +  store float %arg, float* %arg.addr, align 4
> > +  %0 = load float, float* %arg.addr, align 4
> > +  %conv = fptoui float %0 to i64
> > +  ret i64 %conv
> > +; CHECK-LABEL: @_Z8testullff
> > +; CHECK: xscvdpuxds [[CONVREG15:[0-9]+]], 1
> > +; CHECK: mfvsrd 3, [[CONVREG15]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define float @_Z8testfully(i64 %arg) {
> > +entry:
> > +  %arg.addr = alloca i64, align 8
> > +  store i64 %arg, i64* %arg.addr, align 8
> > +  %0 = load i64, i64* %arg.addr, align 8
> > +  %conv = uitofp i64 %0 to float
> > +  ret float %conv
> > +; CHECK-LABEL: @_Z8testfully
> > +; CHECK: mtvsrd [[MOVEREG15:[0-9]+]], 3
> > +; FIXME: Once we have XSCVUXDSP implemented, this will change
> > +; CHECK: fcfidus 1, [[MOVEREG15]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define i64 @_Z8testulldd(double %arg) {
> > +entry:
> > +  %arg.addr = alloca double, align 8
> > +  store double %arg, double* %arg.addr, align 8
> > +  %0 = load double, double* %arg.addr, align 8
> > +  %conv = fptoui double %0 to i64
> > +  ret i64 %conv
> > +; CHECK-LABEL: @_Z8testulldd
> > +; CHECK: xscvdpuxds [[CONVREG16:[0-9]+]], 1
> > +; CHECK: mfvsrd 3, [[CONVREG16]]
> > +}
> > +
> > +; Function Attrs: nounwind
> > +define double @_Z8testdully(i64 %arg) {
> > +entry:
> > +  %arg.addr = alloca i64, align 8
> > +  store i64 %arg, i64* %arg.addr, align 8
> > +  %0 = load i64, i64* %arg.addr, align 8
> > +  %conv = uitofp i64 %0 to double
> > +  ret double %conv
> > +; CHECK-LABEL: @_Z8testdully
> > +; CHECK: mtvsrd [[MOVEREG16:[0-9]+]], 3
> > +; CHECK: xscvuxddp 1, [[MOVEREG16]]
> > +}
> > 
> > Modified: llvm/trunk/test/MC/Disassembler/PowerPC/vsx.txt
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/PowerPC/vsx.txt?rev=234682&r1=234681&r2=234682&view=diff
> > ==============================================================================
> > --- llvm/trunk/test/MC/Disassembler/PowerPC/vsx.txt (original)
> > +++ llvm/trunk/test/MC/Disassembler/PowerPC/vsx.txt Sat Apr 11
> > 05:40:42 2015
> > @@ -459,3 +459,17 @@
> >  # CHECK: xxpermdi 7, 63, 63, 2
> >  0xf0 0xff 0xfa 0x56
> >  
> > +# CHECK: mfvsrd 3, 0
> > +0x7c 0x03 0x00 0x66
> > +
> > +# CHECK: mfvsrwz 5, 0
> > +0x7c 0x05 0x00 0xe6
> > +
> > +# CHECK: mtvsrd 0, 3
> > +0x7c 0x03 0x01 0x66
> > +
> > +# CHECK: mtvsrwa 0, 3
> > +0x7c 0x03 0x01 0xa6
> > +
> > +# CHECK: mtvsrwz 0, 3
> > +0x7c 0x03 0x01 0xe6
> > 
> > Modified: llvm/trunk/test/MC/PowerPC/vsx.s
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/PowerPC/vsx.s?rev=234682&r1=234681&r2=234682&view=diff
> > ==============================================================================
> > --- llvm/trunk/test/MC/PowerPC/vsx.s (original)
> > +++ llvm/trunk/test/MC/PowerPC/vsx.s Sat Apr 11 05:40:42 2015
> > @@ -454,3 +454,20 @@
> >  # CHECK-BE: xxpermdi 7, 63, 63, 2              # encoding:
> >  [0xf0,0xff,0xfa,0x56]
> >  # CHECK-LE: xxpermdi 7, 63, 63, 2              # encoding:
> >  [0x56,0xfa,0xff,0xf0]
> >              xxswapd 7, 63
> > +
> > +# Move to/from VSR
> > +# CHECK-BE: mfvsrd 3, 0                        # encoding:
> > [0x7c,0x03,0x00,0x66]
> > +# CHECK-LE: mfvsrd 3, 0                        # encoding:
> > [0x66,0x00,0x03,0x7c]
> > +            mfvsrd 3, 0
> > +# CHECK-BE: mfvsrwz 5, 0                       # encoding:
> > [0x7c,0x05,0x00,0xe6]
> > +# CHECK-LE: mfvsrwz 5, 0                       # encoding:
> > [0xe6,0x00,0x05,0x7c]
> > +            mfvsrwz 5, 0
> > +# CHECK-BE: mtvsrd 0, 3                        # encoding:
> > [0x7c,0x03,0x01,0x66]
> > +# CHECK-LE: mtvsrd 0, 3                        # encoding:
> > [0x66,0x01,0x03,0x7c]
> > +            mtvsrd 0, 3
> > +# CHECK-BE: mtvsrwa 0, 3                       # encoding:
> > [0x7c,0x03,0x01,0xa6]
> > +# CHECK-LE: mtvsrwa 0, 3                       # encoding:
> > [0xa6,0x01,0x03,0x7c]
> > +            mtvsrwa 0, 3
> > +# CHECK-BE: mtvsrwz 0, 3                       # encoding:
> > [0x7c,0x03,0x01,0xe6]
> > +# CHECK-LE: mtvsrwz 0, 3                       # encoding:
> > [0xe6,0x01,0x03,0x7c]
> > +            mtvsrwz 0, 3
> > 
> > 
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> > 
> 
> --
> Hal Finkel
> Assistant Computational Scientist
> Leadership Computing Facility
> Argonne National Laboratory
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory



More information about the llvm-commits mailing list