public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Move Asan instrumentation to sanopt pass
@ 2014-07-18 13:39 Yury Gribov
  2014-07-18 15:38 ` Jakub Jelinek
  2014-07-22 14:06 ` Richard Biener
  0 siblings, 2 replies; 23+ messages in thread
From: Yury Gribov @ 2014-07-18 13:39 UTC (permalink / raw)
  To: GCC Patches
  Cc: Jakub Jelinek, Konstantin Serebryany, Dmitry Vyukov,
	Viacheslav Garbuzov, Marek Polacek

[-- Attachment #1: Type: text/plain, Size: 1447 bytes --]

Hi all,

Attached patch delays generation of Asan memory checking code
until sanopt pass. This is a first step towards global static analysis
of Asan instrumentation which would allow to
* remove redundant instrumentations
* aggregate adjacent Asan checks
* move invariant checks from loops

The patch also changes the logic behind 
asan-instrumentation-with-call-threshold
parameter to more closely match LLVM.

The patch splits build_check_stmt routine to two parts. The first one
(called from asan0/asan passes) inserts calls to internal functions
ASAN_LOAD and ASAN_STORE. The second expands those to inline checks
(in asan_expand_check_ifn).

Here are some obvious disadvantages:
* passing additional info via hidden parameter of
ASAN_{LOAD,STORE} is ugly but I'm not sure how to do this better
* delayed expansion runs after all optimization passes
so inlined Asan checks will not get a chance to be
CSE-ed, etc.; this may probably be solved by moving sanopt earlier
in the pipeline. BTW I haven't experienced notable slowdowns in my 
experiments.
* passing program pointers to ASAN_{LOAD,STORE} may damage alias analysis
because all pointers will now escape; I probably could
provide fnspec with (EAF_DIRECT | EAF_NOCLOBBER | EAF_NOESCAPE) or
even EAF_UNUSED for these functions but this does not seem
to be supported in current middle-end.

The patch was bootstrapped, regtested and asan-bootstrapped on x64.

Is this ok for trunk?

-Yury

[-- Attachment #2: asan_ifn-1.diff --]
[-- Type: text/x-diff, Size: 41364 bytes --]

commit ec53fb00ab4a762c3c4cefa886f6cd9ee549de8d
Author: Yury Gribov <y.gribov@samsung.com>
Date:   Thu Jul 17 09:45:26 2014 +0400

    Move inlining of Asan memory checks to sanopt pass.
    Change asan-instrumentation-with-call-threshold to more closely match LLVM.
    
    gcc/
    
    2014-07-17  Yury Gribov  <y.gribov@samsung.com>
    
    	* asan.c (asan_check_flags): New enum.
    	(build_check_stmt_with_calls): Removed function.
    	(build_check_stmt): Split inlining logic to
    	asan_expand_check_ifn.
    	(instrument_derefs): Rename parameter.
    	(instrument_mem_region_access): Rename parameter.
    	(instrument_strlen_call): Likewise.
    	(asan_expand_check_ifn): New function.
    	(asan_instrument): Remove old code.
    	(pass_sanopt::execute): Change handling of
    	asan-instrumentation-with-call-threshold.
    	* doc/invoke.texi (asan-instrumentation-with-call-threshold):
    	Update description.
    	* gimple_iterator.h (gsi_start_bb): Fix uninitialized
    	warnings.
    	* internal-fn.c (expand_ASAN_LOAD): New function.
    	(expand_ASAN_STORE): Likewise.
    	* internal-fn.def (ASAN_LOAD): New internal function.
    	(ASAN_STORE): Likewise.
    	* params.def (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD):
    	Update description.
    	(PARAM_ASAN_USE_AFTER_RETURN): Likewise.
    
    gcc/testsuite/
    
    2014-07-17  Yury Gribov  <y.gribov@samsung.com>
    
    	* c-c++-common/asan/inc.c: Update test.
    	* c-c++-common/asan/instrument-with-calls-2.c: Likewise.
    	* c-c++-common/asan/no-redundant-instrumentation-1.c: Likewise.
    	* c-c++-common/asan/no-redundant-instrumentation-2.c: Likewise.
    	* c-c++-common/asan/no-redundant-instrumentation-3.c: Likewise.
    	* c-c++-common/asan/no-redundant-instrumentation-4.c: Likewise.
    	* c-c++-common/asan/no-redundant-instrumentation-5.c: Likewise.
    	* c-c++-common/asan/no-redundant-instrumentation-6.c: Likewise.
    	* c-c++-common/asan/no-redundant-instrumentation-7.c: Likewise.
    	* c-c++-common/asan/no-redundant-instrumentation-8.c: Likewise.
    	* c-c++-common/asan/no-redundant-instrumentation-9.c: Likewise.

diff --git a/gcc/asan.c b/gcc/asan.c
index 0d78634..7fe079d 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -243,18 +243,15 @@ static GTY(()) tree shadow_ptr_types[2];
 /* Decl for __asan_option_detect_stack_use_after_return.  */
 static GTY(()) tree asan_detect_stack_use_after_return;
 
-/* Number of instrumentations in current function so far.  */
-
-static int asan_num_accesses;
-
-/* Check whether we should replace inline instrumentation with calls.  */
-
-static inline bool
-use_calls_p ()
+/* Various flags for Asan builtins.  */
+enum asan_check_flags
 {
-  return ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
-    && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
-}
+  ASAN_CHECK_NON_ZERO_LEN = 1 << 0,
+  ASAN_CHECK_SCALAR_ACCESS = 1 << 1,
+  ASAN_CHECK_START_INSTRUMENTED = 1 << 2,
+  ASAN_CHECK_END_INSTRUMENTED = 1 << 3,
+  ASAN_CHECK_LAST
+};
 
 /* Hashtable support for memory references used by gimple
    statements.  */
@@ -1553,55 +1550,6 @@ maybe_create_ssa_name (location_t loc, tree base, gimple_stmt_iterator *iter,
   return gimple_assign_lhs (g);
 }
 
-/* Instrument the memory access instruction using callbacks.
-   Parameters are similar to BUILD_CHECK_STMT.  */
-
-static void
-build_check_stmt_with_calls (location_t loc, tree base, tree len,
-			     HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter,
-			     bool before_p, bool is_store, bool is_scalar_access)
-{
-  gimple_stmt_iterator gsi = *iter;
-  tree base_ssa = maybe_create_ssa_name (loc, base, &gsi, before_p);
-
-  gimple g
-    = gimple_build_assign_with_ops (NOP_EXPR,
-				    make_ssa_name (pointer_sized_int_node, NULL),
-				    base_ssa, NULL_TREE);
-  gimple_set_location (g, loc);
-  if (before_p)
-    gsi_insert_before (&gsi, g, GSI_NEW_STMT);
-  else
-    gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-  tree base_addr = gimple_assign_lhs (g);
-
-  int nargs;
-  tree fun
-    = check_func (is_store, is_scalar_access ? size_in_bytes : -1, &nargs);
-  if (nargs == 1)
-    g = gimple_build_call (fun, 1, base_addr);
-  else
-    {
-      gcc_assert (nargs == 2);
-      g = gimple_build_assign_with_ops (NOP_EXPR,
-					make_ssa_name (pointer_sized_int_node,
-						       NULL),
-					len, NULL_TREE);
-      gimple_set_location (g, loc);
-      gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-      tree sz_arg = gimple_assign_lhs (g);
-      g = gimple_build_call (fun, nargs, base_addr, sz_arg);
-    }
-  gimple_set_location (g, loc);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
-  if (!before_p)
-    {
-      gsi_next (&gsi);
-      *iter = gsi;
-    }
-}
-
 /* Instrument the memory access instruction BASE.  Insert new
    statements before or after ITER.
 
@@ -1622,27 +1570,30 @@ build_check_stmt_with_calls (location_t loc, tree base, tree len,
    otherwise, it points to the statement logically following it.  */
 
 static void
-build_check_stmt (location_t location, tree base, tree len,
+build_check_stmt (location_t loc, tree base, tree len,
 		  HOST_WIDE_INT size_in_bytes, gimple_stmt_iterator *iter,
-		  bool non_zero_len_p, bool before_p, bool is_store,
+		  bool is_non_zero_len, bool before_p, bool is_store,
 		  bool is_scalar_access, unsigned int align = 0,
 		  bool start_instrumented = false,
 		  bool end_instrumented = false)
 {
   gimple_stmt_iterator gsi = *iter;
   gimple g;
-  tree uintptr_type
-    = build_nonstandard_integer_type (TYPE_PRECISION (TREE_TYPE (base)), 1);
 
-  gcc_assert (!(size_in_bytes > 0 && !non_zero_len_p));
+  gcc_assert (!(size_in_bytes > 0 && !is_non_zero_len));
 
   if (start_instrumented && end_instrumented)
     {
       if (!before_p)
-        gsi_next (iter);
+	gsi_next (iter);
       return;
     }
 
+  gsi = *iter;
+
+  base = unshare_expr (base);
+  base = maybe_create_ssa_name (loc, base, &gsi, before_p);
+
   if (len)
     len = unshare_expr (len);
   else
@@ -1654,9 +1605,8 @@ build_check_stmt (location_t location, tree base, tree len,
   if (size_in_bytes > 1)
     {
       if ((size_in_bytes & (size_in_bytes - 1)) != 0
-	  || !is_scalar_access
 	  || size_in_bytes > 16)
-	size_in_bytes = -1;
+	is_scalar_access = false;
       else if (align && align < size_in_bytes * BITS_PER_UNIT)
 	{
 	  /* On non-strict alignment targets, if
@@ -1667,189 +1617,33 @@ build_check_stmt (location_t location, tree base, tree len,
 	  if (size_in_bytes != 16
 	      || STRICT_ALIGNMENT
 	      || align < 8 * BITS_PER_UNIT)
-	    size_in_bytes = -1;
-	}
-    }
-
-  HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes;
-
-  tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0];
-  tree shadow_type = TREE_TYPE (shadow_ptr_type);
-
-  base = unshare_expr (base);
-
-  if (use_calls_p ())
-    {
-      gsi = *iter;
-      build_check_stmt_with_calls (location, base, len, size_in_bytes, iter,
-				   before_p, is_store, is_scalar_access);
-      return;
-    }
-
-  ++asan_num_accesses;
-
-  if (!non_zero_len_p)
-    {
-      gcc_assert (before_p);
-
-      /* So, the length of the memory area to asan-protect is
-	 non-constant.  Let's guard the generated instrumentation code
-	 like:
-
-	 if (len != 0)
-	   {
-	     //asan instrumentation code goes here.
-	   }
-	 // falltrough instructions, starting with *ITER.  */
-
-      g = gimple_build_cond (NE_EXPR,
-			     len,
-			     build_int_cst (TREE_TYPE (len), 0),
-			     NULL_TREE, NULL_TREE);
-      gimple_set_location (g, location);
-
-      basic_block then_bb, fallthrough_bb;
-      insert_if_then_before_iter (g, iter, /*then_more_likely_p=*/true,
-				  &then_bb, &fallthrough_bb);
-      /* Note that fallthrough_bb starts with the statement that was
-	 pointed to by ITER.  */
-
-      /* The 'then block' of the 'if (len != 0) condition is where
-	 we'll generate the asan instrumentation code now.  */
-      gsi = gsi_last_bb (then_bb);
-      build_check_stmt (location, base, len, size_in_bytes, &gsi,
-			/*non_zero_len_p*/true, /*before_p*/true, is_store,
-			is_scalar_access, align,
-			start_instrumented, end_instrumented);
-      return;
-    }
-
-  /* Get an iterator on the point where we can add the condition
-     statement for the instrumentation.  */
-  basic_block then_bb, else_bb;
-  gsi = create_cond_insert_point (&gsi, before_p,
-				  /*then_more_likely_p=*/false,
-				  /*create_then_fallthru_edge=*/false,
-				  &then_bb,
-				  &else_bb);
-
-  tree base_ssa = maybe_create_ssa_name (location, base, &gsi,
-					 /*before_p*/false);
-
-  g = gimple_build_assign_with_ops (NOP_EXPR,
-				    make_ssa_name (uintptr_type, NULL),
-				    base_ssa, NULL_TREE);
-  gimple_set_location (g, location);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-  tree base_addr = gimple_assign_lhs (g);
-
-  tree t = NULL_TREE;
-  if (real_size_in_bytes >= 8)
-    {
-      tree shadow = build_shadow_mem_access (&gsi, location, base_addr,
-					     shadow_ptr_type);
-      t = shadow;
-    }
-  else
-    {
-      /* Slow path for 1, 2 and 4 byte accesses.  */
-
-      if (!start_instrumented)
-	{
-	  /* Test (shadow != 0)
-		  & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow).  */
-	  tree shadow = build_shadow_mem_access (&gsi, location, base_addr,
-						 shadow_ptr_type);
-	  gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
-	  gimple_seq seq = NULL;
-	  gimple_seq_add_stmt (&seq, shadow_test);
-	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, base_addr, 7));
-	  gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
-						      gimple_seq_last (seq)));
-	  if (real_size_in_bytes > 1)
-	    gimple_seq_add_stmt (&seq,
-				 build_assign (PLUS_EXPR, gimple_seq_last (seq),
-					       real_size_in_bytes - 1));
-	  gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
-						   gimple_seq_last (seq),
-						   shadow));
-	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
-						   gimple_seq_last (seq)));
-	  t = gimple_assign_lhs (gimple_seq_last (seq));
-	  gimple_seq_set_location (seq, location);
-	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
-	}
-
-      /* For non-constant, misaligned or otherwise weird access sizes,
-	 check first and last byte.  */
-      if (size_in_bytes == -1 && !end_instrumented)
-	{
-	  g = gimple_build_assign_with_ops (MINUS_EXPR,
-					    make_ssa_name (uintptr_type, NULL),
-					    len,
-					    build_int_cst (uintptr_type, 1));
-	  gimple_set_location (g, location);
-	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-	  tree last = gimple_assign_lhs (g);
-	  g = gimple_build_assign_with_ops (PLUS_EXPR,
-					    make_ssa_name (uintptr_type, NULL),
-					    base_addr,
-					    last);
-	  gimple_set_location (g, location);
-	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-	  tree base_end_addr = gimple_assign_lhs (g);
-
-	  tree shadow = build_shadow_mem_access (&gsi, location, base_end_addr,
-						 shadow_ptr_type);
-	  gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
-	  gimple_seq seq = NULL;
-	  gimple_seq_add_stmt (&seq, shadow_test);
-	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
-						   base_end_addr, 7));
-	  gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
-						      gimple_seq_last (seq)));
-	  gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
-						   gimple_seq_last (seq),
-						   shadow));
-	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
-						   gimple_seq_last (seq)));
-	  if (!start_instrumented)
-	    gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t,
-						     gimple_seq_last (seq)));
-	  t = gimple_assign_lhs (gimple_seq_last (seq));
-	  gimple_seq_set_location (seq, location);
-	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
+	    is_scalar_access = false;
 	}
     }
 
