[regehr@dyson r44]$ current-gcc -c -O2 small.c small.c: In function 'fn3': small.c:7:1: internal compiler error: in find_or_generate_expression, at tree-ssa-pre.c:3053 fn3 () ^ Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. [regehr@dyson r44]$ cat small.c int a, b, c; unsigned *d; int e[1]; void fn1 (); int fn2 (); int fn3 () { int *f = &a; if (fn2 ()) { for (; c; c++) { e[a] && (b = 0); fn1 (); if (e[a]) return 0; } for (; c <= 0; c++) for (;;) ; } else e[0] = 0 != (d = f); return *d; } [regehr@dyson r44]$ current-gcc -v Using built-in specs. COLLECT_GCC=current-gcc COLLECT_LTO_WRAPPER=/uusoc/exports/scratch/regehr/z/compiler-install/gcc-r186954-install/bin/../libexec/gcc/x86_64-unknown-linux-gnu/4.8.0/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: ../configure --with-libelf=/usr/local --enable-lto --prefix=/home/regehr/z/compiler-install/gcc-r186954-install --program-prefix=r186954- --enable-languages=c,c++ Thread model: posix gcc version 4.8.0 20120430 (experimental) (GCC)
Started failing with http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=185691
Mine.
It's what I always wondered about ... we phi-translate again during do_regular_insertion but we fail to "clean" the result in any way. So we end with a translation result that is "invalid", thus one without a leader and one which we cannot re-create. That is, valid_in_sets returns false for it. Index: gcc/tree-ssa-pre.c =================================================================== --- gcc/tree-ssa-pre.c (revision 187042) +++ gcc/tree-ssa-pre.c (working copy) @@ -3617,6 +3619,11 @@ do_regular_insertion (basic_block block, vprime, NULL); if (edoubleprime == NULL) { + if (!valid_in_sets (AVAIL_OUT (bprime), NULL, eprime, bprime)) + { + cant_insert = true; + break; + } avail[bprime->index] = eprime; all_same = false; } Steven - do you by chance remember why "re-translating" during insertion is ok? Or is a phi-translation result that cannot be inserted in its form at the end of the BB bogus (always? or only during insertion?).
I don't remember. Did you look at the paper/thesis to see if it says anything about this?
I think it is because of how we do VN lookup / insert during phi_translation. SCCVN does not guarantee availability of its lookup result, thus when such availability is not guaranteed when we translate things we should rather use the non-canonical expression (after all we translate expressions (sic!), not values). What happens is that we have (simplified) if (b) { x_1 = a; } else { if (c) for(;;) { x_2 = a; a = 0; } } and SCCVN value-numbers x_2 to x_1. PRE sees that 'a' is ANTIC_IN in the for (;;) block - but it's not ANTIC_OUT in the if (c) block because it gets cleaned out there as it is translated as x_1 which is not insertable. I think the PRE algorithm does not expect that phi_translate (ANTIC_IN (succ)) will ever return something that is _not_ valid at the ANTIC_OUT position. But our phi-translate implementation happily causes this situation. My suggested change to check validity of the phi_translate result at insert time is a workaround, but it only makes this a missed optimization. This particular case is fixed by not turning the memory reference into a conversion on translation.
Author: rguenth Date: Fri May 4 11:30:35 2012 New Revision: 187153 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=187153 Log: 2012-05-04 Richard Guenther <rguenther@suse.de> PR tree-optimization/53168 * tree-ssa-pre.c (phi_translate_1): Only handle type-punned memory reads when the result is a constant we can pun. * gcc.dg/torture/pr53168.c: New testcase. * gcc.dg/tree-ssa/ssa-pre-30.c: Likewise. Added: trunk/gcc/testsuite/gcc.dg/torture/pr53168.c trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-ssa-pre.c
Fixed.