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:
parent
f4fa7bb473
commit
8e9b277397
@ -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
|
||||
|
25
gcc/cgraph.c
25
gcc/cgraph.c
@ -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));
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
16
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-1.c
Normal file
16
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-1.c
Normal 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);
|
||||
}
|
16
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-2.c
Normal file
16
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-2.c
Normal 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);
|
||||
}
|
33
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-3.c
Normal file
33
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-3.c
Normal 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;
|
||||
}
|
||||
|
||||
|
17
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-4.c
Normal file
17
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-4.c
Normal 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);
|
||||
}
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user