re PR target/65527 (ICE: in expand_builtin_with_bounds, at builtins.c:7120 with ...
authorIlya Enkovich <ilya.enkovich@intel.com>
Mon, 1 Jun 2015 11:24:07 +0000 (11:24 +0000)
committerIlya Enkovich <ienkovich@gcc.gnu.org>
Mon, 1 Jun 2015 11:24:07 +0000 (11:24 +0000)
gcc/

PR target/65527
* cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Add
redirection for instrumented calls.
* lto-wrapper.c (merge_and_complain): Merge -fcheck-pointer-bounds.
(append_compiler_options): Append -fcheck-pointer-bounds.
* tree-chkp.h (chkp_copy_call_skip_bounds): New.
(chkp_redirect_edge): New.
* tree-chkp.c (chkp_copy_call_skip_bounds): New.
(chkp_redirect_edge): New.

gcc/testsuite/

PR target/65527
* gcc.target/i386/mpx/chkp-fix-calls-1.c: New.
* gcc.target/i386/mpx/chkp-fix-calls-2.c: New.
* gcc.target/i386/mpx/chkp-fix-calls-3.c: New.
* gcc.target/i386/mpx/chkp-fix-calls-4.c: New.

From-SVN: r223929

gcc/ChangeLog
gcc/cgraph.c
gcc/lto-wrapper.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-4.c [new file with mode: 0644]
gcc/tree-chkp.c
gcc/tree-chkp.h

index 4b007b4a0e0bbfc27f8689b05dead98168318e3d..d61b465bdb2cf4ff5c35055ba60db76971de6dbc 100644 (file)
@@ -1,3 +1,15 @@
+2015-06-01  Ilya Enkovich  <ilya.enkovich@intel.com>
+
+       PR target/65527
+       * cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Add
+       redirection for instrumented calls.
+       * lto-wrapper.c (merge_and_complain): Merge -fcheck-pointer-bounds.
+       (append_compiler_options): Append -fcheck-pointer-bounds.
+       * tree-chkp.h (chkp_copy_call_skip_bounds): New.
+       (chkp_redirect_edge): New.
+       * tree-chkp.c (chkp_copy_call_skip_bounds): New.
+       (chkp_redirect_edge): New.
+
 2015-06-01  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/66280
index dc7d3a74e1fa5e05d7e503c6c98f77c4b04e5503..6a674db4078f13352427b6aeef7d10a3796a287c 100644 (file)
@@ -1281,6 +1281,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
   tree lhs = gimple_call_lhs (e->call_stmt);
   gcall *new_stmt;
   gimple_stmt_iterator gsi;
+  bool skip_bounds = false;
 #ifdef ENABLE_CHECKING
   cgraph_node *node;
 #endif
@@ -1389,8 +1390,16 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
        }
     }
 
+  /* We might propagate instrumented function pointer into
+     not instrumented function and vice versa.  In such a
+     case we need to either fix function declaration or
+     remove bounds from call statement.  */
+  if (flag_check_pointer_bounds && e->callee)
+    skip_bounds = chkp_redirect_edge (e);
+
   if (e->indirect_unknown_callee
-      || decl == e->callee->decl)
+      || (decl == e->callee->decl
+         && !skip_bounds))
     return e->call_stmt;
 
 #ifdef ENABLE_CHECKING
@@ -1415,13 +1424,19 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
        }
     }
 