-  g = gimple_build_cond (NE_EXPR, t, build_int_cst (TREE_TYPE (t), 0),
-			 NULL_TREE, NULL_TREE);
-  gimple_set_location (g, location);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
-  /* Generate call to the run-time library (e.g. __asan_report_load8).  */
-  gsi = gsi_start_bb (then_bb);
-  int nargs;
-  tree fun = report_error_func (is_store, is_scalar_access ? size_in_bytes : -1,
-				&nargs);
-  if (nargs == 1)
-      g = gimple_build_call (fun, 1, base_addr);
+  HOST_WIDE_INT flags = 0;
+  if (is_non_zero_len)
+    flags |= ASAN_CHECK_NON_ZERO_LEN;
+  if (is_scalar_access)
+    flags |= ASAN_CHECK_SCALAR_ACCESS;
+  if (start_instrumented)
+    flags |= ASAN_CHECK_START_INSTRUMENTED;
+  if (end_instrumented)
+    flags |= ASAN_CHECK_END_INSTRUMENTED;
+
+  g = gimple_build_call_internal (is_store ? IFN_ASAN_STORE : IFN_ASAN_LOAD,
+				  3,
+				  build_int_cst (integer_type_node, flags),
+				  base, len);
+  gimple_set_location (g, loc);
+  if (before_p)
+    gsi_insert_before (&gsi, g, GSI_SAME_STMT);
   else
     {
-      gcc_assert (nargs == 2);
-      g = gimple_build_assign_with_ops (NOP_EXPR,
-					make_ssa_name (pointer_sized_int_node,
-						       NULL),
-					len, NULL_TREE);
-      gimple_set_location (g, location);
       gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-      tree sz_arg = gimple_assign_lhs (g);
-      g = gimple_build_call (fun, nargs, base_addr, sz_arg);
+      gsi_next (&gsi);
+      *iter = gsi;
     }
