[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