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
This commit is contained in:
Jakub Jelinek 2018-11-29 15:23:21 +01:00 committed by Jakub Jelinek
parent 55da34ebc2
commit b076fecbc2
4 changed files with 68 additions and 8 deletions

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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;
}