-  gimple_set_location (g, location);
-  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
-
-  *iter = gsi_start_bb (else_bb);
 }
 
 /* If T represents a memory access, add instrumentation code before ITER.
@@ -1942,7 +1736,7 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t,
     {
       unsigned int align = get_object_alignment (t);
       build_check_stmt (location, base, NULL_TREE, size_in_bytes, iter,
-			/*non_zero_len_p*/size_in_bytes > 0, /*before_p=*/true,
+			/*is_non_zero_len*/size_in_bytes > 0, /*before_p=*/true,
 			is_store, /*is_scalar_access*/true, align);
       update_mem_ref_hash_table (base, size_in_bytes);
       update_mem_ref_hash_table (t, size_in_bytes);
@@ -1980,7 +1774,7 @@ instrument_mem_region_access (tree base, tree len,
   HOST_WIDE_INT size_in_bytes = tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
 
   build_check_stmt (location, base, len, size_in_bytes, iter,
-		    /*non_zero_len_p*/size_in_bytes > 0, /*before_p*/true,
+		    /*is_non_zero_len*/size_in_bytes > 0, /*before_p*/true,
 		    is_store, /*is_scalar_access*/false, /*align*/0,
 		    start_instrumented, end_instrumented);
 
@@ -2028,6 +1822,7 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
   tree str_arg = gimple_call_arg (call, 0);
   bool start_instrumented = has_mem_ref_been_instrumented (str_arg, 1);
 
+  // TODO: remove this?
   tree cptr_type = build_pointer_type (char_type_node);
   gimple str_arg_ssa =
     gimple_build_assign_with_ops (NOP_EXPR,
@@ -2037,7 +1832,7 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
   gsi_insert_before (iter, str_arg_ssa, GSI_SAME_STMT);
 
   build_check_stmt (loc, gimple_assign_lhs (str_arg_ssa), NULL_TREE, 1, iter,
-		    /*non_zero_len_p*/true, /*before_p=*/true,
+		    /*is_non_zero_len*/true, /*before_p=*/true,
 		    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0,
 		    start_instrumented, start_instrumented);
 
@@ -2050,7 +1845,7 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
   gsi_insert_after (iter, g, GSI_NEW_STMT);
 
   build_check_stmt (loc, gimple_assign_lhs (g), NULL_TREE, 1, iter,
-		    /*non_zero_len_p*/true, /*before_p=*/false,
+		    /*is_non_zero_len*/true, /*before_p=*/false,
 		    /*is_store=*/false, /*is_scalar_access*/true, /*align*/0);
 
   return true;
@@ -2617,6 +2412,214 @@ asan_finish_file (void)
   flag_sanitize |= SANITIZE_ADDRESS;
 }
 
+/* Expand the ASAN_{LOAD,STORE} builtins.  */
+
+static void
+asan_expand_check_ifn (gimple_stmt_iterator *iter, bool is_store,
+		       bool use_calls)
+{
+  gimple g = gsi_stmt (*iter);
+  location_t loc = gimple_location (g);
+
+  HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
+  gcc_assert (flags < ASAN_CHECK_LAST);
+  bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
+
+  tree base = gimple_call_arg (g, 1);
+  tree len = gimple_call_arg (g, 2);
+
+  HOST_WIDE_INT size_in_bytes
+    = is_scalar_access && tree_fits_shwi_p (len) ? tree_to_shwi (len) : -1;
+
+  if (use_calls)
+    {
+      /* Instrument using callbacks.  */
+      gimple g
+        = gimple_build_assign_with_ops (NOP_EXPR,
+				        make_ssa_name (pointer_sized_int_node,
+                                        NULL),
+				        base, NULL_TREE);
+      gimple_set_location (g, loc);
+      gsi_insert_before (iter, g, GSI_SAME_STMT);
+      tree base_addr = gimple_assign_lhs (g);
+
+      int nargs;
+      tree fun = check_func (is_store, size_in_bytes, &nargs);
+      if (nargs == 1)
+        g = gimple_build_call (fun, 1, base_addr);
+      else
+        {
+          gcc_assert (nargs == 2);
+          g = gimple_build_assign_with_ops (NOP_EXPR,
+					    make_ssa_name (pointer_sized_int_node,
+						           NULL),
+					    len, NULL_TREE);
+          gimple_set_location (g, loc);
+          gsi_insert_before (iter, g, GSI_SAME_STMT);
+          tree sz_arg = gimple_assign_lhs (g);
+          g = gimple_build_call (fun, nargs, base_addr, sz_arg);
+        }
+      gimple_set_location (g, loc);
+      gsi_replace (iter, g, false);
+      return;
+    }
+
+  bool is_non_zero_len = (flags & ASAN_CHECK_NON_ZERO_LEN) != 0;
+  bool start_instrumented = (flags & ASAN_CHECK_START_INSTRUMENTED) != 0;
+  bool end_instrumented = (flags & ASAN_CHECK_END_INSTRUMENTED) != 0;
+
+  HOST_WIDE_INT real_size_in_bytes = size_in_bytes == -1 ? 1 : size_in_bytes;
+
+  tree uintptr_type
+    = build_nonstandard_integer_type (TYPE_PRECISION (TREE_TYPE (base)), 1);
+
+  tree shadow_ptr_type = shadow_ptr_types[real_size_in_bytes == 16 ? 1 : 0];
+  tree shadow_type = TREE_TYPE (shadow_ptr_type);
+
+  gimple_stmt_iterator gsi = *iter;
+
+  if (!is_non_zero_len)
+    {
+      /* So, the length of the memory area to asan-protect is
+	 non-constant.  Let's guard the generated instrumentation code
+	 like:
+
+	 if (len != 0)
+	   {
+	     //asan instrumentation code goes here.
+	   }
+	 // falltrough instructions, starting with *ITER.  */
+
+      g = gimple_build_cond (NE_EXPR,
+			    len,
+			    build_int_cst (TREE_TYPE (len), 0),
+			    NULL_TREE, NULL_TREE);
+      gimple_set_location (g, loc);
+
+      basic_block then_bb, fallthrough_bb;
+      insert_if_then_before_iter (g, iter, /*then_more_likely_p=*/true,
+				 &then_bb, &fallthrough_bb);
+      /* Note that fallthrough_bb starts with the statement that was
+	pointed to by ITER.  */
+
+      /* The 'then block' of the 'if (len != 0) condition is where
+	we'll generate the asan instrumentation code now.  */
+      gsi = gsi_last_bb (then_bb);
+    }
+
+  /* Get an iterator on the point where we can add the condition
+     statement for the instrumentation.  */
+  basic_block then_bb, else_bb;
+  gsi = create_cond_insert_point (&gsi, /*before_p*/false,
+				  /*then_more_likely_p=*/false,
+				  /*create_then_fallthru_edge=*/false,
+				  &then_bb,
+				  &else_bb);
+
+  g = gimple_build_assign_with_ops (NOP_EXPR,
+				    make_ssa_name (pointer_sized_int_node,
+						   NULL),
+				    base, NULL_TREE);
+  gimple_set_location (g, loc);
+  gsi_insert_before (&gsi, g, GSI_NEW_STMT);
+  tree base_addr = gimple_assign_lhs (g);
+
+  tree t = NULL_TREE;
+  if (real_size_in_bytes >= 8)
+    {
+      tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
+					     shadow_ptr_type);
+      t = shadow;
+    }
+  else
+    {
+      /* Slow path for 1, 2 and 4 byte accesses.  */
+
+      if (!start_instrumented)
+	{
+	  /* Test (shadow != 0)
+	     & ((base_addr & 7) + (real_size_in_bytes - 1)) >= shadow).  */
+	  tree shadow = build_shadow_mem_access (&gsi, loc, base_addr,
+						 shadow_ptr_type);
+	  gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
+	  gimple_seq seq = NULL;
+	  gimple_seq_add_stmt (&seq, shadow_test);
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, base_addr, 7));
+	  gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
+						      gimple_seq_last (seq)));
+	  if (real_size_in_bytes > 1)
+	    gimple_seq_add_stmt (&seq,
+				 build_assign (PLUS_EXPR, gimple_seq_last (seq),
+					       real_size_in_bytes - 1));
+	  gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
+						   gimple_seq_last (seq),
+						   shadow));
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
+						   gimple_seq_last (seq)));
+	  t = gimple_assign_lhs (gimple_seq_last (seq));
+	  gimple_seq_set_location (seq, loc);
+	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
+	}
+
+      /* For non-constant, misaligned or otherwise weird access sizes,
+	 check first and last byte.  */
+      if (size_in_bytes == -1 && !end_instrumented)
+	{
+	  g = gimple_build_assign_with_ops (MINUS_EXPR,
+					    make_ssa_name (uintptr_type, NULL),
+					    len,
+					    build_int_cst (uintptr_type, 1));
+	  gimple_set_location (g, loc);
+	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+	  tree last = gimple_assign_lhs (g);
+	  g = gimple_build_assign_with_ops (PLUS_EXPR,
+					    make_ssa_name (uintptr_type, NULL),
+					    base_addr,
+					    last);
+	  gimple_set_location (g, loc);
+	  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+	  tree base_end_addr = gimple_assign_lhs (g);
+
+	  tree shadow = build_shadow_mem_access (&gsi, loc, base_end_addr,
+						 shadow_ptr_type);
+	  gimple shadow_test = build_assign (NE_EXPR, shadow, 0);
+	  gimple_seq seq = NULL;
+	  gimple_seq_add_stmt (&seq, shadow_test);
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR,
+						   base_end_addr, 7));
+	  gimple_seq_add_stmt (&seq, build_type_cast (shadow_type,
+						      gimple_seq_last (seq)));
+	  gimple_seq_add_stmt (&seq, build_assign (GE_EXPR,
+						   gimple_seq_last (seq),
+						   shadow));
+	  gimple_seq_add_stmt (&seq, build_assign (BIT_AND_EXPR, shadow_test,
+						   gimple_seq_last (seq)));
+	  if (!start_instrumented)
+	    gimple_seq_add_stmt (&seq, build_assign (BIT_IOR_EXPR, t,
+						     gimple_seq_last (seq)));
+	  t = gimple_assign_lhs (gimple_seq_last (seq));
+	  gimple_seq_set_location (seq, loc);
+	  gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
+	}
+    }
+
+  g = gimple_build_cond (NE_EXPR, t, build_int_cst (TREE_TYPE (t), 0),
+			 NULL_TREE, NULL_TREE);
+  gimple_set_location (g, loc);
+  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+
+  /* Generate call to the run-time library (e.g. __asan_report_load8).  */
+  gsi = gsi_start_bb (then_bb);
+  int nargs;
+  tree fun = report_error_func (is_store, size_in_bytes, &nargs);
+  g = gimple_build_call (fun, nargs, base_addr, len);
+  gimple_set_location (g, loc);
+  gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+
+  gsi_remove (iter, true);
+  *iter = gsi_start_bb (else_bb);
+}
+
 /* Instrument the current function.  */
 
 static unsigned int
