re PR tree-optimization/83047 (glibc/crypt/crypt_util.c gets miscompiled)
authorJakub Jelinek <jakub@redhat.com>
Tue, 21 Nov 2017 08:41:47 +0000 (09:41 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 21 Nov 2017 08:41:47 +0000 (09:41 +0100)
PR tree-optimization/83047
* gimple-ssa-store-merging.c
(imm_store_chain_info::output_merged_store): If the loads with the
same vuse are in different basic blocks, for load_gsi pick a load
location that is dominated by the other loads.

* gcc.dg/pr83047.c: New test.

From-SVN: r254992

gcc/ChangeLog
gcc/gimple-ssa-store-merging.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr83047.c [new file with mode: 0644]

index a7bbd9c0a99bcc8358c0b725857d106dacb22a8d..a106fe60dcbcf09a0c267021e83f4516009d5662 100644 (file)
@@ -1,5 +1,11 @@
 2017-11-21  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/83047
+       * gimple-ssa-store-merging.c
+       (imm_store_chain_info::output_merged_store): If the loads with the
+       same vuse are in different basic blocks, for load_gsi pick a load
+       location that is dominated by the other loads.
+
        PR c++/83059
        * config/i386/i386.c (ix86_memmodel_check): Start
        -Winvalid-memory-model diagnostics with lowercase letter.
index ac8d9eec2b60d8c8f46aa2bf4f7421578e35d154..c0b1015d9f52b1f6798c71f09df5e9b277bf5d7b 100644 (file)
@@ -3372,7 +3372,30 @@ imm_store_chain_info::output_merged_store (merged_store_group *group)
       store_immediate_info *infol = group->stores.last ();
       if (gimple_vuse (op.stmt) == gimple_vuse (infol->ops[j].stmt))
        {
-         load_gsi[j] = gsi_for_stmt (op.stmt);
+         /* We can't pick the location randomly; while we've verified
+            all the loads have the same vuse, they can be still in different
+            basic blocks and we need to pick the one from the last bb:
+            int x = q[0];
+            if (x == N) return;
+            int y = q[1];
+            p[0] = x;
+            p[1] = y;
+            otherwise if we put the wider load at the q[0] load, we might
+            segfault if q[1] is not mapped.  */
+         basic_block bb = gimple_bb (op.stmt);
+         gimple *ostmt = op.stmt;
+         store_immediate_info *info;
+         FOR_EACH_VEC_ELT (group->stores, i, info)
+           {
+             gimple *tstmt = info->ops[j].stmt;
+             basic_block tbb = gimple_bb (tstmt);
+             if (dominated_by_p (CDI_DOMINATORS, tbb, bb))
+               {
+                 ostmt = tstmt;
+                 bb = tbb;
+               }
+           }
+         load_gsi[j] = gsi_for_stmt (ostmt);
          load_addr[j]
            = force_gimple_operand_1 (unshare_expr (op.base_addr),
                                      &load_seq[j], is_gimple_mem_ref_addr,
index 3901db4b4b891edd37d5b60caf82da5485cc4161..70926dc1e2eaa7c09fcca5d684256b6d8a88dd9a 100644 (file)
@@ -1,5 +1,8 @@
 2017-11-21  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/83047
+       * gcc.dg/pr83047.c: New test.
+
        P0428R2 - familiar template syntax for generic lambdas
        * g++.dg/cpp1y/lambda-generic-x.C: Adjust warnings and limit
        to c++17_down target.
diff --git a/gcc/testsuite/gcc.dg/pr83047.c b/gcc/testsuite/gcc.dg/pr83047.c
new file mode 100644 (file)
index 0000000..db374a9
--- /dev/null
@@ -0,0 +1,58 @@
+/* PR tree-optimization/83047 */
+/* { dg-do run { target mmap } } */
+/* { dg-options "-O2" } */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+#ifndef MAP_ANON
+#define MAP_ANON 0
+#endif
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+#include <stdlib.h>
+
+__attribute__((noipa)) void
+foo (char *p, char *q, int r)
+{
+  char a = q[0];
+  if (r || a == '\0')
+    return;
+  char b = q[1];
+  p[0] = a;
+  p[1] = b;
+}
+
+int
+main ()
+{
+  char *p = mmap (NULL, 131072, PROT_READ | PROT_WRITE,
+                 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+  if (p == MAP_FAILED)
+    return 0;
+  if (munmap (p + 65536, 65536) < 0)
+    return 0;
+  p[0] = 'c';
+  p[1] = 'd';
+  p[65536 - 2] = 'a';
+  p[65536 - 1] = 'b';
+  volatile int r = 1;
+  foo (p, p + 65536 - 2, r);
+  if (p[0] != 'c' || p[1] != 'd')
+    abort ();
+  r = 0;
+  foo (p, p + 65536 - 2, r);
+  if (p[0] != 'a' || p[1] != 'b')
+    abort ();
+  p[0] = 'e';
+  p[1] = 'f';
+  r = 1;
+  foo (p, p + 65536 - 1, r);
+  if (p[0] != 'e' || p[1] != 'f')
+    abort ();
+  return 0;
+}