From 97031af75528283f0b6fc554acdbb692431ccfb1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 21 Nov 2017 09:41:47 +0100 Subject: [PATCH] re PR tree-optimization/83047 (glibc/crypt/crypt_util.c gets miscompiled) 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 | 6 ++++ gcc/gimple-ssa-store-merging.c | 25 ++++++++++++++- gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/gcc.dg/pr83047.c | 58 ++++++++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/pr83047.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a7bbd9c0a99..a106fe60dcb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2017-11-21 Jakub Jelinek + 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. diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c index ac8d9eec2b6..c0b1015d9f5 100644 --- a/gcc/gimple-ssa-store-merging.c +++ b/gcc/gimple-ssa-store-merging.c @@ -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, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3901db4b4b8..70926dc1e2e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2017-11-21 Jakub Jelinek + 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 index 00000000000..db374a9d251 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr83047.c @@ -0,0 +1,58 @@ +/* PR tree-optimization/83047 */ +/* { dg-do run { target mmap } } */ +/* { dg-options "-O2" } */ + +#include +#include +#include +#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 + +__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; +} -- 2.30.2