[rs6000] fix PR 88100, range check for vec_splat_{su}{8,16,32}
authorLi Jia He <helijia@linux.ibm.com>
Wed, 20 Feb 2019 02:35:39 +0000 (02:35 +0000)
committerLi Jia He <helijia@gcc.gnu.org>
Wed, 20 Feb 2019 02:35:39 +0000 (02:35 +0000)
GCC revision 259524 implemented range check for the vec_splat_{su}{8,16,32}
builtins.  However, as a consequence of the implementation, the range check
is not done correctly for the expected vspltis[bhw] instructions.  The result
is that we may not get a valid error message if the valid range of the data
is exceeded.

Although the input of the function prototype of vec_splat_{su}{8,16,32} is
const int, the actual data usage range is limited to the data range of 5 bits
signed.  We should limit the int_cst.val[0] data to the 5 bit signed data range
without any modification in the input arg0 parameter.  However, the sext_hwi
function intercepts the data of TREE_INT_CST_LOW (arg0) as size bits in the
sext_hwi (TREE_INT_CST_LOW (arg0), size) statement.  This will cause some of
the excess data to fall within the range of 5 bits signed, so that the correct
diagnostic information cannot be generated, we need to remove the sext_hwi to
ensure that the input data has not been modified.

This patch fix range check for the vec_splat_s[8,16,32] builtins.  The argument
must be a 5-bit const int as specified for the vspltis[bhw] instructions.

for gcc/ChangeLog

PR target/88100
* gcc/config/rs6000/rs6000.c (rs6000_gimple_fold_builtin)
<case ALTIVEC_BUILTIN_VSPLTISB, ALTIVEC_BUILTIN_VSPLTISH,
ALTIVEC_BUILTIN_VSPLTISW>: Don't convert the operand before
range checking it.

for gcc/testsuite/ChangeLog

PR target/88100
* gcc/testsuite/gcc.target/powerpc/pr88100.c: New testcase.

From-SVN: r269033

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/pr88100.c [new file with mode: 0644]

index 4cd8ad6d82ff11e29ac4cbe8dddb00ce1b1396cc..b18b23cef5effddc82e0660d16cc51a86918eff3 100644 (file)
@@ -1,3 +1,11 @@
+2019-02-20  Li Jia He  <helijia@linux.ibm.com>
+
+       PR target/88100
+       * gcc/config/rs6000/rs6000.c (rs6000_gimple_fold_builtin)
+       <case ALTIVEC_BUILTIN_VSPLTISB, ALTIVEC_BUILTIN_VSPLTISH,
+       ALTIVEC_BUILTIN_VSPLTISW>: Don't convert the operand before
+       range checking it.
+
 2019-02-19  Jonathan Wakely  <jwakely@redhat.com>
 
        * config/gcn/gcn.c (print_operand): Fix typo.
index aea7925d4cfab670e978e79673a19c7ce1880d7b..b1249bcf7167e6ff48c1f32f5c1b0a1ce10be948 100644 (file)
@@ -16105,22 +16105,13 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
     case ALTIVEC_BUILTIN_VSPLTISH:
     case ALTIVEC_BUILTIN_VSPLTISW:
       {
-       int size;
-       if (fn_code == ALTIVEC_BUILTIN_VSPLTISB)
-         size = 8;
-       else if (fn_code == ALTIVEC_BUILTIN_VSPLTISH)
-         size = 16;
-       else
-         size = 32;
-
        arg0 = gimple_call_arg (stmt, 0);
        lhs = gimple_call_lhs (stmt);
 
        /* Only fold the vec_splat_*() if the lower bits of arg 0 is a
           5-bit signed constant in range -16 to +15.  */
        if (TREE_CODE (arg0) != INTEGER_CST
-           || !IN_RANGE (sext_hwi (TREE_INT_CST_LOW (arg0), size),
-                         -16, 15))
+           || !IN_RANGE (TREE_INT_CST_LOW (arg0), -16, 15))
          return false;
        gimple_seq stmts = NULL;
        location_t loc = gimple_location (stmt);
index 0bb6a5dc98633033dbe2b882eb16a3da5071005b..231a6f3bc6fb48eb77bfe1d362bbd8a2bc25e8bb 100644 (file)
@@ -1,3 +1,8 @@
+2019-02-20  Li Jia He  <helijia@linux.ibm.com>
+
+       PR target/88100
+       * gcc/testsuite/gcc.target/powerpc/pr88100.c: New testcase.
+
 2019-02-19  Wilco Dijkstra  <wdijkstr@arm.com>
 
        * gcc.target/arm/pr88850.c: Block -mfloat-abi override.
diff --git a/gcc/testsuite/gcc.target/powerpc/pr88100.c b/gcc/testsuite/gcc.target/powerpc/pr88100.c
new file mode 100644 (file)
index 0000000..4452145
--- /dev/null
@@ -0,0 +1,44 @@
+/* PR88100.  Verify that rs6000 gimple-folding code handles the
+   vec_splat_{su}{8,16,32} invalid data properly. */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec" } */
+
+#include <altivec.h>
+
+vector unsigned char
+splatu1 (void)
+{
+  return vec_splat_u8(0x100);/* { dg-error "argument 1 must be a 5-bit signed literal" } */
+}
+
+vector unsigned short
+splatu2 (void)
+{
+  return vec_splat_u16(0x10000);/* { dg-error "argument 1 must be a 5-bit signed literal" } */
+}
+
+vector unsigned int
+splatu3 (void)
+{
+  return vec_splat_u32(0x10000000);/* { dg-error "argument 1 must be a 5-bit signed literal" } */
+}
+
+vector signed char
+splats1 (void)
+{
+  return vec_splat_s8(0x100);/* { dg-error "argument 1 must be a 5-bit signed literal" } */
+}
+
+vector signed short
+splats2 (void)
+{
+  return vec_splat_s16(0x10000);/* { dg-error "argument 1 must be a 5-bit signed literal" } */
+}
+
+vector signed int
+splats3 (void)
+{
+  return vec_splat_s32(0x10000000);/* { dg-error "argument 1 must be a 5-bit signed literal" } */
+}