re PR target/65527 (ICE: in expand_builtin_with_bounds, at builtins.c:7120 with -fcheck-pointer-bounds -mmpx)

gcc/

	PR target/65527
	* cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Add
	redirection for instrumented calls.
	* lto-wrapper.c (merge_and_complain): Merge -fcheck-pointer-bounds.
	(append_compiler_options): Append -fcheck-pointer-bounds.
	* tree-chkp.h (chkp_copy_call_skip_bounds): New.
	(chkp_redirect_edge): New.
	* tree-chkp.c (chkp_copy_call_skip_bounds): New.
	(chkp_redirect_edge): New.

gcc/testsuite/

	PR target/65527
	* gcc.target/i386/mpx/chkp-fix-calls-1.c: New.
	* gcc.target/i386/mpx/chkp-fix-calls-2.c: New.
	* gcc.target/i386/mpx/chkp-fix-calls-3.c: New.
	* gcc.target/i386/mpx/chkp-fix-calls-4.c: New.

From-SVN: r223929
This commit is contained in:
Ilya Enkovich 2015-06-01 11:24:07 +00:00 committed by Ilya Enkovich
parent f4fa7bb473
commit 8e9b277397
10 changed files with 191 additions and 5 deletions

View File

@ -1,3 +1,15 @@
2015-06-01 Ilya Enkovich <ilya.enkovich@intel.com>
PR target/65527
* cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Add
redirection for instrumented calls.
* lto-wrapper.c (merge_and_complain): Merge -fcheck-pointer-bounds.
(append_compiler_options): Append -fcheck-pointer-bounds.
* tree-chkp.h (chkp_copy_call_skip_bounds): New.
(chkp_redirect_edge): New.
* tree-chkp.c (chkp_copy_call_skip_bounds): New.
(chkp_redirect_edge): New.
2015-06-01 Richard Biener <rguenther@suse.de>
PR tree-optimization/66280

View File

