tree-chkp.c (chkp_get_hard_register_var_fake_base_address): New function.
authorAlexander Ivchenko <alexander.ivchenko@intel.com>
Thu, 8 Jun 2017 14:07:21 +0000 (14:07 +0000)
committerAlexander Ivchenko <aivchenk@gcc.gnu.org>
Thu, 8 Jun 2017 14:07:21 +0000 (14:07 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-lbv.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-nov.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/mpx/hard-reg-2-ubv.c [new file with mode: 0644]
gcc/tree-chkp.c

index ddc675bde45cc0d196d26712b0b20ff4b85eeff8..bf4e0952f71f72afe3eef8d69335b50760d5ccc0 100644 (file)
@@ -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.
index d709baff8c4fc98473f36fce85a3227f2e690758..e077cbb5f5a05468abc71922ab5cb215e2aca07c 100644 (file)
@@ -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 (file)
index 0000000..319e1ec
--- /dev/null
@@ -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 (file)
index 0000000..3c6d39a
--- /dev/null
@@ -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 (file)
index 0000000..7fe76c4
--- /dev/null
@@ -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;
+}
index 2300e989908a90982940cf29fd11728f9393e004..e36ecbfbbe0cdefa28d2a64e2f66bc4963d8e780 100644 (file)
@@ -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)
     {