Hi all. It seems to be a recent regression issue. $cat small.c #include <stdio.h> #include <stdint.h> int32_t a[6]; int64_t b; int32_t *c; int32_t **d = &c; int64_t *e = &b; int32_t **const *f = &d; int32_t **const **g = &f; int32_t *h(); static int16_t j(); static uint32_t k(int8_t, const int32_t *, int64_t); static uint32_t l() { int32_t *m = &a[3]; int32_t n = 0; int8_t o = 0; int32_t *p[] = {&n, &n, &n, &n}; uint32_t q[6][1][2] = {}; for (o = 0; o <= 1; o = 6) if (h(j(k(3, 0, q[2][0][0]), &n), n) == p[3]) *m = *e; return 0; } int32_t *h(uint32_t, int32_t) { return ***g; } int16_t j(uint32_t, int32_t *r) { **f = r; } uint32_t k(int8_t, const int32_t *, int64_t) { *e = 3; return 0;} int main() { int i = 0; l(); for (i = 0; i < 6; i++){ if (i == 3) printf("%d\n", a[i]); } return 0; } $gcc -O1 small.c ; ./a.out 0 $gcc -O0 small.c ; ./a.out 3 $gcc -O2 small.c ; ./a.out 3 $gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/home/haoxin/haoxin-data/compilers/gcc/build/libexec/gcc/x86_64-pc-linux-gnu/12.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with:../configure --prefix=/home/haoxin/haoxin-data/compilers/gcc/build/ --enable-bootstrap --enable-checking=release --enable-languages=c,c++ --enable-multilib : (reconfigured) ../configure --prefix=/home/haoxin/haoxin-data/compilers/gcc/build/ --enable-bootstrap --enable-checking=release --enable-multilib --enable-languages=c,c++,lto --no-create --no-recursion Thread model: posix Supported LTO compression algorithms: zlib gcc version 12.0.0 20211112 (experimental) (GCC) Thanks, Haoxin
Started with r12-4324-g008e7397dad971c0.
mine.
This is bug I introduced to tree-ssa-structalias where I reversed order of flags which deterine global memory read and writes. So pure functions are handled as functions writting global memory but not reading it. I am very surprised it took so long to show as wrong code. diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 153ddf57a61..34fd47fdf47 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -4996,7 +4996,7 @@ find_func_aliases_for_call (struct function *fn, gcall *t) reachable from their arguments, but they are not an escape point for reachable memory of their arguments. */ else if (flags & (ECF_PURE|ECF_LOOPING_CONST_OR_PURE)) - handle_rhs_call (t, &rhsc, implicit_pure_eaf_flags, true, false); + handle_rhs_call (t, &rhsc, implicit_pure_eaf_flags, false, true); /* If the call is to a replaceable operator delete and results from a delete expression as opposed to a direct call to such operator, then the effects for PTA (in particular
Wow, what a bug :P
The master branch has been updated by Jan Hubicka <hubicka@gcc.gnu.org>: https://gcc.gnu.org/g:4d2d5565a0953eaa829d10006baf007cf33bab89 commit r12-5217-g4d2d5565a0953eaa829d10006baf007cf33bab89 Author: Jan Hubicka <jh@suse.cz> Date: Fri Nov 12 23:55:50 2021 +0100 Fix wrong code with pure functions I introduced bug into find_func_aliases_for_call in handling pure functions. Instead of reading global memory pure functions are believed to write global memory. This results in misoptimization of the testcase at -O1. The change to pta-callused.c updates the template for new behaviour of the constraint generation. We copy nonlocal memory to calluse which is correct but also not strictly necessary because later we take care to add nonlocal_p flag manually. gcc/ChangeLog: PR tree-optimization/103209 * tree-ssa-structalias.c (find_func_aliases_for_call): Fix use of handle_rhs_call gcc/testsuite/ChangeLog: PR tree-optimization/103209 * gcc.dg/tree-ssa/pta-callused.c: Update template. * gcc.c-torture/execute/pr103209.c: New test.
Fixed.