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

Hal Finkel hfinkel at anl.gov
Fri Jul 17 08:45:19 PDT 2015


Hi Hans,

I approve this for the release branch.

Thanks again,
Hal

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

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



More information about the llvm-commits mailing list