From: Bill Schmidt Date: Wed, 22 Feb 2017 22:54:56 +0000 (+0000) Subject: backport: re PR target/79261 (vec_xxpermdi appears to have endian issues) X-Git-Tag: releases/gcc-5.5.0~506 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c0d93545ed8b5ef0d8ed96a27981732cbb961062;p=thirdparty%2Fgcc.git backport: re PR target/79261 (vec_xxpermdi appears to have endian issues) [gcc] 2017-02-22 Bill Schmidt Backport from mainline 2017-02-17 Bill Schmidt 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): Call generator for vsx_xxpermdi__be. * config/rs6000/vsx.md (vsx_xxpermdi_): Remove logic to force big-endian semantics. (vsx_xxpermdi__be): New define_expand with same implementation as previous version of vsx_xxpermdi_. [gcc/testsuite] 2017-02-22 Bill Schmidt Backport from mainline 2017-02-17 Bill Schmidt PR target/79261 * gcc.target/powerpc/vec-xxpermdi.c: New file. From-SVN: r245664 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ec6bc7a40844..1c1fec575ce4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2017-02-22 Bill Schmidt + + Backport from mainline + 2017-02-17 Bill Schmidt + + 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): Call + generator for vsx_xxpermdi__be. + * config/rs6000/vsx.md (vsx_xxpermdi_): Remove logic to + force big-endian semantics. + (vsx_xxpermdi__be): New define_expand with same + implementation as previous version of vsx_xxpermdi_. + 2017-02-19 Dominique d'Humieres PR target/71017 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 234d277637b2..63b65dac4cca 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 20580591a68a..526bf329fce8 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -8905,7 +8905,7 @@ rtx gpr_lo_reg = gen_lowpart (DFmode, dest); emit_insn (gen_p8_mfvsrd_3_ (gpr_hi_reg, src)); - emit_insn (gen_vsx_xxpermdi_ (tmp, src, src, GEN_INT (3))); + emit_insn (gen_vsx_xxpermdi__be (tmp, src, src, GEN_INT (3))); emit_insn (gen_p8_mfvsrd_3_ (gpr_lo_reg, tmp)); } [(set_attr "length" "12") diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index efbd3ecccb8e..9fa3b6718b38 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -1936,6 +1936,38 @@ rtx perm1 = GEN_INT ((mask & 1) + 2); rtx (*gen) (rtx, rtx, rtx, rtx, rtx); + if (mode == V2DFmode) + gen = gen_vsx_xxpermdi2_v2df_1; + else + { + gen = gen_vsx_xxpermdi2_v2di_1; + if (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__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)" +{ + 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 == V2DFmode) gen = gen_vsx_xxpermdi2_v2df_1; else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 580c2f6459bd..3fb7dba7672d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2017-02-22 Bill Schmidt + + Backport from mainline + 2017-02-17 Bill Schmidt + + PR target/79261 + * gcc.target/powerpc/vec-xxpermdi.c: New file. + 2017-01-16 Carl Love Backport from mainline commit r245460 on 2017-02-14 @@ -7,6 +15,7 @@ xvcvsxdsp and xvcvuxdsp instructions. 2017-02-06 Carl Love + * 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 index 000000000000..d56276a3dd95 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-xxpermdi.c @@ -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 +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; +}