From: Jakub Jelinek Date: Thu, 29 Nov 2018 14:23:21 +0000 (+0100) Subject: re PR target/88234 (UBsan and runtime error: signed integer overflow using unsigned... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b076fecbc240380b25bb25c65aae85c4b5ea9ce5;p=gcc.git re PR target/88234 (UBsan and runtime error: signed integer overflow using unsigned vector) 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. * gcc.dg/ubsan/pr88234.c: New test. From-SVN: r266619 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 33c307f65b1..5fe36e07b9c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-11-29 Jakub Jelinek + + 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 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 cf5d0cb236f..b2fb5c898b3 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 18a921ceaef..0e908be06d1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-11-29 Jakub Jelinek + + PR target/88234 + * gcc.dg/ubsan/pr88234.c: New test. + 2018-11-29 Richard Biener 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 00000000000..2983cd88aa0 --- /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 + +__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; +}