-  if (e->callee->clone.combined_args_to_skip)
+  if (e->callee->clone.combined_args_to_skip
+      || skip_bounds)
     {
       int lp_nr;
 
-      new_stmt
-       = gimple_call_copy_skip_args (e->call_stmt,
-                                     e->callee->clone.combined_args_to_skip);
+      new_stmt = e->call_stmt;
+      if (e->callee->clone.combined_args_to_skip)
+       new_stmt
+         = gimple_call_copy_skip_args (new_stmt,
+                                       e->callee->clone.combined_args_to_skip);
+      if (skip_bounds)
+       new_stmt = chkp_copy_call_skip_bounds (new_stmt);
+
       gimple_call_set_fndecl (new_stmt, e->callee->decl);
       gimple_call_set_fntype (new_stmt, gimple_call_fntype (e->call_stmt));
 
index 11bf9ad063913518326eaec429eb236f796024a8..d59bd8c6635c852971d21de9976b197e42970014 100644 (file)
@@ -273,6 +273,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options,
        case OPT_fwrapv:
        case OPT_fopenmp:
        case OPT_fopenacc:
+       case OPT_fcheck_pointer_bounds:
          /* For selected options we can merge conservatively.  */
          for (j = 0; j < *decoded_options_count; ++j)
            if ((*decoded_options)[j].opt_index == foption->opt_index)
@@ -503,6 +504,7 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts,
        case OPT_Ofast:
        case OPT_Og:
        case OPT_Os:
+       case OPT_fcheck_pointer_bounds:
          break;
 
        default:
index 239cf4908c7a87422f7ba23ff4d322b128574ea0..fab0df2e41a2022be5380ac55191cd7116611e0b 100644 (file)
@@ -1,3 +1,11 @@
+2015-06-01  Ilya Enkovich  <ilya.enkovich@intel.com>
+
+       PR target/65527
+       * gcc.target/i386/mpx/chkp-fix-calls-1.c: New.
+       * gcc.target/i386/mpx/chkp-fix-calls-2.c: New.
+       * gcc.target/i386/mpx/chkp-fix-calls-3.c: New.
+       * gcc.target/i386/mpx/chkp-fix-calls-4.c: New.
+
 2015-06-01  Alan Lawrence  <alan.lawrence@arm.com>
 
        * gcc.target/aarch64/advsimd-intrinsics/advsimd-intrinsics.exp: Pass
diff --git a/gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-1.c b/gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-1.c
new file mode 100644 (file)
index 0000000..cb4d229
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcheck-pointer-bounds -mmpx" } */
+
+#include "math.h"
+
+double
+test1 (double x, double y, double (*fn)(double, double))
+{
+  return fn (x, y);
+}
+
+double
+test2 (double x, double y)
+{
+  return test1 (x, y, copysign);
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-2.c b/gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-2.c
new file mode 100644 (file)
index 0000000..951e7de
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fcheck-pointer-bounds -mmpx -fno-inline" } */
+
+#include "math.h"
+
+double
+test1 (double x, double y, double (*fn)(double, double))
+{
+  return fn (x, y);
+}
+
+double
+test2 (double x, double y)
+{
+  return test1 (x, y, copysign);
+}
diff --git a/gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-3.c b/gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-3.c
new file mode 100644 (file)
index 0000000..439f631
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fexceptions -fcheck-pointer-bounds -mmpx" } */
+
+extern int f2 (const char*, int, ...);
+extern long int f3 (int *);
+extern void err (void) __attribute__((__error__("error")));
+
+extern __inline __attribute__ ((__always_inline__)) int
+f1 (int i, ...)
+{
+  if (__builtin_constant_p (i))
+    {
+      if (i)
+       err ();
+      return f2 ("", i);
+    }
+
+  return f2 ("", i);
+}
+
+int
+test ()
+{
+  int i;
+
+  if (f1 (0))
+    if (f3 (&i))
+      i = 0;
+
+  return i;
+}
+
+
diff --git a/gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-4.c b/gcc/testsuite/gcc.target/i386/mpx/chkp-fix-calls-4.c
new file mode 100644 (file)
index 0000000..1b7d703
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fcheck-pointer-bounds -mmpx" } */
+
+typedef void (func) (int *);
+
+static inline void
+bar (func f)
+{
+  int i;
+  f (&i);
+}
+
+void
+foo ()
+{
+  bar (0);
+}
index 88c1f459c182f8dab145d015a39ce38329f27c9a..015df1139c7bf49e80c93b6d5cbf19798b7af10b 100644 (file)
@@ -529,6 +529,71 @@ chkp_insert_retbnd_call (tree bndval, tree retval,
   return bndval;
 }
 
+/* Build a GIMPLE_CALL identical to CALL but skipping bounds
+   arguments.  */
+
+gcall *
+chkp_copy_call_skip_bounds (gcall *call)
+{
+  bitmap bounds;
+  unsigned i;
+
+  bitmap_obstack_initialize (NULL);
+  bounds = BITMAP_ALLOC (NULL);
+
+  for (i = 0; i < gimple_call_num_args (call); i++)
+    if (POINTER_BOUNDS_P (gimple_call_arg (call, i)))
+      bitmap_set_bit (bounds, i);
+
+  if (!bitmap_empty_p (bounds))
+    call = gimple_call_copy_skip_args (call, bounds);
+  gimple_call_set_with_bounds (call, false);
+
+  BITMAP_FREE (bounds);
+  bitmap_obstack_release (NULL);
+
+  return call;
+}
+
+/* Redirect edge E to the correct node according to call_stmt.
+   Return 1 if bounds removal from call_stmt should be done
+   instead of redirection.  */
+
+bool
+chkp_redirect_edge (cgraph_edge *e)
+{
+  bool instrumented = false;
+  tree decl = e->callee->decl;
+
+  if (e->callee->instrumentation_clone
+      || chkp_function_instrumented_p (decl))
+    instrumented = true;
+
+  if (instrumented
+      && !gimple_call_with_bounds_p (e->call_stmt))
+    e->redirect_callee (cgraph_node::get_create (e->callee->orig_decl));
+  else if (!instrumented
+          && gimple_call_with_bounds_p (e->call_stmt)
+          && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDCL)
+          && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDCU)
+          && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDSTX))
+    {
+      if (e->callee->instrumented_version)
+       e->redirect_callee (e->callee->instrumented_version);
+      else
+       {
+         tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
+         /* Avoid bounds removal if all args will be removed.  */
+         if (!args || TREE_VALUE (args) != void_type_node)
+           return true;
+         else
+           gimple_call_set_with_bounds (e->call_stmt, false);
+       }
+    }
+
+  return false;
+}
+
 /* Mark statement S to not be instrumented.  */
 static void
 chkp_mark_stmt (gimple s)
index 1bafe994da2213ac3297b3badea9abb904d1e6e5..b5ab56252ed3d293a3f2a435d0a6978abbf50571 100644 (file)
@@ -56,5 +56,7 @@ extern bool chkp_gimple_call_builtin_p (gimple call,
 extern void chkp_expand_bounds_reset_for_mem (tree mem, tree ptr);
 extern tree chkp_insert_retbnd_call (tree bndval, tree retval,
                                     gimple_stmt_iterator *gsi);
+extern gcall *chkp_copy_call_skip_bounds (gcall *call);
+extern bool chkp_redirect_edge (cgraph_edge *e);
 
 #endif /* GCC_TREE_CHKP_H */