GCC Maintainers:

GCC revision 255549  implemented early gimple folding for the
vec_splat_s[8,16,32] builtins.  However, as a consequence of the
implementation, we lost error checking for out-of-range values for the
expected vspltis[bhw] instructions.  The result of not having the out-
of-range checking is we get and ICE.

This patch adds the missing error checking on argument zero 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.

The regression testing for the patch was done on GCC mainline on 

    powerpc64le-unknown-linux-gnu (Power 8 LE)

with no regressions.  Additional hand testing was done as well to test
the various cases such as

vec_splat_s8 (31)
vec_splat_s8 (32)
vec_splat_s8 (value) where "value" is an integer variable

to verify vector result is correct for a 5-bit const int argument (
i.e. 31).  The error message "error: argument 1 must be a 5-bit signed
literal" is generated in the other cases.

Please let me know if the patch looks OK for the GCC 7 branch.

                         Carl Love
---------------------------------------------------


gcc/ChangeLog:

2018-04-13  Carl Love  <c...@us.ibm.com>

        PR target/83402
        * config/rs6000/rs6000-c.c (rs6000_gimple_fold_builtin): Add
        size check for arg0.
---
 gcc/config/rs6000/rs6000.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index a0c9b5c..855be43 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -16576,8 +16576,9 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
       {
         arg0 = gimple_call_arg (stmt, 0);
         lhs = gimple_call_lhs (stmt);
-        /* Only fold the vec_splat_*() if arg0 is constant.  */
-        if (TREE_CODE (arg0) != INTEGER_CST)
+        /* Only fold the vec_splat_*() if arg0 is a 5-bit constant.  */
+        if (TREE_CODE (arg0) != INTEGER_CST
+            || TREE_INT_CST_LOW (arg0) & ~0x1f)
           return false;
         gimple_seq stmts = NULL;
         location_t loc = gimple_location (stmt);
-- 
2.7.4

Reply via email to