]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR target/79261 (vec_xxpermdi appears to have endian issues)
authorBill Schmidt <wschmidt@linux.vnet.ibm.com>
Wed, 22 Feb 2017 22:54:56 +0000 (22:54 +0000)
committerWilliam Schmidt <wschmidt@gcc.gnu.org>
Wed, 22 Feb 2017 22:54:56 +0000 (22:54 +0000)
[gcc]

2017-02-22  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

Backport from mainline
2017-02-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

PR target/79261
* config/rs6000/rs6000.c (rs6000_expand_ternop_builtin): Add
support for CODE_FOR_vsx_xxpermdi_v2d[fi]_be.
* config/rs6000/rs6000.md (reload_gpr_from_vsx<mode>): Call
generator for vsx_xxpermdi_<mode>_be.
* config/rs6000/vsx.md (vsx_xxpermdi_<mode>): Remove logic to
force big-endian semantics.
(vsx_xxpermdi_<mode>_be): New define_expand with same
implementation as previous version of vsx_xxpermdi_<mode>.

[gcc/testsuite]

2017-02-22  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

Backport from mainline
2017-02-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>

PR target/79261
* gcc.target/powerpc/vec-xxpermdi.c: New file.

From-SVN: r245664

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/vsx.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/vec-xxpermdi.c [new file with mode: 0644]

index ec6bc7a408440f5720d2dd32d8cac242e8681238..1c1fec575ce4090f033751172b814e4ab2d4c510 100644 (file)
@@ -1,3 +1,18 @@
+2017-02-22  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       Backport from mainline
+       2017-02-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       PR target/79261
+       * config/rs6000/rs6000.c (rs6000_expand_ternop_builtin): Add
+       support for CODE_FOR_vsx_xxpermdi_v2d[fi]_be.
+       * config/rs6000/rs6000.md (reload_gpr_from_vsx<mode>): Call
+       generator for vsx_xxpermdi_<mode>_be.
+       * config/rs6000/vsx.md (vsx_xxpermdi_<mode>): Remove logic to
+       force big-endian semantics.
+       (vsx_xxpermdi_<mode>_be): New define_expand with same
+       implementation as previous version of vsx_xxpermdi_<mode>.
+
 2017-02-19  Dominique d'Humieres  <dominiq@lps.ens.fr>
 
        PR target/71017
