tree-dse: Fix mem* head trimming if call has lhs [PR94130]
authorJakub Jelinek <jakub@redhat.com>
Thu, 12 Mar 2020 08:34:00 +0000 (09:34 +0100)
committerJakub Jelinek <jakub@redhat.com>
Thu, 12 Mar 2020 08:34:00 +0000 (09:34 +0100)
As the testcase shows, if DSE decides to head trim {mem{set,cpy,move},strncpy}
and the call has lhs, it is incorrect to leave the lhs as is, because it
will then point to the adjusted address (base + head_trim) instead of the
original base.
The following patch fixes that by dropping the lhs of the call and assigning
lhs the original base in a following statement.

2020-03-12  Jakub Jelinek  <jakub@redhat.com>

PR tree-optimization/94130
* tree-ssa-dse.c: Include gimplify.h.
(increment_start_addr): If stmt has lhs, drop the lhs from call and
set it after the call to the original value of the first argument.
Formatting fixes.
(decrement_count): Formatting fix.

* gcc.c-torture/execute/pr94130.c: New test.

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr94130.c [new file with mode: 0644]
gcc/tree-ssa-dse.c

index dfc9b8e7c33bdf092eaabdb742fdee432eb2d225..d6a75081f24c0c63f26d4bcb7acb2a0cb0dc921f 100644 (file)
@@ -1,3 +1,12 @@
+2020-03-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/94130
+       * tree-ssa-dse.c: Include gimplify.h.
+       (increment_start_addr): If stmt has lhs, drop the lhs from call and
+       set it after the call to the original value of the first argument.
+       Formatting fixes.
+       (decrement_count): Formatting fix.
+
 2020-03-11  Delia Burduv  <delia.burduv@arm.com>
 
        * config/arm/arm-builtins.c
index 18427eb1808d8a186658e90aff7bbe5c1a424817..5e232c691d5186c44fb3357c320d79764eb5a5e3 100644 (file)
@@ -1,5 +1,8 @@
 2020-03-12  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/94130
+       * gcc.c-torture/execute/pr94130.c: New test.
+
        PR c++/93907
        * g++.dg/cpp2a/concepts-using2.C (cc): Use long long instead of
        __int128 if __SIZEOF_INT128__ isn't defined.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94130.c b/gcc/testsuite/gcc.c-torture/execute/pr94130.c
new file mode 100644 (file)
index 0000000..044e578
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR tree-optimization/94130 */
+
+int
+main ()
+{
+  int a[8];
+  char *b = __builtin_memset (a, 0, sizeof (a));
+  a[0] = 1;
+  a[1] = 2;
+  a[2] = 3;
+  if (b != (char *) a)
+    __builtin_abort ();
+  else
+    asm volatile ("" : : "g" (a) : "memory");
+  return 0;
+}
index f2a4ed97a361bf9771324e9276bd4edb365e7a59..3ab15e2107ad318864c3afe275e54562d67e9aab 100644 (file)
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-dse.h"
 #include "builtins.h"
 #include "gimple-fold.h"
+#include "gimplify.h"
 
 /* This file implements dead store elimination.
 
@@ -422,29 +423,38 @@ decrement_count (gimple *stmt, int decrement)
   gcc_assert (TREE_CODE (*countp) == INTEGER_CST);
   *countp = wide_int_to_tree (TREE_TYPE (*countp), (TREE_INT_CST_LOW (*countp)
                                                    - decrement));
-
 }
 
 static void
 increment_start_addr (gimple *stmt, tree *where, int increment)
 {
+  if (tree lhs = gimple_call_lhs (stmt))
+    if (where == gimple_call_arg_ptr (stmt, 0))
+      {
+       gassign *newop = gimple_build_assign (lhs, unshare_expr (*where));
+       gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+       gsi_insert_after (&gsi, newop, GSI_SAME_STMT);
+       gimple_call_set_lhs (stmt, NULL_TREE);
+       update_stmt (stmt);
+      }
+
   if (TREE_CODE (*where) == SSA_NAME)
     {
       tree tem = make_ssa_name (TREE_TYPE (*where));
       gassign *newop
-        = gimple_build_assign (tem, POINTER_PLUS_EXPR, *where,
+       = gimple_build_assign (tem, POINTER_PLUS_EXPR, *where,
                               build_int_cst (sizetype, increment));
       gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
       gsi_insert_before (&gsi, newop, GSI_SAME_STMT);
       *where = tem;
-      update_stmt (gsi_stmt (gsi));
+      update_stmt (stmt);
       return;
     }
 
   *where = build_fold_addr_expr (fold_build2 (MEM_REF, char_type_node,
-                                             *where,
-                                             build_int_cst (ptr_type_node,
-                                                            increment)));
+                                             *where,
+                                             build_int_cst (ptr_type_node,
+                                                            increment)));
 }
 
 /* STMT is builtin call that writes bytes in bitmap ORIG, some bytes are dead