aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexander Ivchenko <alexander.ivchenko@intel.com>2017-06-08 14:07:21 +0000
committerAlexander Ivchenko <aivchenk@gcc.gnu.org>2017-06-08 14:07:21 +0000
commit0036534fa36a1e3f62ddaffb3d6c2fa565511f17 (patch)
treeae9a619499347db624cba5c08b23183acb68eaec /gcc
parentb69d9ac6a9f6fae426080c77ce4a395fafb49a5f (diff)
downloadgcc-0036534fa36a1e3f62ddaffb3d6c2fa565511f17.zip
gcc-0036534fa36a1e3f62ddaffb3d6c2fa565511f17.tar.gz
gcc-0036534fa36a1e3f62ddaffb3d6c2fa565511f17.tar.bz2
tree-chkp.c (chkp_get_hard_register_var_fake_base_address): New function.
gcc/ChangeLog: 2017-05-09 Alexander Ivchenko <aivchenk@gmail.com> * tree-chkp.c (chkp_get_hard_register_var_fake_base_address): New function. (chkp_get_hard_register_fake_addr_expr): Ditto. (chkp_build_addr_expr): Add check for hard reg case. (chkp_parse_array_and_component_ref): Ditto. (chkp_find_bounds_1): Ditto. (chkp_process_stmt): Don't generate bounds store for hard reg case. gcc/testsuite/ChangeLog: 2017-05-09 Alexander Ivchenko <aivchenk@gmail.com> * gcc.target/i386/mpx/hard-reg-2-lbv.c: New test. * gcc.target/i386/mpx/hard-reg-2-nov.c: New test. * gcc.target/i386/mpx/hard-reg-2-ubv.c: New test. From-SVN: r249015
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c21
-rw-r--r--gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c21
-rw-r--r--gcc/tree-chkp.c68
6 files changed, 145 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ddc675b..bf4e095 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2017-06-08 Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+ * tree-chkp.c (chkp_get_hard_register_var_fake_base_address):
+ New function.
+ (chkp_get_hard_register_fake_addr_expr): Ditto.
+ (chkp_build_addr_expr): Add check for hard reg case.
+ (chkp_parse_array_and_component_ref): Ditto.
+ (chkp_find_bounds_1): Ditto.
+ (chkp_process_stmt): Don't generate bounds store for
+ hard reg case.
+
2017-06-08 Jan Hubicka <hubicka@ucw.cz>
* predict.c (maybe_hot_bb_p): Do not check profile status.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d709baf..e077cbb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2017-06-08 Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+ * gcc.target/i386/mpx/hard-reg-2-lbv.c: New test.
+ * gcc.target/i386/mpx/hard-reg-2-nov.c: New test.
+ * gcc.target/i386/mpx/hard-reg-2-ubv.c: New test.
+
2017-06-08 Jan Hubicka <hubicka@ucw.cz>
* g++.dg/tree-ssa/counts-1.C: New testcase.
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/tree-chkp.c b/gcc/tree-chkp.c
index 2300e98..e36ecbf 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)
{