@ -1281,6 +1281,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
tree lhs = gimple_call_lhs (e->call_stmt);
gcall *new_stmt;
gimple_stmt_iterator gsi;
bool skip_bounds = false;
#ifdef ENABLE_CHECKING
cgraph_node *node;
#endif
@ -1389,8 +1390,16 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
}
}
/* We might propagate instrumented function pointer into
not instrumented function and vice versa. In such a
case we need to either fix function declaration or
remove bounds from call statement. */
if (flag_check_pointer_bounds && e->callee)
skip_bounds = chkp_redirect_edge (e);
if (e->indirect_unknown_callee
|| decl == e->callee->decl)
|| (decl == e->callee->decl
&& !skip_bounds))
return e->call_stmt;
#ifdef ENABLE_CHECKING
@ -1415,13 +1424,19 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
}
}
if (e->callee->clone.combined_args_to_skip)
if (e->callee->clone.combined_args_to_skip
|| skip_bounds)
{
int lp_nr;
new_stmt
= gimple_call_copy_skip_args (e->call_stmt,
e->callee->clone.combined_args_to_skip);
new_stmt = e->call_stmt;
if (e->callee->clone.combined_args_to_skip)
new_stmt
= gimple_call_copy_skip_args (new_stmt,
e->callee->clone.combined_args_to_skip);
if (skip_bounds)
new_stmt = chkp_copy_call_skip_bounds (new_stmt);
gimple_call_set_fndecl (new_stmt, e->callee->decl);
gimple_call_set_fntype (new_stmt, gimple_call_fntype (e->call_stmt));

View File

@ -273,6 +273,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
case OPT_fwrapv:
case OPT_fopenmp:
case OPT_fopenacc:
case OPT_fcheck_pointer_bounds:
/* For selected options we can merge conservatively. */
for (j = 0; j < *decoded_options_count; ++j)
if ((*decoded_options)[j].opt_index == foption->opt_index)
@ -503,6 +504,7 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
case OPT_Ofast:
case OPT_Og:
case OPT_Os:
case OPT_fcheck_pointer_bounds:
break;
default:

View File

@ -1,3 +1,11 @@
2015-06-01 Ilya Enkovich <ilya.enkovich@intel.com>
PR target/65527
* gcc.target/i386/mpx/chkp-fix-calls-1.c: New.
* gcc.target/i386/mpx/chkp-fix-calls-2.c: New.
* gcc.target/i386/mpx/chkp-fix-calls-3.c: New.
* gcc.target/i386/mpx/chkp-fix-calls-4.c: New.
2015-06-01 Alan Lawrence <alan.lawrence@arm.com>
* gcc.target/aarch64/advsimd-intrinsics/advsimd-intrinsics.exp: Pass

View File

@ -0,0 +1,16 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fcheck-pointer-bounds -mmpx" } */
#include "math.h"
double
test1 (double x, double y, double (*fn)(double, double))
{
return fn (x, y);
}
double
test2 (double x, double y)
{
return test1 (x, y, copysign);
}

View File

@ -0,0 +1,16 @@
/* { dg-do compile } */
/* { dg-options "-O3 -fcheck-pointer-bounds -mmpx -fno-inline" } */
#include "math.h"
double
test1 (double x, double y, double (*fn)(double, double))
{
return fn (x, y);
}
double
test2 (double x, double y)
{
return test1 (x, y, copysign);
}

View File

@ -0,0 +1,33 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fexceptions -fcheck-pointer-bounds -mmpx" } */
extern int f2 (const char*, int, ...);
extern long int f3 (int *);
extern void err (void) __attribute__((__error__("error")));
extern __inline __attribute__ ((__always_inline__)) int
f1 (int i, ...)
{
if (__builtin_constant_p (i))
{
if (i)
err ();
return f2 ("", i);
}
return f2 ("", i);
}
int
test ()
{
int i;
if (f1 (0))
if (f3 (&i))
i = 0;
return i;
}

View File

@ -0,0 +1,17 @@
/* { dg-do compile } */
/* { dg-options "-Os -fcheck-pointer-bounds -mmpx" } */
typedef void (func) (int *);
static inline void
bar (func f)
{
int i;
f (&i);
}
void
foo ()
{
bar (0);
}

View File

@ -529,6 +529,71 @@ chkp_insert_retbnd_call (tree bndval, tree retval,
return bndval;
}
/* Build a GIMPLE_CALL identical to CALL but skipping bounds
arguments. */
gcall *
chkp_copy_call_skip_bounds (gcall *call)
{
bitmap bounds;
unsigned i;
bitmap_obstack_initialize (NULL);
bounds = BITMAP_ALLOC (NULL);
for (i = 0; i < gimple_call_num_args (call); i++)
if (POINTER_BOUNDS_P (gimple_call_arg (call, i)))
bitmap_set_bit (bounds, i);
if (!bitmap_empty_p (bounds))
call = gimple_call_copy_skip_args (call, bounds);
gimple_call_set_with_bounds (call, false);
BITMAP_FREE (bounds);
bitmap_obstack_release (NULL);
return call;
}
/* Redirect edge E to the correct node according to call_stmt.
Return 1 if bounds removal from call_stmt should be done
instead of redirection. */
bool
chkp_redirect_edge (cgraph_edge *e)
{
bool instrumented = false;
tree decl = e->callee->decl;
if (e->callee->instrumentation_clone
|| chkp_function_instrumented_p (decl))
instrumented = true;
if (instrumented
&& !gimple_call_with_bounds_p (e->call_stmt))
e->redirect_callee (cgraph_node::get_create (e->callee->orig_decl));
else if (!instrumented
&& gimple_call_with_bounds_p (e->call_stmt)
&& !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDCL)
&& !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDCU)
&& !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDSTX))
{
if (e->callee->instrumented_version)
e->redirect_callee (e->callee->instrumented_version);
else
{
tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
/* Avoid bounds removal if all args will be removed. */
if (!args || TREE_VALUE (args) != void_type_node)
return true;
else
gimple_call_set_with_bounds (e->call_stmt, false);
}
}
return false;
}
/* Mark statement S to not be instrumented. */
static void
chkp_mark_stmt (gimple s)

View File

@ -56,5 +56,7 @@ extern bool chkp_gimple_call_builtin_p (gimple call,
extern void chkp_expand_bounds_reset_for_mem (tree mem, tree ptr);
extern tree chkp_insert_retbnd_call (tree bndval, tree retval,
gimple_stmt_iterator *gsi);
extern gcall *chkp_copy_call_skip_bounds (gcall *call);
extern bool chkp_redirect_edge (cgraph_edge *e);
#endif /* GCC_TREE_CHKP_H */