Hi, Here is the latest version of the patch with all comments addressed:
gcc/ChangeLog: 2017-05-09 Alexander Ivchenko <aivch...@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 <aivch...@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. * gcc.target/i386/mpx/hard-reg-3-1-lbv.c: New test. * gcc.target/i386/mpx/hard-reg-3-1-nov.c: New test. * gcc.target/i386/mpx/hard-reg-3-1-ubv.c: New test. * gcc.target/i386/mpx/hard-reg-3-2-lbv.c: New test. * gcc.target/i386/mpx/hard-reg-3-2-nov.c: New test. * gcc.target/i386/mpx/hard-reg-3-2-ubv.c: New test. * gcc.target/i386/mpx/hard-reg-3-lbv.c: New test. * gcc.target/i386/mpx/hard-reg-3-nov.c: New test. * gcc.target/i386/mpx/hard-reg-3-ubv.c: New test. * gcc.target/i386/mpx/hard-reg-4-1-lbv.c: New test. * gcc.target/i386/mpx/hard-reg-4-1-nov.c: New test. * gcc.target/i386/mpx/hard-reg-4-1-ubv.c: New test. * gcc.target/i386/mpx/hard-reg-4-2-lbv.c: New test. * gcc.target/i386/mpx/hard-reg-4-2-nov.c: New test. * gcc.target/i386/mpx/hard-reg-4-2-ubv.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c new file mode 100644 index 0000000..319e1ec --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c @@ -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; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c new file mode 100644 index 0000000..3c6d39a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c @@ -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; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c new file mode 100644 index 0000000..7fe76c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c @@ -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; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c new file mode 100644 index 0000000..7e4451f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-shouldfail "bounds violation" } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + +#define SHOULDFAIL + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1; + v8 s2f2; +}; + +int foo_s2f1 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f1.s1f[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f1 (-1)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c new file mode 100644 index 0000000..73bd7fb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1; + v8 s2f2; +}; + +int foo_s2f1 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f1.s1f[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f1 (0)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c new file mode 100644 index 0000000..166b6b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-shouldfail "bounds violation" } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + +#define SHOULDFAIL + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1; + v8 s2f2; +}; + +int foo_s2f1 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f1.s1f[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f1 (3)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c new file mode 100644 index 0000000..7820c2f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-shouldfail "bounds violation" } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + +#define SHOULDFAIL + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1; + v8 s2f2; +}; + +int foo_s2f2 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f2[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f2 (-1)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c new file mode 100644 index 0000000..0816e58 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1; + v8 s2f2; +}; + +int foo_s2f2 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f2[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f2 (0)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c new file mode 100644 index 0000000..94261a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c @@ -0,0 +1,33 @@ +/* { dg-do run } */ +/* { dg-shouldfail "bounds violation" } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + +#define SHOULDFAIL + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1; + v8 s2f2; +}; + +int foo_s2f2 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f2[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f2 (3)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c new file mode 100644 index 0000000..f273d58 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c @@ -0,0 +1,27 @@ +/* { 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))); + +struct S1 +{ + v16 s1f1; +}; + +int foo_s1f1 (int i) +{ + register struct S1 b asm ("xmm0"); + return b.s1f1[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s1f1 (-1)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c new file mode 100644 index 0000000..aa8f7b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + +#include "mpx-check.h" + +typedef int v16 __attribute__ ((vector_size (16))); + +struct S1 +{ + v16 s1f1; +}; + +int foo_s1f1 (int i) +{ + register struct S1 b asm ("xmm0"); + return b.s1f1[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s1f1 (0)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c new file mode 100644 index 0000000..3d0c9b2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c @@ -0,0 +1,27 @@ +/* { 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))); + +struct S1 +{ + v16 s1f1; +}; + +int foo_s1f1 (int i) +{ + register struct S1 b asm ("xmm0"); + return b.s1f1[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s1f1 (7)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-1-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-1-lbv.c new file mode 100644 index 0000000..201b62d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-1-lbv.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-shouldfail "bounds violation" } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + +#define SHOULDFAIL + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1[2]; +}; + +int foo_s2f1 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f1[0].s1f[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f1 (-1)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-1-nov.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-1-nov.c new file mode 100644 index 0000000..f94a879 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-1-nov.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1[2]; +}; + +int foo_s2f1 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f1[0].s1f[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f1 (1)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-1-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-1-ubv.c new file mode 100644 index 0000000..6ab981d --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-1-ubv.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-shouldfail "bounds violation" } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + +#define SHOULDFAIL + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1[2]; +}; + +int foo_s2f1 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f1[0].s1f[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f1 (4)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-2-lbv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-2-lbv.c new file mode 100644 index 0000000..cc58e8a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-2-lbv.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-shouldfail "bounds violation" } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + +#define SHOULDFAIL + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1[2]; +}; + +int foo_s2f1 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f1[1].s1f[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f1 (-1)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-2-nov.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-2-nov.c new file mode 100644 index 0000000..5898c3b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-2-nov.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1[2]; +}; + +int foo_s2f1 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f1[1].s1f[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f1 (1)); + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-2-ubv.c b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-2-ubv.c new file mode 100644 index 0000000..2910795 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-2-ubv.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ +/* { dg-shouldfail "bounds violation" } */ +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ + + +#define SHOULDFAIL + +#include "mpx-check.h" + +typedef int v8 __attribute__ ((vector_size (8))); + +struct S1 +{ + v8 s1f; +}; + +struct S2 +{ + struct S1 s2f1[2]; +}; + +int foo_s2f1 (int i) +{ + register struct S2 b asm ("xmm0"); + return b.s2f1[1].s1f[i]; +} + +int mpx_test (int argc, const char **argv) +{ + printf ("%d\n", foo_s2f1 (4)); + return 0; +} diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c index 23f5af9..852ca7b 100644 --- a/gcc/tree-chkp.c +++ b/gcc/tree-chkp.c @@ -327,6 +327,8 @@ static void chkp_parse_array_and_component_ref (tree node, tree *ptr, bool innermost_bounds); static void chkp_parse_bit_field_ref (tree node, location_t loc, tree *offset, tree *size); +static tree +chkp_make_addressed_object_bounds (tree obj, gimple_stmt_iterator *iter); #define chkp_bndldx_fndecl \ (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>; } +/* 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. */ static void chkp_register_incomplete_bounds (tree bounds, tree ptr) @@ -1044,6 +1085,12 @@ chkp_add_modification_to_stmt_list (tree lhs, static tree 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 ? tree_mem_ref_addr (ptr_type_node, 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); *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 @@ -3646,6 +3700,11 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, gimple_stmt_iterator *iter) case ARRAY_REF: case COMPONENT_REF: addr = get_base_address (ptr_src); + if (VAR_P (addr) && DECL_HARD_REGISTER (addr)) + { + bounds = chkp_get_zero_bounds (); + break; + } if (DECL_P (addr) || TREE_CODE (addr) == 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 ptr = NULL_TREE; /* a pointer used for dereference */ tree bounds = NULL_TREE; + bool reg_store = false; /* We do not need instrumentation for clobbers. */ 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); } + 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. */ 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. */ if (dirflag == integer_one_node + && !reg_store && chkp_type_has_pointer (node_type) && flag_chkp_store_bounds) { Is it OK? thanks, Alexander 2017-04-21 17:13 GMT+02:00 Alexander Ivchenko <aivch...@gmail.com>: > Something like that? > > diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c > index 3ef73a9..3fb76bc 100644 > --- a/gcc/tree-chkp.c > +++ b/gcc/tree-chkp.c > @@ -3700,6 +3700,11 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, > gimple_stmt_iterator *iter) > case ARRAY_REF: > case COMPONENT_REF: > addr = get_base_address (ptr_src); > + if (VAR_P (addr) && DECL_HARD_REGISTER (addr)) > + { > + bounds = chkp_get_zero_bounds (); > + break; > + } > if (DECL_P (addr) > || TREE_CODE (addr) == MEM_REF > || TREE_CODE (addr) == TARGET_MEM_REF) > > Here is the tree-chkp dump of the same function after this change: > > __attribute__((chkp instrumented)) > foo.chkp (int i) > { > __bounds_type __bound_tmp.1; > register struct S2 b __asm__ (*xmm0); > int k; > int * _1; > long unsigned int _2; > long unsigned int _3; > int * _4; > int * _5; > int _11; > > <bb 4> [0.00%]: > __bound_tmp.1_15 = __chkp_zero_bounds; > __bound_tmp.1_14 = __builtin_ia32_bndmk (&k, 4); > __bound_tmp.1_13 = __builtin_ia32_bndmk (-2147483648B, 16); > > <bb 3> [0.00%]: > > <bb 2> [0.00%]: > k = 5; > b.f3 = &k; > __builtin_ia32_bndstx (&k, __bound_tmp.1_14, -2147483648B); > _1 = b.f3; > _2 = (long unsigned int) i_9(D); > _3 = _2 * 4; > _4 = _1 + _3; > b.f3 = _4; > __builtin_ia32_bndstx (_4, __bound_tmp.1_15, -2147483648B); > _5 = b.f3; > _11 = *_5; > k ={v} {CLOBBER}; > return _11; > > } > > Doesn't work.. let me look a little deeper. > > Alexander > > 2017-04-20 19:17 GMT+02:00 Ilya Enkovich <enkovich....@gmail.com>: >> 2017-04-20 12:27 GMT+03:00 Alexander Ivchenko <aivch...@gmail.com>: >>> Thanks for correcting the usage of get_base_address. I fixed that. >>> Plus addressed the comment about the avoiding the usage of >>> chkp_find_bounds. >>> >>> >>> gcc/testsuite/ChangeLog: >>> >>> 2017-04-20 Alexander Ivchenko <alexander.ivche...@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. >>> * gcc.target/i386/mpx/hard-reg-3-1-lbv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-3-1-nov.c: New test. >>> * gcc.target/i386/mpx/hard-reg-3-1-ubv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-3-2-lbv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-3-2-nov.c: New test. >>> * gcc.target/i386/mpx/hard-reg-3-2-ubv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-3-lbv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-3-nov.c: New test. >>> * gcc.target/i386/mpx/hard-reg-3-ubv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-4-lbv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-4-nov.c: New test. >>> * gcc.target/i386/mpx/hard-reg-4-ubv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-5-1-lbv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-5-1-nov.c: New test. >>> * gcc.target/i386/mpx/hard-reg-5-1-ubv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-5-2-lbv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-5-2-nov.c: New test. >>> * gcc.target/i386/mpx/hard-reg-5-2-ubv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-6-lbv.c: New test. >>> * gcc.target/i386/mpx/hard-reg-6-nov.c: New test. >>> * gcc.target/i386/mpx/hard-reg-6-ubv.c: New test. >>> >>> gcc/ChangeLog: >>> >>> 2017-04-20 Alexander Ivchenko <alexander.ivche...@intel.com> >>> >>> * tree-chkp.c (chkp_get_hard_register_var_fake_base_address): >>> New function to provide a base address for >>> chkp_get_hard_register_fake_addr_expr. >>> (chkp_get_hard_register_fake_addr_expr): New function to build >>> fake address expression for an expr that resides on a hard >>> register. >>> (chkp_build_addr_expr): Add checks for hard reg cases. >>> (chkp_parse_array_and_component_ref): Create/find bounds if the >>> var resides on a hard reg. >>> >>> >>> I already had a testcases for struct with a pointer - "hard-reg-4-*". >>> Here is the instrumentation of the foo function: >>> >>> __attribute__((chkp instrumented)) >>> foo.chkp (int i) >>> { >>> __bounds_type __bound_tmp.1; >>> register struct S2 b __asm__ (*xmm0); >>> int k; >>> int * _1; >>> long unsigned int _2; >>> long unsigned int _3; >>> int * _4; >>> int * _5; >>> int _11; >>> int * _18; >>> >>> <bb 4> [0.00%]: >>> __bound_tmp.1_17 = __chkp_zero_bounds; >>> __bound_tmp.1_14 = __builtin_ia32_bndmk (&k, 4); >>> __bound_tmp.1_13 = __builtin_ia32_bndmk (-2147483648B, 16); >>> >>> <bb 3> [0.00%]: >>> >>> <bb 2> [0.00%]: >>> k = 5; >>> b.f3 = &k; >>> __builtin_ia32_bndstx (&k, __bound_tmp.1_14, -2147483648B); >>> _1 = b.f3; >>> __bound_tmp.1_15 = __builtin_ia32_bndldx (-2147483648B, _1); >>> _2 = (long unsigned int) i_9(D); >>> _3 = _2 * 4; >>> _4 = _1 + _3; >>> b.f3 = _4; >>> __builtin_ia32_bndstx (_4, __bound_tmp.1_15, -2147483648B); >>> _5 = b.f3; >>> __bound_tmp.1_16 = __builtin_ia32_bndldx (-2147483648B, _5); >>> __builtin_ia32_bndcl (_5, __bound_tmp.1_16); >>> _18 = _5 + 3; >>> __builtin_ia32_bndcu (_18, __bound_tmp.1_16); >>> _11 = *_5; >>> k ={v} {CLOBBER}; >>> return _11; >>> >>> } >>> >>> Which is the most suspicious one, because we have ldx and stx. I'm not >>> sure whether this is OK. >> >> It is not OK because single entry in BT may be used by multiple hardreg >> variables. There is a code in chkp_find_bounds_1 to use zero bounds in >> case we load bounds from register var. I believe here we should do the >> same. In chkp_find_bounds_1 at ARRAY_REF/COMPONENT_REF >> case check if addr is register var and use zero bounds. >> >> Thanks, >> Ilya >> >> >>> >>> Here is the chkp dump for foo function of newly added hard-reg-6* case: >>> >>> __attribute__((chkp instrumented)) >>> foo.chkp (int i, int * kp1, __bounds_type __chkp_bounds_of_kp1) >>> { >>> __bounds_type __bound_tmp.1; >>> int D.2873; >>> register struct S2 b __asm__ (*xmm0); >>> int k2; >>> int * _1; >>> long unsigned int _2; >>> long unsigned int _3; >>> int * _4; >>> int * _5; >>> int _13; >>> int * _31; >>> >>> <bb 5> [0.00%]: >>> __bound_tmp.1_22 = __builtin_ia32_bndmk (&k2, 4); >>> __bound_tmp.1_17 = __chkp_zero_bounds; >>> __bound_tmp.1_15 = __builtin_ia32_bndmk (-2147483648B, 16); >>> >>> <bb 4> [0.00%]: >>> >>> <bb 2> [0.00%]: >>> k2 = 5; >>> __bound_tmp.1_16 = __builtin_ia32_bndmk (-2147483648B, 16); >>> __bound_tmp.1_18 = __builtin_ia32_bndint (__bound_tmp.1_16, >>> __bound_tmp.1_15); >>> __builtin_ia32_bndcl (-2147483648B, __bound_tmp.1_18); >>> __builtin_ia32_bndcu (-2147483641B, __bound_tmp.1_18); >>> b.f[0] = kp1_8(D); >>> __builtin_ia32_bndstx (kp1_8(D), __chkp_bounds_of_kp1_19(D), >>> -2147483648B); >>> __bound_tmp.1_20 = __builtin_ia32_bndmk (-2147483648B, 16); >>> __bound_tmp.1_21 = __builtin_ia32_bndint (__bound_tmp.1_20, >>> __bound_tmp.1_15); >>> __builtin_ia32_bndcl (-2147483640B, __bound_tmp.1_21); >>> __builtin_ia32_bndcu (-2147483633B, __bound_tmp.1_21); >>> b.f[1] = &k2; >>> __builtin_ia32_bndstx (&k2, __bound_tmp.1_22, -2147483640B); >>> __bound_tmp.1_23 = __builtin_ia32_bndmk (-2147483648B, 16); >>> __bound_tmp.1_24 = __builtin_ia32_bndint (__bound_tmp.1_23, >>> __bound_tmp.1_15); >>> __builtin_ia32_bndcl (-2147483648B, __bound_tmp.1_24); >>> __builtin_ia32_bndcu (-2147483641B, __bound_tmp.1_24); >>> _1 = b.f[0]; >>> __bound_tmp.1_27 = __builtin_ia32_bndldx (-2147483648B, _1); >>> _2 = (long unsigned int) i_11(D); >>> _3 = _2 * 4; >>> _4 = _1 + _3; >>> __bound_tmp.1_25 = __builtin_ia32_bndmk (-2147483648B, 16); >>> __bound_tmp.1_26 = __builtin_ia32_bndint (__bound_tmp.1_25, >>> __bound_tmp.1_15); >>> __builtin_ia32_bndcl (-2147483648B, __bound_tmp.1_26); >>> __builtin_ia32_bndcu (-2147483641B, __bound_tmp.1_26); >>> b.f[0] = _4; >>> __builtin_ia32_bndstx (_4, __bound_tmp.1_27, -2147483648B); >>> __bound_tmp.1_28 = __builtin_ia32_bndmk (-2147483648B, 16); >>> __bound_tmp.1_29 = __builtin_ia32_bndint (__bound_tmp.1_28, >>> __bound_tmp.1_15); >>> __builtin_ia32_bndcl (-2147483648B, __bound_tmp.1_29); >>> __builtin_ia32_bndcu (-2147483641B, __bound_tmp.1_29); >>> _5 = b.f[0]; >>> __bound_tmp.1_30 = __builtin_ia32_bndldx (-2147483648B, _5); >>> __builtin_ia32_bndcl (_5, __bound_tmp.1_30); >>> _31 = _5 + 3; >>> __builtin_ia32_bndcu (_31, __bound_tmp.1_30); >>> _13 = *_5; >>> k2 ={v} {CLOBBER}; >>> >>> <L0> [0.00%]: >>> return _13; >>> } >>> >>> ..which looks fine to me. And here is the dump-chkp for the basic case >>> of hard-reg-2: >>> >>> __attribute__((chkp instrumented)) >>> foo.chkp (int i) >>> { >>> __bounds_type __bound_tmp.1; >>> int D.2863; >>> register v16 u __asm__ (*xmm0); >>> int _3; >>> long unsigned int _6; >>> sizetype _7; >>> void * _8; >>> sizetype _9; >>> sizetype _10; >>> sizetype _11; >>> sizetype _12; >>> void * _13; >>> >>> <bb 5> [0.00%]: >>> __bound_tmp.1_5 = __chkp_zero_bounds; >>> __bound_tmp.1_4 = __builtin_ia32_bndmk (-2147483648B, 16); >>> >>> <bb 4> [0.00%]: >>> >>> <bb 2> [0.00%]: >>> _6 = (long unsigned int) i_2(D); >>> _7 = _6 * 4; >>> _8 = -2147483648B + _7; >>> __builtin_ia32_bndcl (_8, __bound_tmp.1_4); >>> _9 = (sizetype) i_2(D); >>> _10 = _9 + 1; >>> _11 = _10 * 4; >>> _12 = _11 + 18446744073709551615; >>> _13 = -2147483648B + _12; >>> __builtin_ia32_bndcu (_13, __bound_tmp.1_4); >>> _3 = VIEW_CONVERT_EXPR<int[4]>(u)[i_2(D)]; >>> >>> <L0> [0.00%]: >>> return _3; >>> >>> } >>> >>> So overall we have these fails (they all have the same backtrace as >>> PR80270) and other combinations pass: >>> >>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 (internal compiler >>> error) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O3 -g (internal compiler >>> error) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O3 -g (test for excess >>> errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 -flto >>> -fno-use-linker-plugin -flto-partition=none (internal compiler error) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 -flto >>> -fno-use-linker-plugin -flto-partition=none (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 -flto >>> -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 -flto >>> -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 (internal compiler >>> error) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O3 -g (internal compiler >>> error) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O3 -g (test for excess >>> errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 -flto >>> -fno-use-linker-plugin -flto-partition=none (internal compiler error) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 -flto >>> -fno-use-linker-plugin -flto-partition=none (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 -flto >>> -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) >>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 -flto >>> -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-4-lbv.c -O0 (internal compiler error) >>> FAIL: gcc.target/i386/mpx/hard-reg-4-lbv.c -O0 (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-4-nov.c -O0 (internal compiler error) >>> FAIL: gcc.target/i386/mpx/hard-reg-4-nov.c -O0 (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-4-ubv.c -O0 (internal compiler error) >>> FAIL: gcc.target/i386/mpx/hard-reg-4-ubv.c -O0 (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 (internal compiler >>> error) >>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O3 -g (internal compiler >>> error) >>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O3 -g (test for excess >>> errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 -flto >>> -fno-use-linker-plugin -flto-partition=none (internal compiler error) >>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 -flto >>> -fno-use-linker-plugin -flto-partition=none (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 -flto >>> -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) >>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 -flto >>> -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) >>> FAIL: gcc.target/i386/mpx/hard-reg-6-lbv.c -O0 (internal compiler error) >>> FAIL: gcc.target/i386/mpx/hard-reg-6-lbv.c -O0 (test for excess errors) >>> >>> >>> >>> Here is the patch itself: >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c >>> new file mode 100644 >>> index 0000000..319e1ec >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c >>> @@ -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; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c >>> new file mode 100644 >>> index 0000000..3c6d39a >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c >>> @@ -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; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c >>> new file mode 100644 >>> index 0000000..7fe76c4 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c >>> @@ -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; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c >>> new file mode 100644 >>> index 0000000..7e4451f >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c >>> @@ -0,0 +1,33 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1; >>> + v8 s2f2; >>> +}; >>> + >>> +int foo_s2f1 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f1.s1f[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f1 (-1)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c >>> new file mode 100644 >>> index 0000000..73bd7fb >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c >>> @@ -0,0 +1,30 @@ >>> +/* { dg-do run } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1; >>> + v8 s2f2; >>> +}; >>> + >>> +int foo_s2f1 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f1.s1f[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f1 (0)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c >>> new file mode 100644 >>> index 0000000..166b6b9 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c >>> @@ -0,0 +1,33 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1; >>> + v8 s2f2; >>> +}; >>> + >>> +int foo_s2f1 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f1.s1f[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f1 (3)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c >>> new file mode 100644 >>> index 0000000..7820c2f >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c >>> @@ -0,0 +1,33 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1; >>> + v8 s2f2; >>> +}; >>> + >>> +int foo_s2f2 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f2[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f2 (-1)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c >>> new file mode 100644 >>> index 0000000..0816e58 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c >>> @@ -0,0 +1,30 @@ >>> +/* { dg-do run } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1; >>> + v8 s2f2; >>> +}; >>> + >>> +int foo_s2f2 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f2[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f2 (0)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c >>> new file mode 100644 >>> index 0000000..94261a7 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c >>> @@ -0,0 +1,33 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1; >>> + v8 s2f2; >>> +}; >>> + >>> +int foo_s2f2 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f2[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f2 (3)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c >>> new file mode 100644 >>> index 0000000..f273d58 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c >>> @@ -0,0 +1,27 @@ >>> +/* { 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))); >>> + >>> +struct S1 >>> +{ >>> + v16 s1f1; >>> +}; >>> + >>> +int foo_s1f1 (int i) >>> +{ >>> + register struct S1 b asm ("xmm0"); >>> + return b.s1f1[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s1f1 (-1)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c >>> new file mode 100644 >>> index 0000000..aa8f7b9 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c >>> @@ -0,0 +1,24 @@ >>> +/* { dg-do run } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v16 __attribute__ ((vector_size (16))); >>> + >>> +struct S1 >>> +{ >>> + v16 s1f1; >>> +}; >>> + >>> +int foo_s1f1 (int i) >>> +{ >>> + register struct S1 b asm ("xmm0"); >>> + return b.s1f1[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s1f1 (0)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c >>> new file mode 100644 >>> index 0000000..3d0c9b2 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c >>> @@ -0,0 +1,27 @@ >>> +/* { 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))); >>> + >>> +struct S1 >>> +{ >>> + v16 s1f1; >>> +}; >>> + >>> +int foo_s1f1 (int i) >>> +{ >>> + register struct S1 b asm ("xmm0"); >>> + return b.s1f1[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s1f1 (7)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-lbv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-lbv.c >>> new file mode 100644 >>> index 0000000..e81b942 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-lbv.c >>> @@ -0,0 +1,31 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S2 >>> +{ >>> + v8 s2f2; >>> + int* f3; >>> +}; >>> + >>> +int foo (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + int k = 5; >>> + b.f3 = &k; >>> + b.f3 = b.f3 + i; >>> + return *b.f3; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo (-1)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-nov.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-nov.c >>> new file mode 100644 >>> index 0000000..4b1f1ac >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-nov.c >>> @@ -0,0 +1,28 @@ >>> +/* { dg-do run } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S2 >>> +{ >>> + v8 s2f2; >>> + int* f3; >>> +}; >>> + >>> +int foo (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + int k = 5; >>> + b.f3 = &k; >>> + b.f3 = b.f3 + i; >>> + return *b.f3; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo (0)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-ubv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-ubv.c >>> new file mode 100644 >>> index 0000000..e95e68f >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-ubv.c >>> @@ -0,0 +1,31 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S2 >>> +{ >>> + v8 s2f2; >>> + int* f3; >>> +}; >>> + >>> +int foo (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + int k = 5; >>> + b.f3 = &k; >>> + b.f3 = b.f3 + i; >>> + return *b.f3; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo (1)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-lbv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-lbv.c >>> new file mode 100644 >>> index 0000000..201b62d >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-lbv.c >>> @@ -0,0 +1,32 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1[2]; >>> +}; >>> + >>> +int foo_s2f1 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f1[0].s1f[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f1 (-1)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-nov.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-nov.c >>> new file mode 100644 >>> index 0000000..f94a879 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-nov.c >>> @@ -0,0 +1,30 @@ >>> +/* { dg-do run } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1[2]; >>> +}; >>> + >>> +int foo_s2f1 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f1[0].s1f[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f1 (1)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-ubv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-ubv.c >>> new file mode 100644 >>> index 0000000..6ab981d >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-ubv.c >>> @@ -0,0 +1,32 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1[2]; >>> +}; >>> + >>> +int foo_s2f1 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f1[0].s1f[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f1 (4)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-lbv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-lbv.c >>> new file mode 100644 >>> index 0000000..cc58e8a >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-lbv.c >>> @@ -0,0 +1,32 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1[2]; >>> +}; >>> + >>> +int foo_s2f1 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f1[1].s1f[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f1 (-1)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-nov.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-nov.c >>> new file mode 100644 >>> index 0000000..5898c3b >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-nov.c >>> @@ -0,0 +1,30 @@ >>> +/* { dg-do run } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1[2]; >>> +}; >>> + >>> +int foo_s2f1 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f1[1].s1f[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f1 (1)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-ubv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-ubv.c >>> new file mode 100644 >>> index 0000000..2910795 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-ubv.c >>> @@ -0,0 +1,32 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S1 >>> +{ >>> + v8 s1f; >>> +}; >>> + >>> +struct S2 >>> +{ >>> + struct S1 s2f1[2]; >>> +}; >>> + >>> +int foo_s2f1 (int i) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + return b.s2f1[1].s1f[i]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + printf ("%d\n", foo_s2f1 (4)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-6-lbv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-6-lbv.c >>> new file mode 100644 >>> index 0000000..b160915 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-6-lbv.c >>> @@ -0,0 +1,34 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S2 >>> +{ >>> + int* f[2]; >>> +}; >>> + >>> +int foo (int i, int *kp1) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + int k2 = 5; >>> + >>> + b.f[0] = kp1; >>> + b.f[1] = &k2; >>> + >>> + b.f[1] = b.f[1] + i; >>> + return *b.f[1]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + int k1 = 10; >>> + printf ("%d\n", foo (-1, &k1)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-6-nov.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-6-nov.c >>> new file mode 100644 >>> index 0000000..584b3e5 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-6-nov.c >>> @@ -0,0 +1,31 @@ >>> +/* { dg-do run } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S2 >>> +{ >>> + int* f[2]; >>> +}; >>> + >>> +int foo (int i, int *kp1) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + int k2 = 5; >>> + >>> + b.f[0] = kp1; >>> + b.f[1] = &k2; >>> + >>> + b.f[0] = b.f[0] + i; >>> + return *b.f[0]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + int k1 = 10; >>> + printf ("%d\n", foo (0, &k1)); >>> + return 0; >>> +} >>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-6-ubv.c >>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-6-ubv.c >>> new file mode 100644 >>> index 0000000..92fa793 >>> --- /dev/null >>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-6-ubv.c >>> @@ -0,0 +1,34 @@ >>> +/* { dg-do run } */ >>> +/* { dg-shouldfail "bounds violation" } */ >>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>> + >>> + >>> +#define SHOULDFAIL >>> + >>> +#include "mpx-check.h" >>> + >>> +typedef int v8 __attribute__ ((vector_size (8))); >>> + >>> +struct S2 >>> +{ >>> + int* f[2]; >>> +}; >>> + >>> +int foo (int i, int *kp1) >>> +{ >>> + register struct S2 b asm ("xmm0"); >>> + int k2 = 5; >>> + >>> + b.f[0] = kp1; >>> + b.f[1] = &k2; >>> + >>> + b.f[0] = b.f[0] + i; >>> + return *b.f[0]; >>> +} >>> + >>> +int mpx_test (int argc, const char **argv) >>> +{ >>> + int k1 = 10; >>> + printf ("%d\n", foo (1, &k1)); >>> + return 0; >>> +} >>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c >>> index b1ff218..3ef73a9 100644 >>> --- a/gcc/tree-chkp.c >>> +++ b/gcc/tree-chkp.c >>> @@ -327,6 +327,8 @@ static void chkp_parse_array_and_component_ref >>> (tree node, tree *ptr, >>> bool innermost_bounds); >>> static void chkp_parse_bit_field_ref (tree node, location_t loc, >>> tree *offset, tree *size); >>> +static tree >>> +chkp_make_addressed_object_bounds (tree obj, gimple_stmt_iterator *iter); >>> >>> #define chkp_bndldx_fndecl \ >>> (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>; >>> } >>> >>> +/* 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. */ >>> static void >>> chkp_register_incomplete_bounds (tree bounds, tree ptr) >>> @@ -1044,6 +1085,12 @@ chkp_add_modification_to_stmt_list (tree lhs, >>> static tree >>> 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 >>> ? tree_mem_ref_addr (ptr_type_node, 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); >>> >>> *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 (DECL_HARD_REGISTER (var)) >>> + *bounds = chkp_make_addressed_object_bounds (var, iter); >>> } >>> >>> /* In this loop we are trying to find a field access >>> >>> 2017-04-19 21:32 GMT+02:00 Ilya Enkovich <enkovich....@gmail.com>: >>>> 2017-04-19 19:48 GMT+03:00 Alexander Ivchenko <aivch...@gmail.com>: >>>>> Hi, >>>>> >>>>> Thanks for the comments, that was a good idea to place all the logic >>>>> inside >>>>> of chkp_build_addr_expr function. I followed it and here is what I got: >>>>> >>>>> gcc/testsuite/ChangeLog: >>>>> >>>>> 2017-04-19 Alexander Ivchenko <aivch...@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. >>>>> * gcc.target/i386/mpx/hard-reg-3-1-lbv.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-3-1-nov.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-3-1-ubv.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-3-2-lbv.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-3-2-nov.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-3-2-ubv.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-3-lbv.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-3-nov.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-3-ubv.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-4-lbv.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-4-nov.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-4-ubv.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-5-1-lbv.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-5-1-nov.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-5-1-ubv.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-5-2-lbv.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-5-2-nov.c: New test. >>>>> * gcc.target/i386/mpx/hard-reg-5-2-ubv.c: New test. >>>>> >>>>> gcc/ChangeLog: >>>>> >>>>> 2017-04-19 Alexander Ivchenko <aivch...@gmail.com> >>>>> >>>>> * tree-chkp.c (chkp_get_hard_register_var_fake_base_address): >>>>> New function to provide a base address for. >>>>> chkp_get_hard_register_fake_addr_expr >>>>> (chkp_get_hard_register_fake_addr_expr): New function to build >>>>> fake address expression for an expr that resides on a hard >>>>> register. >>>>> (chkp_build_addr_expr): Add checks for hard reg cases. >>>>> (chkp_parse_array_and_component_ref): Create/find bounds if the >>>>> var resides on a hard reg. >>>>> (chkp_find_bounds_1): Check for hard register cases. >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> And the patch itself: >>>>> >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c >>>>> new file mode 100644 >>>>> index 0000000..319e1ec >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c >>>>> @@ -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; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c >>>>> new file mode 100644 >>>>> index 0000000..3c6d39a >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c >>>>> @@ -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; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c >>>>> new file mode 100644 >>>>> index 0000000..7fe76c4 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c >>>>> @@ -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; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c >>>>> new file mode 100644 >>>>> index 0000000..7e4451f >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c >>>>> @@ -0,0 +1,33 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#define SHOULDFAIL >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1; >>>>> + v8 s2f2; >>>>> +}; >>>>> + >>>>> +int foo_s2f1 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f1.s1f[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f1 (-1)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c >>>>> new file mode 100644 >>>>> index 0000000..73bd7fb >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c >>>>> @@ -0,0 +1,30 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1; >>>>> + v8 s2f2; >>>>> +}; >>>>> + >>>>> +int foo_s2f1 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f1.s1f[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f1 (0)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c >>>>> new file mode 100644 >>>>> index 0000000..166b6b9 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c >>>>> @@ -0,0 +1,33 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#define SHOULDFAIL >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1; >>>>> + v8 s2f2; >>>>> +}; >>>>> + >>>>> +int foo_s2f1 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f1.s1f[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f1 (3)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c >>>>> new file mode 100644 >>>>> index 0000000..7820c2f >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c >>>>> @@ -0,0 +1,33 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#define SHOULDFAIL >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1; >>>>> + v8 s2f2; >>>>> +}; >>>>> + >>>>> +int foo_s2f2 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f2[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f2 (-1)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c >>>>> new file mode 100644 >>>>> index 0000000..0816e58 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c >>>>> @@ -0,0 +1,30 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1; >>>>> + v8 s2f2; >>>>> +}; >>>>> + >>>>> +int foo_s2f2 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f2[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f2 (0)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c >>>>> new file mode 100644 >>>>> index 0000000..94261a7 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c >>>>> @@ -0,0 +1,33 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#define SHOULDFAIL >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1; >>>>> + v8 s2f2; >>>>> +}; >>>>> + >>>>> +int foo_s2f2 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f2[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f2 (3)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c >>>>> new file mode 100644 >>>>> index 0000000..f273d58 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c >>>>> @@ -0,0 +1,27 @@ >>>>> +/* { 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))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v16 s1f1; >>>>> +}; >>>>> + >>>>> +int foo_s1f1 (int i) >>>>> +{ >>>>> + register struct S1 b asm ("xmm0"); >>>>> + return b.s1f1[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s1f1 (-1)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c >>>>> new file mode 100644 >>>>> index 0000000..aa8f7b9 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c >>>>> @@ -0,0 +1,24 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v16 __attribute__ ((vector_size (16))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v16 s1f1; >>>>> +}; >>>>> + >>>>> +int foo_s1f1 (int i) >>>>> +{ >>>>> + register struct S1 b asm ("xmm0"); >>>>> + return b.s1f1[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s1f1 (0)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c >>>>> new file mode 100644 >>>>> index 0000000..3d0c9b2 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c >>>>> @@ -0,0 +1,27 @@ >>>>> +/* { 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))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v16 s1f1; >>>>> +}; >>>>> + >>>>> +int foo_s1f1 (int i) >>>>> +{ >>>>> + register struct S1 b asm ("xmm0"); >>>>> + return b.s1f1[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s1f1 (7)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-lbv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-lbv.c >>>>> new file mode 100644 >>>>> index 0000000..e81b942 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-lbv.c >>>>> @@ -0,0 +1,31 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#define SHOULDFAIL >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + v8 s2f2; >>>>> + int* f3; >>>>> +}; >>>>> + >>>>> +int foo (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + int k = 5; >>>>> + b.f3 = &k; >>>>> + b.f3 = b.f3 + i; >>>>> + return *b.f3; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo (-1)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-nov.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-nov.c >>>>> new file mode 100644 >>>>> index 0000000..4b1f1ac >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-nov.c >>>>> @@ -0,0 +1,28 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + v8 s2f2; >>>>> + int* f3; >>>>> +}; >>>>> + >>>>> +int foo (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + int k = 5; >>>>> + b.f3 = &k; >>>>> + b.f3 = b.f3 + i; >>>>> + return *b.f3; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo (0)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-ubv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-ubv.c >>>>> new file mode 100644 >>>>> index 0000000..e95e68f >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-ubv.c >>>>> @@ -0,0 +1,31 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#define SHOULDFAIL >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + v8 s2f2; >>>>> + int* f3; >>>>> +}; >>>>> + >>>>> +int foo (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + int k = 5; >>>>> + b.f3 = &k; >>>>> + b.f3 = b.f3 + i; >>>>> + return *b.f3; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo (1)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-lbv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-lbv.c >>>>> new file mode 100644 >>>>> index 0000000..201b62d >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-lbv.c >>>>> @@ -0,0 +1,32 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#define SHOULDFAIL >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1[2]; >>>>> +}; >>>>> + >>>>> +int foo_s2f1 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f1[0].s1f[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f1 (-1)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-nov.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-nov.c >>>>> new file mode 100644 >>>>> index 0000000..f94a879 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-nov.c >>>>> @@ -0,0 +1,30 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1[2]; >>>>> +}; >>>>> + >>>>> +int foo_s2f1 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f1[0].s1f[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f1 (1)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-ubv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-ubv.c >>>>> new file mode 100644 >>>>> index 0000000..6ab981d >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-1-ubv.c >>>>> @@ -0,0 +1,32 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#define SHOULDFAIL >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1[2]; >>>>> +}; >>>>> + >>>>> +int foo_s2f1 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f1[0].s1f[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f1 (4)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-lbv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-lbv.c >>>>> new file mode 100644 >>>>> index 0000000..cc58e8a >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-lbv.c >>>>> @@ -0,0 +1,32 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#define SHOULDFAIL >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1[2]; >>>>> +}; >>>>> + >>>>> +int foo_s2f1 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f1[1].s1f[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f1 (-1)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-nov.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-nov.c >>>>> new file mode 100644 >>>>> index 0000000..5898c3b >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-nov.c >>>>> @@ -0,0 +1,30 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1[2]; >>>>> +}; >>>>> + >>>>> +int foo_s2f1 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f1[1].s1f[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f1 (1)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-ubv.c >>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-ubv.c >>>>> new file mode 100644 >>>>> index 0000000..2910795 >>>>> --- /dev/null >>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-5-2-ubv.c >>>>> @@ -0,0 +1,32 @@ >>>>> +/* { dg-do run } */ >>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>> + >>>>> + >>>>> +#define SHOULDFAIL >>>>> + >>>>> +#include "mpx-check.h" >>>>> + >>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>> + >>>>> +struct S1 >>>>> +{ >>>>> + v8 s1f; >>>>> +}; >>>>> + >>>>> +struct S2 >>>>> +{ >>>>> + struct S1 s2f1[2]; >>>>> +}; >>>>> + >>>>> +int foo_s2f1 (int i) >>>>> +{ >>>>> + register struct S2 b asm ("xmm0"); >>>>> + return b.s2f1[1].s1f[i]; >>>>> +} >>>>> + >>>>> +int mpx_test (int argc, const char **argv) >>>>> +{ >>>>> + printf ("%d\n", foo_s2f1 (4)); >>>>> + return 0; >>>>> +} >>>>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c >>>>> index b1ff218..6a48a55 100644 >>>>> --- a/gcc/tree-chkp.c >>>>> +++ b/gcc/tree-chkp.c >>>>> @@ -679,6 +679,46 @@ chkp_erase_completed_bounds (void) >>>>> 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 = get_base_address (outer); >>>> >>>> Hi! >>>> >>>> I don't think get_base_address is what you want here because it goes to >>>> the most inner base. >>>> >>>>> + } >>>>> + } >>>>> + gcc_assert (VAR_P (outer) && DECL_HARD_REGISTER (outer)); >>>>> + >>>>> + return addr; >>>>> +} >>>>> + >>>>> /* Mark BOUNDS associated with PTR as incomplete. */ >>>>> static void >>>>> chkp_register_incomplete_bounds (tree bounds, tree ptr) >>>>> @@ -1044,6 +1084,18 @@ chkp_add_modification_to_stmt_list (tree lhs, >>>>> static tree >>>>> chkp_build_addr_expr (tree obj) >>>>> { >>>>> + /* We first check whether it is a "hard reg case". */ >>>>> + tree outer = obj; >>>>> + while (TREE_CODE (outer) == COMPONENT_REF >>>>> + || TREE_CODE (outer) == ARRAY_REF) >>>>> + if (TREE_CODE (outer) == COMPONENT_REF) >>>>> + outer = TREE_OPERAND (outer, 0); >>>>> + else >>>>> + outer = get_base_address (outer); >>>> >>>> And here simple call to get_base_address might replace the whole loop. >>>> >>>>> + if (VAR_P (outer) && DECL_HARD_REGISTER (outer)) >>>>> + return chkp_get_hard_register_fake_addr_expr (obj); >>>>> + >>>>> + /* If not - return regular ADDR_EXPR. */ >>>>> return TREE_CODE (obj) == TARGET_MEM_REF >>>>> ? tree_mem_ref_addr (ptr_type_node, obj) >>>>> : build_fold_addr_expr (obj); >>>>> @@ -3442,6 +3494,13 @@ chkp_parse_array_and_component_ref (tree node, >>>>> tree *ptr, >>>>> || TREE_CODE (var) == SSA_NAME); >>>>> >>>>> *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 (DECL_HARD_REGISTER (var)) >>>>> + *bounds = chkp_find_bounds (var, iter); >>>> >>>> Current semantics of this call is to get bounds for the pointer read from >>>> var. >>>> I know we never get here fo pointer vars but still... >>>> >>>> I propose to just call chkp_make_addressed_object_bounds here instead of >>>> chkp_find_bounds to avoid this non-intuitive interpretation of non-pointer >>>> hardreg variable in chkp_find_bounds_1. >>>> >>>> BTW what if we have a structure with a pointer field or vector of pointers? >>>> If we read this pointer then we might have some fun trying to find its >>>> bounds. >>>> Let's make a test! :) >>>> >>>> Also what code do we produce now? Do we create static bounds variable >>>> to hold fake bounds of hard reg variable? Is it initialized statically >>>> or dynamically? >>>> >>>>> } >>>>> >>>>> /* In this loop we are trying to find a field access >>>>> @@ -3639,6 +3698,8 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, >>>>> gimple_stmt_iterator *iter) >>>>> addr = chkp_build_addr_expr (ptr_src); >>>>> bounds = chkp_build_bndldx (addr, ptr, iter); >>>>> } >>>>> + else if (VAR_P (ptr) && DECL_HARD_REGISTER (ptr)) >>>>> + bounds = chkp_make_addressed_object_bounds (ptr_src, iter); >>>>> else >>>>> bounds = chkp_get_nonpointer_load_bounds (); >>>>> break; >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> As before, the following added testcases fail because of PR80270: >>>> >>>> That makes hard to confirm patch correctness. Please at least check >>>> GIMPLE for some of these tests are produced correctly by chkp phase. >>>> >>>> Overall this version looks much simpler and better. New MPX feature >>>> to catch non-memory bounds violation is almost done! >>>> >>>> Thanks, >>>> Ilya >>>> >>>>> >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 (internal compiler >>>>> error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 (test for excess >>>>> errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O3 -g (internal compiler >>>>> error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O3 -g (test for excess >>>>> errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 -flto >>>>> -fno-use-linker-plugin -flto-partition=none (internal compiler error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 -flto >>>>> -fno-use-linker-plugin -flto-partition=none (test for excess errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 -flto >>>>> -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-1-ubv.c -O2 -flto >>>>> -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 (internal compiler >>>>> error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 (test for excess >>>>> errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O3 -g (internal compiler >>>>> error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O3 -g (test for excess >>>>> errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 -flto >>>>> -fno-use-linker-plugin -flto-partition=none (internal compiler error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 -flto >>>>> -fno-use-linker-plugin -flto-partition=none (test for excess errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 -flto >>>>> -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-3-2-nov.c -O2 -flto >>>>> -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-4-lbv.c -O0 (internal compiler >>>>> error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-4-lbv.c -O0 (test for excess errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-4-nov.c -O0 (internal compiler >>>>> error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-4-nov.c -O0 (test for excess errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-4-ubv.c -O0 (internal compiler >>>>> error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-4-ubv.c -O0 (test for excess errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 (internal compiler >>>>> error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 (test for excess >>>>> errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O3 -g (internal compiler >>>>> error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O3 -g (test for excess >>>>> errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 -flto >>>>> -fno-use-linker-plugin -flto-partition=none (internal compiler error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 -flto >>>>> -fno-use-linker-plugin -flto-partition=none (test for excess errors) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 -flto >>>>> -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error) >>>>> FAIL: gcc.target/i386/mpx/hard-reg-5-2-nov.c -O2 -flto >>>>> -fuse-linker-plugin -fno-fat-lto-objects (test for excess errors) >>>>> >>>>> hard-reg-4-* looks suspicious to me. May be we need to handle that >>>>> case differently, but it is hard to say because of the ICE now. >>>>> >>>>> >>>>> 2017-04-10 23:21 GMT+02:00 Ilya Enkovich <enkovich....@gmail.com>: >>>>>> 2017-04-02 23:52 GMT+03:00 Alexander Ivchenko <aivch...@gmail.com>: >>>>>>> Hi, >>>>>>> >>>>>>> Here is the patch that roughly follows your idea. >>>>>>> Some comments: >>>>>>> >>>>>>> - There are more cases than array_ref overflow. We need to take care >>>>>>> of component_ref and both underflows/overflows are possible >>>>>>> - I could not make it work with "0" as a fake address, because then >>>>>>> catching lower bounds violation is getting hard at O2 and above. E.g. >>>>>>> consider this: >>>>>>> >>>>>>> 0x00000000004005f8 <+8>: bndmk 0x7(%rax),%bnd0 >>>>>>> 0x00000000004005fd <+13>: mov $0x400734,%edi >>>>>>> => 0x0000000000400602 <+18>: bndcl 0xfffffffffffffffc,%bnd0 >>>>>>> (gdb) p $bnd0 >>>>>>> $1 = {lbound = 0x0, ubound = 0x7} : size 8 >>>>>>> 0x000000000040060b <+27>: callq 0x400500 <printf@plt> >>>>>>> >>>>>>> - bndcu is removed as not necessary and underflowed access is not >>>>>>> caught. I used another fake value for lower bound address, which is >>>>>>> 2^(bitness - 1) >>>>>> >>>>>> Hi, >>>>>> >>>>>> Looks like CHKP optimizations don't let us catch cases when pointer >>>>>> arithmetc overflows. Using any fake value doesn't guarantee you don't >>>>>> have overflow. >>>>>> >>>>>> This overoptimization is definately a separate issue. It should be easy >>>>>> to write a test where usage of a huge index in array causes >>>>>> uncought bounds violation because of removed bndcl/bndcu. You should >>>>>> file a bug for that. >>>>>> >>>>>> If we don't try to work around overflow issues in this patch then using 0 >>>>>> should be more efficient because it allows you to always use bndcu only >>>>>> (you just can't violate zero lower bound). >>>>>> >>>>>> BTW please don't forget ChangeLogs for your patches. >>>>>> >>>>>>> >>>>>>> - hard-reg-3-[1,2]* tests fail with ICE right now because of PR80270. >>>>>>> I will mark them as XFAIL if the patch is approved and the mentioned >>>>>>> bug is not fixed >>>>>>> >>>>>>> >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..319e1ec >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c >>>>>>> @@ -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; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..3c6d39a >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c >>>>>>> @@ -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; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..7fe76c4 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c >>>>>>> @@ -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; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..7e4451f >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-lbv.c >>>>>>> @@ -0,0 +1,33 @@ >>>>>>> +/* { dg-do run } */ >>>>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>>>> + >>>>>>> + >>>>>>> +#define SHOULDFAIL >>>>>>> + >>>>>>> +#include "mpx-check.h" >>>>>>> + >>>>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>>>> + >>>>>>> +struct S1 >>>>>>> +{ >>>>>>> + v8 s1f; >>>>>>> +}; >>>>>>> + >>>>>>> +struct S2 >>>>>>> +{ >>>>>>> + struct S1 s2f1; >>>>>>> + v8 s2f2; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo_s2f1 (int i) >>>>>>> +{ >>>>>>> + register struct S2 b asm ("xmm0"); >>>>>>> + return b.s2f1.s1f[i]; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo_s2f1 (-1)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..73bd7fb >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-nov.c >>>>>>> @@ -0,0 +1,30 @@ >>>>>>> +/* { dg-do run } */ >>>>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>>>> + >>>>>>> + >>>>>>> +#include "mpx-check.h" >>>>>>> + >>>>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>>>> + >>>>>>> +struct S1 >>>>>>> +{ >>>>>>> + v8 s1f; >>>>>>> +}; >>>>>>> + >>>>>>> +struct S2 >>>>>>> +{ >>>>>>> + struct S1 s2f1; >>>>>>> + v8 s2f2; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo_s2f1 (int i) >>>>>>> +{ >>>>>>> + register struct S2 b asm ("xmm0"); >>>>>>> + return b.s2f1.s1f[i]; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo_s2f1 (0)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..166b6b9 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-1-ubv.c >>>>>>> @@ -0,0 +1,33 @@ >>>>>>> +/* { dg-do run } */ >>>>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>>>> + >>>>>>> + >>>>>>> +#define SHOULDFAIL >>>>>>> + >>>>>>> +#include "mpx-check.h" >>>>>>> + >>>>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>>>> + >>>>>>> +struct S1 >>>>>>> +{ >>>>>>> + v8 s1f; >>>>>>> +}; >>>>>>> + >>>>>>> +struct S2 >>>>>>> +{ >>>>>>> + struct S1 s2f1; >>>>>>> + v8 s2f2; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo_s2f1 (int i) >>>>>>> +{ >>>>>>> + register struct S2 b asm ("xmm0"); >>>>>>> + return b.s2f1.s1f[i]; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo_s2f1 (3)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..7820c2f >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-lbv.c >>>>>>> @@ -0,0 +1,33 @@ >>>>>>> +/* { dg-do run } */ >>>>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>>>> + >>>>>>> + >>>>>>> +#define SHOULDFAIL >>>>>>> + >>>>>>> +#include "mpx-check.h" >>>>>>> + >>>>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>>>> + >>>>>>> +struct S1 >>>>>>> +{ >>>>>>> + v8 s1f; >>>>>>> +}; >>>>>>> + >>>>>>> +struct S2 >>>>>>> +{ >>>>>>> + struct S1 s2f1; >>>>>>> + v8 s2f2; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo_s2f2 (int i) >>>>>>> +{ >>>>>>> + register struct S2 b asm ("xmm0"); >>>>>>> + return b.s2f2[i]; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo_s2f2 (-1)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..0816e58 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-nov.c >>>>>>> @@ -0,0 +1,30 @@ >>>>>>> +/* { dg-do run } */ >>>>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>>>> + >>>>>>> + >>>>>>> +#include "mpx-check.h" >>>>>>> + >>>>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>>>> + >>>>>>> +struct S1 >>>>>>> +{ >>>>>>> + v8 s1f; >>>>>>> +}; >>>>>>> + >>>>>>> +struct S2 >>>>>>> +{ >>>>>>> + struct S1 s2f1; >>>>>>> + v8 s2f2; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo_s2f2 (int i) >>>>>>> +{ >>>>>>> + register struct S2 b asm ("xmm0"); >>>>>>> + return b.s2f2[i]; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo_s2f2 (0)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..94261a7 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-2-ubv.c >>>>>>> @@ -0,0 +1,33 @@ >>>>>>> +/* { dg-do run } */ >>>>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>>>> + >>>>>>> + >>>>>>> +#define SHOULDFAIL >>>>>>> + >>>>>>> +#include "mpx-check.h" >>>>>>> + >>>>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>>>> + >>>>>>> +struct S1 >>>>>>> +{ >>>>>>> + v8 s1f; >>>>>>> +}; >>>>>>> + >>>>>>> +struct S2 >>>>>>> +{ >>>>>>> + struct S1 s2f1; >>>>>>> + v8 s2f2; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo_s2f2 (int i) >>>>>>> +{ >>>>>>> + register struct S2 b asm ("xmm0"); >>>>>>> + return b.s2f2[i]; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo_s2f2 (3)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..f273d58 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-lbv.c >>>>>>> @@ -0,0 +1,27 @@ >>>>>>> +/* { 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))); >>>>>>> + >>>>>>> +struct S1 >>>>>>> +{ >>>>>>> + v16 s1f1; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo_s1f1 (int i) >>>>>>> +{ >>>>>>> + register struct S1 b asm ("xmm0"); >>>>>>> + return b.s1f1[i]; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo_s1f1 (-1)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..aa8f7b9 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-nov.c >>>>>>> @@ -0,0 +1,24 @@ >>>>>>> +/* { dg-do run } */ >>>>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>>>> + >>>>>>> + >>>>>>> +#include "mpx-check.h" >>>>>>> + >>>>>>> +typedef int v16 __attribute__ ((vector_size (16))); >>>>>>> + >>>>>>> +struct S1 >>>>>>> +{ >>>>>>> + v16 s1f1; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo_s1f1 (int i) >>>>>>> +{ >>>>>>> + register struct S1 b asm ("xmm0"); >>>>>>> + return b.s1f1[i]; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo_s1f1 (0)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..3d0c9b2 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-3-ubv.c >>>>>>> @@ -0,0 +1,27 @@ >>>>>>> +/* { 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))); >>>>>>> + >>>>>>> +struct S1 >>>>>>> +{ >>>>>>> + v16 s1f1; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo_s1f1 (int i) >>>>>>> +{ >>>>>>> + register struct S1 b asm ("xmm0"); >>>>>>> + return b.s1f1[i]; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo_s1f1 (7)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-lbv.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-lbv.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..e81b942 >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-lbv.c >>>>>>> @@ -0,0 +1,31 @@ >>>>>>> +/* { dg-do run } */ >>>>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>>>> + >>>>>>> + >>>>>>> +#define SHOULDFAIL >>>>>>> + >>>>>>> +#include "mpx-check.h" >>>>>>> + >>>>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>>>> + >>>>>>> +struct S2 >>>>>>> +{ >>>>>>> + v8 s2f2; >>>>>>> + int* f3; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo (int i) >>>>>>> +{ >>>>>>> + register struct S2 b asm ("xmm0"); >>>>>>> + int k = 5; >>>>>>> + b.f3 = &k; >>>>>>> + b.f3 = b.f3 + i; >>>>>>> + return *b.f3; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo (-1)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-nov.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-nov.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..4b1f1ac >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-nov.c >>>>>>> @@ -0,0 +1,28 @@ >>>>>>> +/* { dg-do run } */ >>>>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>>>> + >>>>>>> + >>>>>>> +#include "mpx-check.h" >>>>>>> + >>>>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>>>> + >>>>>>> +struct S2 >>>>>>> +{ >>>>>>> + v8 s2f2; >>>>>>> + int* f3; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo (int i) >>>>>>> +{ >>>>>>> + register struct S2 b asm ("xmm0"); >>>>>>> + int k = 5; >>>>>>> + b.f3 = &k; >>>>>>> + b.f3 = b.f3 + i; >>>>>>> + return *b.f3; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo (0)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-ubv.c >>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-ubv.c >>>>>>> new file mode 100644 >>>>>>> index 0000000..e95e68f >>>>>>> --- /dev/null >>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/hard-reg-4-ubv.c >>>>>>> @@ -0,0 +1,31 @@ >>>>>>> +/* { dg-do run } */ >>>>>>> +/* { dg-shouldfail "bounds violation" } */ >>>>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>>>> + >>>>>>> + >>>>>>> +#define SHOULDFAIL >>>>>>> + >>>>>>> +#include "mpx-check.h" >>>>>>> + >>>>>>> +typedef int v8 __attribute__ ((vector_size (8))); >>>>>>> + >>>>>>> +struct S2 >>>>>>> +{ >>>>>>> + v8 s2f2; >>>>>>> + int* f3; >>>>>>> +}; >>>>>>> + >>>>>>> +int foo (int i) >>>>>>> +{ >>>>>>> + register struct S2 b asm ("xmm0"); >>>>>>> + int k = 5; >>>>>>> + b.f3 = &k; >>>>>>> + b.f3 = b.f3 + i; >>>>>>> + return *b.f3; >>>>>>> +} >>>>>>> + >>>>>>> +int mpx_test (int argc, const char **argv) >>>>>>> +{ >>>>>>> + printf ("%d\n", foo (1)); >>>>>>> + return 0; >>>>>>> +} >>>>>>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c >>>>>>> index b1ff218..15c0da6 100644 >>>>>>> --- a/gcc/tree-chkp.c >>>>>>> +++ b/gcc/tree-chkp.c >>>>>>> @@ -679,6 +679,17 @@ chkp_erase_completed_bounds (void) >>>>>>> chkp_completed_bounds_set = new hash_set<tree>; >>>>>>> } >>>>>>> >>>>>>> +/* 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_var_fake_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); >>>>>>> +} >>>>>>> + >>>>>>> /* Mark BOUNDS associated with PTR as incomplete. */ >>>>>>> static void >>>>>>> chkp_register_incomplete_bounds (tree bounds, tree ptr) >>>>>>> @@ -1040,10 +1051,24 @@ chkp_add_modification_to_stmt_list (tree lhs, >>>>>>> stmts->avail--; >>>>>>> } >>>>>>> >>>>>>> -/* Build and return ADDR_EXPR for specified object OBJ. */ >>>>>>> +/* Build and return ADDR_EXPR for specified object OBJ. >>>>>>> + There is a special case for which we cannot return >>>>>>> + ADDR_EXPR - if the object is declared to be placed >>>>>>> + on a fixed hard register - in this case we cannot >>>>>>> + take its address, so we use the object itself. The >>>>>>> + caller of this function must be aware of that and >>>>>>> + use proper checks if necessary. */ >>>>>> >>>>>> I don't follow the idea of this change. >>>>>> >>>>>> If we want to use fake address for register vars then why not to >>>>>> return this fake value by this function? In case of accessing a >>>>>> component of register var we should return fake value + required >>>>>> offset then. >>>>>> >>>>>>> static tree >>>>>>> chkp_build_addr_expr (tree obj) >>>>>>> { >>>>>>> + /* We first check whether it is a "hard reg case". */ >>>>>>> + tree outer = obj; >>>>>>> + while (TREE_CODE (outer) == COMPONENT_REF) >>>>>>> + outer = TREE_OPERAND (outer, 0); >>>>>> >>>>>> What about ARRAY_REF? Probably get_base_address is what you need. >>>>>> >>>>>>> + if (VAR_P (outer) && DECL_HARD_REGISTER (outer)) >>>>>>> + return obj; >>>>>>> + >>>>>>> + /* If not - return regular ADDR_EXPR. */ >>>>>>> return TREE_CODE (obj) == TARGET_MEM_REF >>>>>>> ? tree_mem_ref_addr (ptr_type_node, obj) >>>>>>> : build_fold_addr_expr (obj); >>>>>>> @@ -3170,6 +3195,11 @@ chkp_get_bounds_for_decl_addr (tree decl) >>>>>>> gcc_assert (VAR_P (decl)); >>>>>>> bounds = chkp_generate_extern_var_bounds (decl); >>>>>>> } >>>>>>> + else if (VAR_P (decl) && DECL_HARD_REGISTER (decl)) >>>>>>> + { >>>>>>> + tree lb = chkp_get_hard_register_var_fake_address (); >>>>>>> + bounds = chkp_make_bounds(lb, DECL_SIZE_UNIT (decl), NULL, >>>>>>> false); >>>>>>> + } >>>>>>> else >>>>>>> { >>>>>>> tree lb = chkp_build_addr_expr (decl); >>>>>>> @@ -3351,6 +3381,8 @@ chkp_narrow_bounds_to_field (tree bounds, tree >>>>>>> component, >>>>>>> tree field_ptr = chkp_build_addr_expr (component); >>>>>>> tree field_bounds; >>>>>>> >>>>>>> + if (!BOUNDED_P (field_ptr)) >>>>>>> + field_ptr = chkp_get_hard_register_var_fake_address (); >>>>>> >>>>>> This gives you fake pointer instead of fake pointer + offset. No? >>>>>> >>>>>>> field_bounds = chkp_make_bounds (field_ptr, size, iter, false); >>>>>>> >>>>>>> return chkp_intersect_bounds (field_bounds, bounds, iter); >>>>>>> @@ -3639,6 +3671,8 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, >>>>>>> gimple_stmt_iterator *iter) >>>>>>> addr = chkp_build_addr_expr (ptr_src); >>>>>>> bounds = chkp_build_bndldx (addr, ptr, iter); >>>>>>> } >>>>>>> + else if (VAR_P (ptr) && DECL_HARD_REGISTER (ptr)) >>>>>>> + bounds = chkp_make_addressed_object_bounds (ptr_src, iter); >>>>>> >>>>>> I don't get what this piece of code is for. >>>>>> >>>>>>> else >>>>>>> bounds = chkp_get_nonpointer_load_bounds (); >>>>>>> break; >>>>>>> @@ -4031,7 +4065,19 @@ chkp_process_stmt (gimple_stmt_iterator *iter, >>>>>>> tree node, >>>>>>> addr_first, >>>>>>> byte_position (field)); >>>>>>> } >>>>>>> - else >>>>>>> + else if (VAR_P (ptr) && DECL_HARD_REGISTER (ptr)) >>>>>>> + { >>>>>>> + gcc_assert (TREE_CODE (node) == ARRAY_REF >>>>>>> + || TREE_CODE (node) == COMPONENT_REF); >>>>>> >>>>>> This may never hit because this code is in a switch block filtering >>>>>> node to ARRAY_REF and COMPONENT_REF already. >>>>>> >>>>>>> + >>>>>>> + tree base = chkp_get_hard_register_var_fake_address (); >>>>>>> + tree indx = fold_convert_loc (loc, >>>>>>> + size_type_node, >>>>>>> + TREE_OPERAND (node, 1)); >>>>>> >>>>>> Code looks like it expects ARRAY_REF only but COMPONENT_REF >>>>>> is also possible. >>>>>> >>>>>>> + tree offset = size_binop_loc (loc, MULT_EXPR, size, indx); >>>>>> >>>>>> 'size' here holds a size of memory access, not size of array element. >>>>>> >>>>>> Overall it looks like all you need is a proper fix in >>>>>> chkp_build_addr_expr >>>>>> to use fake value when required. Many (all?) other changes might just >>>>>> go away then. >>>>>> >>>>>> Thanks, >>>>>> Ilya >>>>>> >>>>>>> + addr_first = fold_build_pointer_plus_loc (loc, base, offset); >>>>>>> + } >>>>>>> + else >>>>>>> addr_first = chkp_build_addr_expr (node); >>>>>>> } >>>>>>> break; >>>>>>> >>>>>>> 2017-03-23 20:57 GMT+01:00 Ilya Enkovich <enkovich....@gmail.com>: >>>>>>>> 2017-03-23 17:18 GMT+03:00 Alexander Ivchenko <aivch...@gmail.com>: >>>>>>>>> Hi, >>>>>>>>> >>>>>>>>> The patch below attempts to fix the PR. I checked that it did not >>>>>>>>> break any of mpx.exp tests, but I did not run the full testing yet. >>>>>>>>> Would like to know whether this approach is generally correct or not. >>>>>>>>> >>>>>>>>> The issue is that we have the hard reg vector variable: >>>>>>>>> >>>>>>>>> typedef int U __attribute__ ((vector_size (16))); >>>>>>>>> register U u asm("xmm0"); >>>>>>>>> >>>>>>>>> and chkp tries to instrument access to it: >>>>>>>>> >>>>>>>>> return u[i]; >>>>>>>>> >>>>>>>>> by doing that: >>>>>>>>> >>>>>>>>> __bound_tmp.0_4 = __builtin_ia32_bndmk (&u, 16); >>>>>>>>> >>>>>>>>> However, you cannot take an address of a register variable (in fact if >>>>>>>>> you do that, the compiler will give you "address of register variable >>>>>>>>> āuā requested" error), so expand, sensibly, gives an ICE on on &u >>>>>>>>> here. I believe that if there is no pointers, pointer bounds checker >>>>>>>>> shouldn't get involved into that business. What do you think? >>>>>>>> >>>>>>>> Hi! >>>>>>>> >>>>>>>> I think with this patch I can call foo with any index and thus access >>>>>>>> some random stack slot. The first thing we should answer is 'do we >>>>>>>> want to catch array index overflows in such cases'? If we want to (and >>>>>>>> this looks reasonable thing to do because it prevents invalid memory >>>>>>>> accesses) then this patch doesn't resolve the problem. >>>>>>>> >>>>>>>> I'm not sure it can affect the patch, but please consider more complex >>>>>>>> cases. E.g.: >>>>>>>> >>>>>>>> typedef int v8 __attribute__ ((vector_size(8))); >>>>>>>> >>>>>>>> struct U { >>>>>>>> v8 a; >>>>>>>> v8 b; >>>>>>>> }; >>>>>>>> >>>>>>>> int >>>>>>>> foo (int i) >>>>>>>> { >>>>>>>> register struct U u asm ("xmm0"); >>>>>>>> return u.b[i]; >>>>>>>> } >>>>>>>> >>>>>>>> One way to catch overflow in such cases might be to use some fake >>>>>>>> pointer value (e.g. 0) for such not addressible variable. This fake >>>>>>>> value >>>>>>>> would be used as base for memory access and as lower bound. I don't >>>>>>>> see other cases except array_ref overflow check where such value >>>>>>>> might be used. So this fake value will not be passed somewhere and >>>>>>>> will not be stored to Bounds Table. >>>>>>>> >>>>>>>> Thanks, >>>>>>>> Ilya >>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c >>>>>>>>> index 75caf83..e39ec9a 100644 >>>>>>>>> --- a/gcc/tree-chkp.c >>>>>>>>> +++ b/gcc/tree-chkp.c >>>>>>>>> @@ -3383,6 +3383,7 @@ chkp_parse_array_and_component_ref (tree node, >>>>>>>>> tree *ptr, >>>>>>>>> tree comp_to_narrow = NULL_TREE; >>>>>>>>> tree last_comp = NULL_TREE; >>>>>>>>> bool array_ref_found = false; >>>>>>>>> + bool is_register_var = false; >>>>>>>>> tree *nodes; >>>>>>>>> tree var; >>>>>>>>> int len; >>>>>>>>> @@ -3440,6 +3441,9 @@ chkp_parse_array_and_component_ref (tree node, >>>>>>>>> tree *ptr, >>>>>>>>> || TREE_CODE (var) == STRING_CST >>>>>>>>> || TREE_CODE (var) == SSA_NAME); >>>>>>>>> >>>>>>>>> + if (VAR_P (var) && DECL_HARD_REGISTER (var)) >>>>>>>>> + is_register_var = true; >>>>>>>>> + >>>>>>>>> *ptr = chkp_build_addr_expr (var); >>>>>>>>> } >>>>>>>>> >>>>>>>>> @@ -3455,7 +3459,11 @@ chkp_parse_array_and_component_ref (tree node, >>>>>>>>> tree *ptr, >>>>>>>>> >>>>>>>>> if (TREE_CODE (var) == ARRAY_REF) >>>>>>>>> { >>>>>>>>> - *safe = false; >>>>>>>>> + // Mark it as unsafe, unless the array being accessed >>>>>>>>> + // has been explicitly placed on a register: in this >>>>>>>>> + // case we cannot take a pointer of this variable, >>>>>>>>> + // so we don't instrument the access. >>>>>>>>> + *safe = is_register_var; >>>>>>>>> array_ref_found = true; >>>>>>>>> if (flag_chkp_narrow_bounds >>>>>>>>> && !flag_chkp_narrow_to_innermost_arrray >>>>>>>>> @@ -4001,6 +4009,19 @@ chkp_process_stmt (gimple_stmt_iterator *iter, >>>>>>>>> tree node, >>>>>>>>> bool bitfield; >>>>>>>>> tree elt; >>>>>>>>> >>>>>>>>> + { >>>>>>>>> + // We don't instrument accesses to arrays that >>>>>>>>> + // are explicitely assigned to hard registers. >>>>>>>>> + HOST_WIDE_INT bitsize, bitpos; >>>>>>>>> + tree base, offset; >>>>>>>>> + machine_mode mode; >>>>>>>>> + int unsignedp, reversep, volatilep = 0; >>>>>>>>> + base = get_inner_reference (node, &bitsize, &bitpos, >>>>>>>>> &offset, &mode, >>>>>>>>> + &unsignedp, &reversep, >>>>>>>>> &volatilep); >>>>>>>>> + if (VAR_P (base) && DECL_HARD_REGISTER (base)) >>>>>>>>> + safe = true; >>>>>>>>> + } >>>>>>>>> + >>>>>>>>> if (safe) >>>>>>>>> { >>>>>>>>> /* We are not going to generate any checks, so do not >>>>>>>>> >>>>>>>>> diff --git a/gcc/testsuite/gcc.target/i386/mpx/pr79990.c >>>>>>>>> b/gcc/testsuite/gcc.target/i386/mpx/pr79990.c >>>>>>>>> new file mode 100644 >>>>>>>>> index 0000000..a27734d >>>>>>>>> --- /dev/null >>>>>>>>> +++ b/gcc/testsuite/gcc.target/i386/mpx/pr79990.c >>>>>>>>> @@ -0,0 +1,18 @@ >>>>>>>>> +/* { dg-do compile } */ >>>>>>>>> +/* { dg-options "-fcheck-pointer-bounds -mmpx" } */ >>>>>>>>> + >>>>>>>>> +typedef int U __attribute__ ((vector_size (16))); >>>>>>>>> + >>>>>>>>> +int >>>>>>>>> +foo (int i) >>>>>>>>> +{ >>>>>>>>> +#if __SSE2__ >>>>>>>>> + register >>>>>>>>> +#endif >>>>>>>>> + U u >>>>>>>>> +#if __SSE2__ >>>>>>>>> + asm ("xmm0") >>>>>>>>> +#endif >>>>>>>>> + ; >>>>>>>>> + return u[i]; >>>>>>>>> +} >>>>>>>>> >>>>>>>>> regards, >>>>>>>>> Alexander