mirror of git://gcc.gnu.org/git/gcc.git
tree-chkp.c (chkp_get_hard_register_var_fake_base_address): New function.
gcc/ChangeLog:
2017-05-09 Alexander Ivchenko <aivchenk@gmail.com>
* tree-chkp.c (chkp_get_hard_register_var_fake_base_address):
New function.
(chkp_get_hard_register_fake_addr_expr): Ditto.
(chkp_build_addr_expr): Add check for hard reg case.
(chkp_parse_array_and_component_ref): Ditto.
(chkp_find_bounds_1): Ditto.
(chkp_process_stmt): Don't generate bounds store for
hard reg case.
gcc/testsuite/ChangeLog:
2017-05-09 Alexander Ivchenko <aivchenk@gmail.com>
* gcc.target/i386/mpx/hard-reg-2-lbv.c: New test.
* gcc.target/i386/mpx/hard-reg-2-nov.c: New test.
* gcc.target/i386/mpx/hard-reg-2-ubv.c: New test.
From-SVN: r249015
This commit is contained in:
parent
b69d9ac6a9
commit
0036534fa3
|
|
@ -1,3 +1,14 @@
|
||||||
|
2017-06-08 Alexander Ivchenko <alexander.ivchenko@intel.com>
|
||||||
|
|
||||||
|
* tree-chkp.c (chkp_get_hard_register_var_fake_base_address):
|
||||||
|
New function.
|
||||||
|
(chkp_get_hard_register_fake_addr_expr): Ditto.
|
||||||
|
(chkp_build_addr_expr): Add check for hard reg case.
|
||||||
|
(chkp_parse_array_and_component_ref): Ditto.
|
||||||
|
(chkp_find_bounds_1): Ditto.
|
||||||
|
(chkp_process_stmt): Don't generate bounds store for
|
||||||
|
hard reg case.
|
||||||
|
|
||||||
2017-06-08 Jan Hubicka <hubicka@ucw.cz>
|
2017-06-08 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
* predict.c (maybe_hot_bb_p): Do not check profile status.
|
* predict.c (maybe_hot_bb_p): Do not check profile status.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2017-06-08 Alexander Ivchenko <alexander.ivchenko@intel.com>
|
||||||
|
|
||||||
|
* gcc.target/i386/mpx/hard-reg-2-lbv.c: New test.
|
||||||
|
* gcc.target/i386/mpx/hard-reg-2-nov.c: New test.
|
||||||
|
* gcc.target/i386/mpx/hard-reg-2-ubv.c: New test.
|
||||||
|
|
||||||
2017-06-08 Jan Hubicka <hubicka@ucw.cz>
|
2017-06-08 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
* g++.dg/tree-ssa/counts-1.C: New testcase.
|
* g++.dg/tree-ssa/counts-1.C: New testcase.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-shouldfail "bounds violation" } */
|
||||||
|
/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
|
||||||
|
|
||||||
|
|
||||||
|
#define SHOULDFAIL
|
||||||
|
|
||||||
|
#include "mpx-check.h"
|
||||||
|
|
||||||
|
typedef int v16 __attribute__((vector_size(16)));
|
||||||
|
|
||||||
|
int foo(int i) {
|
||||||
|
register v16 u asm("xmm0");
|
||||||
|
return u[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int mpx_test (int argc, const char **argv)
|
||||||
|
{
|
||||||
|
printf ("%d\n", foo (-1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
|
||||||
|
|
||||||
|
#include "mpx-check.h"
|
||||||
|
|
||||||
|
typedef int v16 __attribute__((vector_size(16)));
|
||||||
|
|
||||||
|
int foo (int i) {
|
||||||
|
register v16 u asm ("xmm0");
|
||||||
|
return u[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int mpx_test (int argc, const char **argv)
|
||||||
|
{
|
||||||
|
printf ("%d\n", foo (3));
|
||||||
|
printf ("%d\n", foo (0));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-shouldfail "bounds violation" } */
|
||||||
|
/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
|
||||||
|
|
||||||
|
|
||||||
|
#define SHOULDFAIL
|
||||||
|
|
||||||
|
#include "mpx-check.h"
|
||||||
|
|
||||||
|
typedef int v16 __attribute__((vector_size(16)));
|
||||||
|
|
||||||
|
int foo (int i) {
|
||||||
|
register v16 u asm ("xmm0");
|
||||||
|
return u[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int mpx_test (int argc, const char **argv)
|
||||||
|
{
|
||||||
|
printf ("%d\n", foo (5));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -327,6 +327,8 @@ static void chkp_parse_array_and_component_ref (tree node, tree *ptr,
|
||||||
bool innermost_bounds);
|
bool innermost_bounds);
|
||||||
static void chkp_parse_bit_field_ref (tree node, location_t loc,
|
static void chkp_parse_bit_field_ref (tree node, location_t loc,
|
||||||
tree *offset, tree *size);
|
tree *offset, tree *size);
|
||||||
|
static tree
|
||||||
|
chkp_make_addressed_object_bounds (tree obj, gimple_stmt_iterator *iter);
|
||||||
|
|
||||||
#define chkp_bndldx_fndecl \
|
#define chkp_bndldx_fndecl \
|
||||||
(targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDLDX))
|
(targetm.builtin_chkp_function (BUILT_IN_CHKP_BNDLDX))
|
||||||
|
|
@ -679,6 +681,45 @@ chkp_erase_completed_bounds (void)
|
||||||
chkp_completed_bounds_set = new hash_set<tree>;
|
chkp_completed_bounds_set = new hash_set<tree>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function is used to provide a base address for
|
||||||
|
chkp_get_hard_register_fake_addr_expr. */
|
||||||
|
static tree
|
||||||
|
chkp_get_hard_register_var_fake_base_address ()
|
||||||
|
{
|
||||||
|
tree base = fold_convert (ptr_type_node, integer_zero_node);
|
||||||
|
unsigned HOST_WIDE_INT offset = 1 << (TYPE_PRECISION (ptr_type_node) - 1);
|
||||||
|
return fold_build_pointer_plus_hwi (base, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we check bounds for a hard register variable, we cannot
|
||||||
|
use its address - it is illegal, so instead of that we use
|
||||||
|
this fake value. */
|
||||||
|
static tree
|
||||||
|
chkp_get_hard_register_fake_addr_expr (tree obj)
|
||||||
|
{
|
||||||
|
tree addr = chkp_get_hard_register_var_fake_base_address ();
|
||||||
|
tree outer = obj;
|
||||||
|
while (TREE_CODE (outer) == COMPONENT_REF || TREE_CODE (outer) == ARRAY_REF)
|
||||||
|
{
|
||||||
|
if (TREE_CODE (outer) == COMPONENT_REF)
|
||||||
|
{
|
||||||
|
addr = fold_build_pointer_plus (addr,
|
||||||
|
component_ref_field_offset (outer));
|
||||||
|
outer = TREE_OPERAND (outer, 0);
|
||||||
|
}
|
||||||
|
else if (TREE_CODE (outer) == ARRAY_REF)
|
||||||
|
{
|
||||||
|
tree indx = fold_convert(size_type_node, TREE_OPERAND(outer, 1));
|
||||||
|
tree offset = size_binop (MULT_EXPR,
|
||||||
|
array_ref_element_size (outer), indx);
|
||||||
|
addr = fold_build_pointer_plus (addr, offset);
|
||||||
|
outer = TREE_OPERAND (outer, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
/* Mark BOUNDS associated with PTR as incomplete. */
|
/* Mark BOUNDS associated with PTR as incomplete. */
|
||||||
static void
|
static void
|
||||||
chkp_register_incomplete_bounds (tree bounds, tree ptr)
|
chkp_register_incomplete_bounds (tree bounds, tree ptr)
|
||||||
|
|
@ -1044,6 +1085,12 @@ chkp_add_modification_to_stmt_list (tree lhs,
|
||||||
static tree
|
static tree
|
||||||
chkp_build_addr_expr (tree obj)
|
chkp_build_addr_expr (tree obj)
|
||||||
{
|
{
|
||||||
|
/* We first check whether it is a "hard reg case". */
|
||||||
|
tree base = get_base_address (obj);
|
||||||
|
if (VAR_P (base) && DECL_HARD_REGISTER (base))
|
||||||
|
return chkp_get_hard_register_fake_addr_expr (obj);
|
||||||
|
|
||||||
|
/* If not - return regular ADDR_EXPR. */
|
||||||
return TREE_CODE (obj) == TARGET_MEM_REF
|
return TREE_CODE (obj) == TARGET_MEM_REF
|
||||||
? tree_mem_ref_addr (ptr_type_node, obj)
|
? tree_mem_ref_addr (ptr_type_node, obj)
|
||||||
: build_fold_addr_expr (obj);
|
: build_fold_addr_expr (obj);
|
||||||
|
|
@ -3442,6 +3489,13 @@ chkp_parse_array_and_component_ref (tree node, tree *ptr,
|
||||||
|| TREE_CODE (var) == SSA_NAME);
|
|| TREE_CODE (var) == SSA_NAME);
|
||||||
|
|
||||||
*ptr = chkp_build_addr_expr (var);
|
*ptr = chkp_build_addr_expr (var);
|
||||||
|
|
||||||
|
/* For hard register cases chkp_build_addr_expr returns INTEGER_CST
|
||||||
|
and later on chkp_find_bounds will fail to find proper bounds.
|
||||||
|
In order to avoid that, we find/create bounds right aways using
|
||||||
|
the var itself. */
|
||||||
|
if (VAR_P (var) && DECL_HARD_REGISTER (var))
|
||||||
|
*bounds = chkp_make_addressed_object_bounds (var, iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In this loop we are trying to find a field access
|
/* In this loop we are trying to find a field access
|
||||||
|
|
@ -3646,6 +3700,11 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, gimple_stmt_iterator *iter)
|
||||||
case ARRAY_REF:
|
case ARRAY_REF:
|
||||||
case COMPONENT_REF:
|
case COMPONENT_REF:
|
||||||
addr = get_base_address (ptr_src);
|
addr = get_base_address (ptr_src);
|
||||||
|
if (VAR_P (addr) && DECL_HARD_REGISTER (addr))
|
||||||
|
{
|
||||||
|
bounds = chkp_get_zero_bounds ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (DECL_P (addr)
|
if (DECL_P (addr)
|
||||||
|| TREE_CODE (addr) == MEM_REF
|
|| TREE_CODE (addr) == MEM_REF
|
||||||
|| TREE_CODE (addr) == TARGET_MEM_REF)
|
|| TREE_CODE (addr) == TARGET_MEM_REF)
|
||||||
|
|
@ -3989,6 +4048,7 @@ chkp_process_stmt (gimple_stmt_iterator *iter, tree node,
|
||||||
tree addr_last = NULL_TREE; /* address of the last accessed byte */
|
tree addr_last = NULL_TREE; /* address of the last accessed byte */
|
||||||
tree ptr = NULL_TREE; /* a pointer used for dereference */
|
tree ptr = NULL_TREE; /* a pointer used for dereference */
|
||||||
tree bounds = NULL_TREE;
|
tree bounds = NULL_TREE;
|
||||||
|
bool reg_store = false;
|
||||||
|
|
||||||
/* We do not need instrumentation for clobbers. */
|
/* We do not need instrumentation for clobbers. */
|
||||||
if (dirflag == integer_one_node
|
if (dirflag == integer_one_node
|
||||||
|
|
@ -4103,6 +4163,13 @@ chkp_process_stmt (gimple_stmt_iterator *iter, tree node,
|
||||||
addr_last = fold_build_pointer_plus_loc (loc, addr_last, access_offs);
|
addr_last = fold_build_pointer_plus_loc (loc, addr_last, access_offs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dirflag == integer_one_node)
|
||||||
|
{
|
||||||
|
tree base = get_base_address (node);
|
||||||
|
if (VAR_P (base) && DECL_HARD_REGISTER (base))
|
||||||
|
reg_store = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Generate bndcl/bndcu checks if memory access is not safe. */
|
/* Generate bndcl/bndcu checks if memory access is not safe. */
|
||||||
if (!safe)
|
if (!safe)
|
||||||
{
|
{
|
||||||
|
|
@ -4117,6 +4184,7 @@ chkp_process_stmt (gimple_stmt_iterator *iter, tree node,
|
||||||
|
|
||||||
/* We need to store bounds in case pointer is stored. */
|
/* We need to store bounds in case pointer is stored. */
|
||||||
if (dirflag == integer_one_node
|
if (dirflag == integer_one_node
|
||||||
|
&& !reg_store
|
||||||
&& chkp_type_has_pointer (node_type)
|
&& chkp_type_has_pointer (node_type)
|
||||||
&& flag_chkp_store_bounds)
|
&& flag_chkp_store_bounds)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue