[llvm] r242296 - [PPC64LE] Fix vec_sld semantics for little endian

Bill Schmidt wschmidt at linux.vnet.ibm.com
Wed Jul 15 09:04:39 PDT 2015


On Wed, 2015-07-15 at 10:58 -0500, Hal Finkel wrote:
> Test case?
> 
>  -Hal

I forgot to mention this.  We have existing tests that just check for a
vperm that gets generated for vec_sld.  That is still the case.  I am
having trouble figuring out how to create a test case that gets more
information, primarily because I can't get clang -cc1 to stop at that
point rather than moving on and converting the vperm into a
shufflevector.  I'd be interested in any help with this.

Thanks,
Bill

> 
> ----- Original Message -----
> > From: "Bill Schmidt" <wschmidt at linux.vnet.ibm.com>
> > To: llvm-commits at cs.uiuc.edu
> > Sent: Wednesday, July 15, 2015 10:45:31 AM
> > Subject: [llvm] r242296 - [PPC64LE] Fix vec_sld semantics for little endian
> > 
> > Author: wschmidt
> > Date: Wed Jul 15 10:45:30 2015
> > New Revision: 242296
> > 
> > URL: http://llvm.org/viewvc/llvm-project?rev=242296&view=rev
> > Log:
> > [PPC64LE] Fix vec_sld semantics for little endian
> > 
> > The vec_sld interface provides access to the vsldoi instruction.
> > Unlike most of the vec_* interfaces, we do not attempt to change the
> > generated code for vec_sld based on the endian mode.  It is too
> > difficult to correctly infer the desired semantics because of
> > different element types, and the corrected instruction sequence is
> > expensive, involving loading a permute control vector and performing
> > a
> > generalized permute.
> > 
> > For GCC, this was implemented as "Don't touch the vec_sld"
> > implementation.  When it came time for the LLVM implementation, I did
> > the same thing.  However, this was hasty and incorrect.  In LLVM's
> > version of altivec.h, vec_sld was previously defined in terms of the
> > vec_perm interface.  Because vec_perm semantics are adjusted for
> > little endian, this means that leaving vec_sld untouched causes it to
> > generate something different for LE than for BE.  Not good.
> > 
> > This back-end patch accompanies the changes to altivec.h that change
> > vec_sld's behavior for little endian.  Those changes mean that we see
> > slightly different code in the back end when trying to recognize a
> > VSLDOI instruction in isVSLDOIShuffleMask.  In particular, a
> > ShuffleKind of 1 (where the two inputs are identical) must now be
> > treated the same way as a ShuffleKind of 2 (little endian with
> > different inputs) when little endian mode is in force.  This is
> > because ShuffleKind of 1 is defined using big-endian numbering.
> > 
> > This has a ripple effect on LowerBUILD_VECTOR, where we create our
> > own
> > internal VSLDOI instructions.  Because these are a ShuffleKind of 1,
> > they will now have their shift amounts subtracted from 16 when
> > recognizing the shuffle mask.  To avoid problems we have to subtract
> > them from 16 again before creating the VSLDOI instructions.
> > 
> > There are a couple of other uses of BuildVSLDOI, but these do not
> > need
> > to be modified because the shift amount is 8, which is unchanged when
> > subtracted from 16.
> > 
> > Modified:
> >     llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
> > 
> > Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
> > URL:
> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=242296&r1=242295&r2=242296&view=diff
> > ==============================================================================
> > --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
> > +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Wed Jul 15
> > 10:45:30 2015
> > @@ -1416,7 +1416,7 @@ int PPC::isVSLDOIShuffleMask(SDNode *N,
> >    } else
> >      return -1;
> >  
> > -  if (ShuffleKind == 2 && isLE)
> > +  if (isLE)
> >      ShiftAmt = 16 - ShiftAmt;
> >  
> >    return ShiftAmt;
> > @@ -7011,17 +7011,20 @@ SDValue PPCTargetLowering::LowerBUILD_VE
> >      // t = vsplti c, result = vsldoi t, t, 1
> >      if (SextVal == (int)(((unsigned)i << 8) | (i < 0 ? 0xFF : 0))) {
> >        SDValue T = BuildSplatI(i, SplatSize, MVT::v16i8, DAG, dl);
> > -      return BuildVSLDOI(T, T, 1, Op.getValueType(), DAG, dl);
> > +      unsigned Amt = Subtarget.isLittleEndian() ? 15 : 1;
> > +      return BuildVSLDOI(T, T, Amt, Op.getValueType(), DAG, dl);
> >      }
> >      // t = vsplti c, result = vsldoi t, t, 2
> >      if (SextVal == (int)(((unsigned)i << 16) | (i < 0 ? 0xFFFF :
> >      0))) {
> >        SDValue T = BuildSplatI(i, SplatSize, MVT::v16i8, DAG, dl);
> > -      return BuildVSLDOI(T, T, 2, Op.getValueType(), DAG, dl);
> > +      unsigned Amt = Subtarget.isLittleEndian() ? 14 : 2;
> > +      return BuildVSLDOI(T, T, Amt, Op.getValueType(), DAG, dl);
> >      }
> >      // t = vsplti c, result = vsldoi t, t, 3
> >      if (SextVal == (int)(((unsigned)i << 24) | (i < 0 ? 0xFFFFFF :
> >      0))) {
> >        SDValue T = BuildSplatI(i, SplatSize, MVT::v16i8, DAG, dl);
> > -      return BuildVSLDOI(T, T, 3, Op.getValueType(), DAG, dl);
> > +      unsigned Amt = Subtarget.isLittleEndian() ? 13 : 3;
> > +      return BuildVSLDOI(T, T, Amt, Op.getValueType(), DAG, dl);
> >      }
> >    }
> >  
> > 
> > 
> > _______________________________________________
> > 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