aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/rs6000/rs6000.c34
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/pr88234.c29
4 files changed, 68 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 33c307f..5fe36e0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2018-11-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/88234
+ * config/rs6000/rs6000.c (rs6000_gimple_fold_builtin): For
+ vec_add and vec_sub builtins, perform PLUS_EXPR or MINUS_EXPR
+ in unsigned_type_for instead of vector integral type where overflow
+ doesn't wrap.
+
2018-11-29 Michael Ploujnikov <michael.ploujnikov@oracle.com>
There can be at most one .resolver clone per function
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index cf5d0cb..b2fb5c8 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -15371,6 +15371,7 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
enum rs6000_builtins fn_code
= (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
tree arg0, arg1, lhs, temp;
+ enum tree_code bcode;
gimple *g;
size_t uns_fncode = (size_t) fn_code;
@@ -15409,10 +15410,32 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
case P8V_BUILTIN_VADDUDM:
case ALTIVEC_BUILTIN_VADDFP:
case VSX_BUILTIN_XVADDDP:
+ bcode = PLUS_EXPR;
+ do_binary:
arg0 = gimple_call_arg (stmt, 0);
arg1 = gimple_call_arg (stmt, 1);
lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, PLUS_EXPR, arg0, arg1);
+ if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (lhs)))
+ && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (lhs))))
+ {
+ /* Ensure the binary operation is performed in a type
+ that wraps if it is integral type. */
+ gimple_seq stmts = NULL;
+ tree type = unsigned_type_for (TREE_TYPE (lhs));
+ tree uarg0 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+ type, arg0);
+ tree uarg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+ type, arg1);
+ tree res = gimple_build (&stmts, gimple_location (stmt), bcode,
+ type, uarg0, uarg1);
+ gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+ g = gimple_build_assign (lhs, VIEW_CONVERT_EXPR,
+ build1 (VIEW_CONVERT_EXPR,
+ TREE_TYPE (lhs), res));
+ gsi_replace (gsi, g, true);
+ return true;
+ }
+ g = gimple_build_assign (lhs, bcode, arg0, arg1);
gimple_set_location (g, gimple_location (stmt));
gsi_replace (gsi, g, true);
return true;
@@ -15424,13 +15447,8 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
case P8V_BUILTIN_VSUBUDM:
case ALTIVEC_BUILTIN_VSUBFP:
case VSX_BUILTIN_XVSUBDP:
- arg0 = gimple_call_arg (stmt, 0);
- arg1 = gimple_call_arg (stmt, 1);
- lhs = gimple_call_lhs (stmt);
- g = gimple_build_assign (lhs, MINUS_EXPR, arg0, arg1);
- gimple_set_location (g, gimple_location (stmt));
- gsi_replace (gsi, g, true);
- return true;
+ bcode = MINUS_EXPR;
+ goto do_binary;
case VSX_BUILTIN_XVMULSP:
case VSX_BUILTIN_XVMULDP:
arg0 = gimple_call_arg (stmt, 0);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 18a921c..0e908be 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2018-11-29 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/88234
+ * gcc.dg/ubsan/pr88234.c: New test.
+
2018-11-29 Richard Biener <rguenther@suse.de>
PR tree-optimization/88243
diff --git a/gcc/testsuite/gcc.dg/ubsan/pr88234.c b/gcc/testsuite/gcc.dg/ubsan/pr88234.c
new file mode 100644
index 0000000..2983cd8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/pr88234.c
@@ -0,0 +1,29 @@
+/* PR target/88234 */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-fsanitize=signed-integer-overflow -fno-sanitize-recover=signed-integer-overflow -O2 -maltivec" } */
+
+#include <altivec.h>
+
+__attribute__((noipa)) vector unsigned int
+f1 (vector unsigned int x, vector unsigned int y)
+{
+ return vec_add (x, y);
+}
+
+__attribute__((noipa)) vector unsigned int
+f2 (vector unsigned int x, vector unsigned int y)
+{
+ return vec_sub (x, y);
+}
+
+int
+main ()
+{
+ vector unsigned int x = { __INT_MAX__, -__INT_MAX__, __INT_MAX__ - 3, -__INT_MAX__ + 4 };
+ vector unsigned int y = { 1, -1, 4, -5 };
+ vector unsigned int z = f1 (x, y);
+ f2 (z, x);
+ f2 (z, y);
+ return 0;
+}