@@ -2624,7 +2627,6 @@ asan_instrument (void)
 {
   if (shadow_ptr_types[0] == NULL_TREE)
     asan_init_shadow_ptr_types ();
-  asan_num_accesses = 0;
   transform_statements ();
   return 0;
 }
@@ -2744,10 +2746,35 @@ unsigned int
 pass_sanopt::execute (function *fun)
 {
   basic_block bb;
+  gimple_stmt_iterator gsi;
 
+  int asan_num_accesses = 0;
+  FOR_EACH_BB_FN (bb, fun)
+    for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+      {
+ 	gimple stmt = gsi_stmt (gsi);
+	if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
+	  {
+	    enum internal_fn ifn = gimple_call_internal_fn (stmt);
+	    switch (ifn)
+	      {
+	      case IFN_ASAN_LOAD:
+	      case IFN_ASAN_STORE:
+		{
+		  ++asan_num_accesses;
+		  break;
+		}
+	      default:
+		break;
+	      }
+	    }
+        }
+
+  bool use_calls = ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD < INT_MAX
+    && asan_num_accesses >= ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD;
+    
   FOR_EACH_BB_FN (bb, fun)
     {
-      gimple_stmt_iterator gsi;
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
 	{
 	  gimple stmt = gsi_stmt (gsi);
@@ -2756,17 +2783,27 @@ pass_sanopt::execute (function *fun)
 	    continue;
 
 	  if (gimple_call_internal_p (stmt))
-	    switch (gimple_call_internal_fn (stmt))
-	      {
-	      case IFN_UBSAN_NULL:
-		ubsan_expand_null_ifn (gsi);
-		break;
-	      case IFN_UBSAN_BOUNDS:
-		ubsan_expand_bounds_ifn (&gsi);
-		break;
-	      default:
-		break;
-	      }
+	    {
+	      enum internal_fn ifn = gimple_call_internal_fn (stmt);
+	      switch (ifn)
+		{
+		case IFN_UBSAN_NULL:
+		  ubsan_expand_null_ifn (gsi);
+		  break;
+		case IFN_UBSAN_BOUNDS:
+		  ubsan_expand_bounds_ifn (&gsi);
+		  break;
+		case IFN_ASAN_LOAD:
+		case IFN_ASAN_STORE:
+		  {
+		    bool is_store = ifn == IFN_ASAN_STORE;
+		    asan_expand_check_ifn (&gsi, is_store, use_calls);
+		    break;
+		  }
+		default:
+		  break;
+		}
+	    }
 
 	  if (dump_file && (dump_flags & TDF_DETAILS))
 	    {
@@ -2775,7 +2812,7 @@ pass_sanopt::execute (function *fun)
 	      fprintf (dump_file, "\n");
 	    }
 
-	  /* ubsan_expand_bounds_ifn might move us to the end of the BB.  */
+	  /* Expansions might move us to the end of the BB.  */
 	  if (gsi_end_p (gsi))
 	    break;
 	}
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index b5e8d98..8a755df 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -10312,9 +10312,9 @@ To disable use-after-return detection use
 @option{--param asan-use-after-return=0}.
 
 @item asan-instrumentation-with-call-threshold
-Once number of memory accesses  in function becomes greater
-or equal than this number, use callbacks instead of
-generating inline code.  E.g. to disable inline code use
+If number of memory accesses in function being instrumented
+is greater or equal to this number, use callbacks instead of inline checks.
+E.g. to disable inline code use
 @option{--param asan-instrumentation-with-call-threshold=0}.
 
 @end table
diff --git a/gcc/gimple-iterator.h b/gcc/gimple-iterator.h
index 909d58b..0761bba 100644
--- a/gcc/gimple-iterator.h
+++ b/gcc/gimple-iterator.h
@@ -116,6 +116,7 @@ gsi_start_bb (basic_block bb)
   gimple_seq *seq;
 
   seq = bb_seq_addr (bb);
+  gcc_assert (seq);
   i.ptr = gimple_seq_first (*seq);
   i.seq = seq;
   i.bb = bb;
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 78f59d6..f7935b2 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -167,6 +167,20 @@ expand_UBSAN_BOUNDS (gimple stmt ATTRIBUTE_UNUSED)
   gcc_unreachable ();
 }
 
+/* These should get expanded in the sanopt pass.  */
+
+static void
+expand_ASAN_LOAD (gimple stmt ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+}
+
+static void
+expand_ASAN_STORE (gimple stmt ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+}
+
 /* Add sub/add overflow checking to the statement STMT.
    CODE says whether the operation is +, or -.  */
 
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index f0766bc..cfa7450 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -54,3 +54,5 @@ DEF_INTERNAL_FN (UBSAN_CHECK_SUB, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
 DEF_INTERNAL_FN (UBSAN_CHECK_MUL, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
 DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN)
 DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
+DEF_INTERNAL_FN (ASAN_LOAD, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW)
+DEF_INTERNAL_FN (ASAN_STORE, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW)
diff --git a/gcc/params.def b/gcc/params.def
index aa1e88d..f1c44e0 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -1072,14 +1072,14 @@ DEFPARAM (PARAM_ASAN_MEMINTRIN,
 
 DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN,
          "asan-use-after-return",
-         "Enable asan builtin functions protection",
+         "Enable asan detection of use-after-return bugs",
          1, 0, 1)
 
 DEFPARAM (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
          "asan-instrumentation-with-call-threshold",
-         "Use callbacks instead of inline code once number of accesses "
-         " in function becomes greater or equal than this threshold",
-         10000, 0, INT_MAX)
+         "Use callbacks instead of inline code if number of accesses "
+         "in function becomes greater or equal to this number",
+         7000, 0, INT_MAX)
 
 DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS,
 	  "uninit-control-dep-attempts",
diff --git a/gcc/testsuite/c-c++-common/asan/inc.c b/gcc/testsuite/c-c++-common/asan/inc.c
index b9c6734..865d50a 100644
--- a/gcc/testsuite/c-c++-common/asan/inc.c
+++ b/gcc/testsuite/c-c++-common/asan/inc.c
@@ -16,6 +16,6 @@ main ()
   return 0;
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 1 "asan0" } }  */
-/* { dg-final { scan-tree-dump "__builtin___asan_report_load4" "asan0" } }  */
+/* { dg-final { scan-tree-dump-times "ASAN_" 1 "asan0" } }  */
+/* { dg-final { scan-tree-dump "ASAN_LOAD \\(.*, 4\\);" "asan0" } }  */
 /* { dg-final { cleanup-tree-dump "asan0" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c
index 570f796..04fdad0 100644
--- a/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c
+++ b/gcc/testsuite/c-c++-common/asan/instrument-with-calls-2.c
@@ -9,8 +9,8 @@ void f(int *a, int *b) {
   x = *b;
 }
 
-/* { dg-final { scan-assembler-not "__asan_store4" } } */
-/* { dg-final { scan-assembler "__asan_report_store4" } } */
+/* { dg-final { scan-assembler "__asan_store4" } } */
+/* { dg-final { scan-assembler-not "__asan_report_store4" } } */
 /* { dg-final { scan-assembler "__asan_load4" } } */
 /* { dg-final { scan-assembler-not "__asan_report_load4" } } */
 /* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
index c7c594e..028f8d7 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c
@@ -2,7 +2,7 @@
    location in the same basic block, the second reference should not
    be instrumented by the Address Sanitizer.  */
 
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -62,7 +62,7 @@ main ()
   return test0 () && test1 (0);
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 3 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 1 "asan0" }  } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 3 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 1 "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c
index 143312f..a58411c 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-2.c
@@ -3,7 +3,7 @@
    be instrumented by the Address Sanitizer.  But in case of access to
    overlapping regions we must be precise.  */
 
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -20,7 +20,7 @@ main ()
   __builtin_memset (tab, 1, 3);
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 3 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "asan0" }  } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 3 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-3.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-3.c
index 420a263..5193ae0 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-3.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-3.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -12,7 +12,7 @@ foo (__INT32_TYPE__ *p)
   return ret; 
 }
 
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store" 1 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store" 1 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
index da91cd5..c3632aa 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-4.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -10,8 +10,8 @@ foo  (int *a, char *b, char *c)
   /* For a total of 5 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 5 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
index 134be66..077ea34 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-5.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -10,9 +10,9 @@ foo  (int *a, char *b, char *c)
   /* For a total of 5 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 5 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
index 55c8ee3..6d87104 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-6.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -12,9 +12,9 @@ foo  (int *a, char *b, char *c)
   /* For a total of 8 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 8 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 2 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 2 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 8 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 2 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 2 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
index a04956d..5baa10d 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-7.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -21,7 +21,7 @@ foo  (int *a, char *b, char *c)
   return d;
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 6 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 4 "asan0" } } */
-/* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 6 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 4 "sanopt" } } */
+/* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
index 308a133..2a4c081 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-8.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -12,9 +12,9 @@ foo  (int *a, char *b, char *c)
   /* For a total of 5 checks.  */
 }
 
