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

Hans Wennborg hans at chromium.org
Fri Jul 17 08:57:46 PDT 2015


Merged in r242530.

Thanks,
Hans

On Fri, Jul 17, 2015 at 8:45 AM, Hal Finkel <hfinkel at anl.gov> wrote:
> 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