index 234d277637b248e35631fef1c51f217476668c2c..63b65dac4ccaeb874800ce2f6c7a9b92922c9b52 100644 (file)
@@ -12962,6 +12962,8 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
     }
   else if (icode == CODE_FOR_vsx_xxpermdi_v2df
            || icode == CODE_FOR_vsx_xxpermdi_v2di
+           || icode == CODE_FOR_vsx_xxpermdi_v2df_be
+           || icode == CODE_FOR_vsx_xxpermdi_v2di_be
            || icode == CODE_FOR_vsx_xxsldwi_v16qi
            || icode == CODE_FOR_vsx_xxsldwi_v8hi
            || icode == CODE_FOR_vsx_xxsldwi_v4si
index 20580591a68aa623ae91741f31ecb667cf75d292..526bf329fce8ff5223efef8c2cc3b813a9d38ba5 100644 (file)
   rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
 
   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
-  emit_insn (gen_vsx_xxpermdi_<mode> (tmp, src, src, GEN_INT (3)));
+  emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
   emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
 }
   [(set_attr "length" "12")
index efbd3ecccb8ee70af71f4c21d1ccc5f350c6a1f1..9fa3b6718b38a544ce99e01cbd2dac985c13918f 100644 (file)
   rtx perm1 = GEN_INT ((mask & 1) + 2);
   rtx (*gen) (rtx, rtx, rtx, rtx, rtx);
 
+  if (<MODE>mode == V2DFmode)
+    gen = gen_vsx_xxpermdi2_v2df_1;
+  else
+    {
+      gen = gen_vsx_xxpermdi2_v2di_1;
+      if (<MODE>mode != V2DImode)
+       {
+         target = gen_lowpart (V2DImode, target);
+         op0 = gen_lowpart (V2DImode, op0);
+         op1 = gen_lowpart (V2DImode, op1);
+       }
+    }
+  emit_insn (gen (target, op0, op1, perm0, perm1));
+  DONE;
+})
+
+;; Special version of xxpermdi that retains big-endian semantics.
+(define_expand "vsx_xxpermdi_<mode>_be"
+  [(match_operand:VSX_L 0 "vsx_register_operand" "")
+   (match_operand:VSX_L 1 "vsx_register_operand" "")
+   (match_operand:VSX_L 2 "vsx_register_operand" "")
+   (match_operand:QI 3 "u5bit_cint_operand" "")]
+  "VECTOR_MEM_VSX_P (<MODE>mode)"
+{
+  rtx target = operands[0];
+  rtx op0 = operands[1];
+  rtx op1 = operands[2];
+  int mask = INTVAL (operands[3]);
+  rtx perm0 = GEN_INT ((mask >> 1) & 1);
+  rtx perm1 = GEN_INT ((mask & 1) + 2);
+  rtx (*gen) (rtx, rtx, rtx, rtx, rtx);
+
   if (<MODE>mode == V2DFmode)
     gen = gen_vsx_xxpermdi2_v2df_1;
   else
index 580c2f6459bdd223ced32cea1283e44b361dc3d2..3fb7dba7672d41070ba20e82141fb936f2e9e063 100644 (file)
@@ -1,3 +1,11 @@
+2017-02-22  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       Backport from mainline
+       2017-02-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
+
+       PR target/79261
+       * gcc.target/powerpc/vec-xxpermdi.c: New file.
+
 2017-01-16  Carl Love  <cel@us.ibm.com>
 
        Backport from mainline commit r245460 on 2017-02-14
@@ -7,6 +15,7 @@
        xvcvsxdsp and xvcvuxdsp instructions.
 
 2017-02-06  Carl Love  <cel@us.ibm.com>
+
        * gcc.target/powerpc/builtins-3-p8.c:  Add new testfile for missing
        vec_packs built-in tests.
 
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-xxpermdi.c b/gcc/testsuite/gcc.target/powerpc/vec-xxpermdi.c
new file mode 100644 (file)
index 0000000..d56276a
--- /dev/null
@@ -0,0 +1,68 @@
+/* { dg-do run { target { powerpc64*-*-* && vsx_hw } } } */
+/* { dg-options "-O2 -mvsx" } */
+
+/* Added for PR79261 to test that vec_xxpermdi works correctly for
+   both BE and LE targets.  */
+
+#include <altivec.h>
+void abort (void);
+
+vector double vdx = { 0.0, 1.0 };
+vector double vdy = { 2.0, 3.0 };
+vector double vdz;
+
+vector signed long long vsllx = { 0, 1 };
+vector signed long long vslly = { 2, 3 };
+vector signed long long vsllz;
+
+vector float vfx = { 0.0, 1.0, 2.0, 3.0 };
+vector float vfy = { 4.0, 5.0, 6.0, 7.0 };
+vector float vfz;
+
+vector signed int vsix = { 0, 1, 2, 3 };
+vector signed int vsiy = { 4, 5, 6, 7 };
+vector signed int vsiz;
+
+vector signed short vssx = { 0, 1, 2, 3, 4, 5, 6, 7 };
+vector signed short vssy = { 8, 9, 10, 11, 12, 13, 14, 15 };
+vector signed short vssz;
+
+vector signed char vscx = { 0, 1, 2, 3, 4, 5, 6, 7,
+                           8, 9, 10, 11, 12, 13, 14, 15 };
+vector signed char vscy = { 16, 17, 18, 19, 20, 21, 22, 23,
+                           24, 25, 26, 27, 28, 29, 30, 31 };
+vector signed char vscz;
+
+int
+main ()
+{
+  vdz = vec_xxpermdi (vdx, vdy, 0b01);
+  if (vdz[0] != 0.0 || vdz[1] != 3.0)
+    abort ();
+
+  vsllz = vec_xxpermdi (vsllx, vslly, 0b10);
+  if (vsllz[0] != 1 || vsllz[1] != 2)
+    abort ();
+
+  vfz = vec_xxpermdi (vfx, vfy, 0b01);
+  if (vfz[0] != 0.0 || vfz[1] != 1.0 || vfz[2] != 6.0 || vfz[3] != 7.0)
+    abort ();
+
+  vsiz = vec_xxpermdi (vsix, vsiy, 0b10);
+  if (vsiz[0] != 2 || vsiz[1] != 3 || vsiz[2] != 4 || vsiz[3] != 5)
+    abort ();
+
+  vssz = vec_xxpermdi (vssx, vssy, 0b00);
+  if (vssz[0] != 0 || vssz[1] != 1 || vssz[2] != 2 || vssz[3] != 3
+      || vssz[4] != 8 || vssz[5] != 9 || vssz[6] != 10 || vssz[7] != 11)
+    abort ();
+
+  vscz = vec_xxpermdi (vscx, vscy, 0b11);
+  if (vscz[0] != 8 || vscz[1] != 9 || vscz[2] != 10 || vscz[3] != 11
+      || vscz[4] != 12 || vscz[5] != 13 || vscz[6] != 14 || vscz[7] != 15
+      || vscz[8] != 24 || vscz[9] != 25 || vscz[10] != 26 || vscz[11] != 27
+      || vscz[12] != 28 || vscz[13] != 29 || vscz[14] != 30 || vscz[15] != 31)
+    abort ();
+
+  return 0;
+}