-/* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
-/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "& 7" 5 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "sanopt" } } */
+/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */
diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c
index c6575ad..9449de5 100644
--- a/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c
+++ b/gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-9.c
@@ -1,4 +1,4 @@
-/* { dg-options "-fdump-tree-asan0" } */
+/* { dg-options "-fdump-tree-sanopt" } */
 /* { dg-do compile } */
 /* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
 
@@ -9,5 +9,5 @@ f (char *a)
   return  __builtin_strlen (a);
 }
 
-/* { dg-final { scan-tree-dump-times "__asan_report_load1" 1 "asan0" } } */
-/* { dg-final { cleanup-tree-dump "asan0" } } */
+/* { dg-final { scan-tree-dump-times "__asan_report_load1" 1 "sanopt" } } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */

^ permalink raw reply	[flat|nested] 23+ messages in thread
* Re: [PATCH] Move Asan instrumentation to sanopt pass
@ 2014-07-18 17:28 Yuri Gribov
       [not found] ` <20140718172323.GL3003@laptop.redhat.com>
  0 siblings, 1 reply; 23+ messages in thread
From: Yuri Gribov @ 2014-07-18 17:28 UTC (permalink / raw)
  To: Jakub Jelinek
  Cc: GCC Patches, Konstantin Serebryany, Dmitry Vyukov,
	Viacheslav Garbuzov, Marek Polacek

> For formatting, can you please just replace 8 spaces with tabs
> in the ^+ lines in the patch?

Sorry, I thought I cleared all these out but looks like I indeed
missed some whites. I should probably take some time and finally setup
my editor to do this.

> Can you avoid using // comments in code that uses /* */ comments?

Thanks, this TODO should have been included in the patch to begin with.

> If all the ifns have a bitmask argument, one question is if we really
> want ASAN_LOAD vs. ASAN_STORE, instead of a single ASAN_CHECK that
> would actually have ASAN_CHECK_IS_STORE as one of the flags.

True.

>> +  gcc_assert (seq);
>
> Uh.  Can you please explain this?  That sounds weird.

Sure, this caused maybe-uninitialized warnings with iterator during
bootstrap. It turned out that *bb_seq_addr (bb) in gsi_start (bb)
returned something like bb.flags & GIMPLE ? bb.il.gimple.seq : NULL
and when GCC saw *NULL it rushed to generated uninitialized read. This
assert silences compiler.

-Y

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2014-08-11  6:13 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-18 13:39 [PATCH] Move Asan instrumentation to sanopt pass Yury Gribov
2014-07-18 15:38 ` Jakub Jelinek
2014-07-22  9:03   ` Yury Gribov
2014-07-23 14:42     ` Yury Gribov
2014-07-22 14:06 ` Richard Biener
2014-07-22 14:20   ` Yury Gribov
2014-07-22 14:48     ` Richard Biener
2014-07-23 20:33       ` Jakub Jelinek
2014-07-24  6:35         ` Yury Gribov
2014-07-24  8:28           ` Jakub Jelinek
2014-07-28 14:26             ` Yury Gribov
2014-08-01  7:18               ` Jakub Jelinek
2014-08-01  9:07                 ` Richard Biener
2014-08-08  6:11                   ` [PATCH 1/2] Support fnspecs for internal functions Yury Gribov
2014-08-08  8:07                     ` Jakub Jelinek
2014-08-11  6:13                       ` Yury Gribov
2014-08-08  6:11                 ` [PATCH 2/2] Move Asan instrumentation to sanopt pass Yury Gribov
2014-08-08  8:09                   ` Jakub Jelinek
2014-08-11  6:12                     ` Yury Gribov
2014-07-18 17:28 [PATCH] " Yuri Gribov
     [not found] ` <20140718172323.GL3003@laptop.redhat.com>
2014-07-18 18:55   ` Yuri Gribov
2014-07-19  9:34     ` Jakub Jelinek
2014-07-19 19:33       ` Yuri Gribov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).