It appears to be a recent regression from 12.2. Compiler Explorer: https://godbolt.org/z/4T3xMvsab [578] % gcctk -v Using built-in specs. COLLECT_GCC=gcctk COLLECT_LTO_WRAPPER=/local/suz-local/software/local/gcc-trunk/libexec/gcc/x86_64-pc-linux-gnu/13.0.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc-trunk/configure --disable-bootstrap --enable-checking=yes --prefix=/local/suz-local/software/local/gcc-trunk --enable-sanitizers --enable-languages=c,c++ --disable-werror --disable-multilib Thread model: posix Supported LTO compression algorithms: zlib gcc version 13.0.1 20230127 (experimental) [master r12-4647-g3f861a5c8fd] (GCC) [579] % [579] % gcctk -O3 small.c [580] % ./a.out Floating point exception [581] % [581] % cat small.c int a = 1, b, c = 2, d; int main() { if (b) goto L2; L1: { int e = c; a = 1 % a; while (e && 1 <= d) ; d >= b; L2: if (1 >= e) goto L1; } return 0; }
Here is another reproducer likely for the same bug. Compiler Explorer: https://godbolt.org/z/Efvczc6f8 [556] % gcctk -O3 small.c [557] % ./a.out Floating point exception [558] % [558] % cat small.c int a, b, c, d, e, f, g = -1, h; void l() { if (!e) goto i; for (; g; g++) { b = ~d; int j = 0, k = 1; if (k && (b || f)) j = b; i: a = ~j; } } int main() { h = 3; for (; h; h--) { e = 1; int m = ~a, n = 1 % m; c = n; l(); } return 0; }
Another likely related test case. Compiler Explorer: https://godbolt.org/z/G514hnMeY [537] % gcctk -O3 small.c [538] % timeout -s 9 5 ./a.out Killed [539] % gcctk -O1 small.c [540] % ./a.out [541] % [541] % cat small.c int a = 3557301289, d; char b, f; unsigned short c = 241; short e, g; static void h() { if (!a) goto i; b = a; for (; a < 2; a = b) { unsigned short j; if (c || !g) { j = c; i: e = j; } f = j; d = ~(f & ~2880764155); while (d > -2316069) ; } } int main() { h(); return 0; }
(In reply to Zhendong Su from comment #0) > It appears to be a recent regression from 12.2. In the testcase from comment #0, pre is messing it up because of an uninitialized variable on one path (which is not taken). Note somehow the statement: d >= b; changes the IR slightly ... testcase in comment #1 also depends on an uninitialized variable on a path not taken too (in that case j). testcase in comment #2 also looks similar and depends on an unintialized variable on a path not taken too.
Likely caused by r13-5348-gc29d85359add80 We do marking outgoing edge 12 -> 6 executable Looking for changed values of backedge 12->6 destination PHIs Predication says 0 and e_10 are equal on edge 11 -> 6 Setting value number of e_5 to 0 I will have a more detailed look.
*** Bug 108584 has been marked as a duplicate of this bug. ***
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:7ac3e69e311351b70407d7f87a0169c4d463e57b commit r13-5492-g7ac3e69e311351b70407d7f87a0169c4d463e57b Author: Richard Biener <rguenther@suse.de> Date: Mon Jan 30 09:25:23 2023 +0100 tree-optimization/108574 - wrong-code with PRE PHI node processing The PR108523 was too optimistic in replacing the same value with an equivalence from a possibly not taken edge. The following rectifies this and instead refrains from using the equivalence in the problematic cases. PR tree-optimization/108574 * tree-ssa-sccvn.cc (visit_phi): Instead of swapping sameval and def, ignore the equivalence if there's the danger of oscillating between two values. * gcc.dg/torture/pr108574-1.c: New testcase. * gcc.dg/torture/pr108574-2.c: Likewise. * gcc.dg/torture/pr108574-3.c: Likewise.
Fixed.