Created attachment 47010 [details] Preprocessed source The commit r276645 | rguenth | 2019-10-07 07:53:45 +0000 (Mon, 07 Oct 2019) | 20 lines 2019-10-07 Richard Biener <rguenther@suse.de> PR tree-optimization/91975 * tree-ssa-loop-ivcanon.c (constant_after_peeling): Consistently handle invariants. introduced spurious -Warray-bounds warnings that break the glibc build for certain 32-bit configurations (i686 and 32-bit powerpc and s390). I've attached a testcase; compile with -m32 -O2 -Wall with an x86_64 compiler and you get: In file included from ../sysdeps/ieee754/float128/strtof128_l.c:48, from ../sysdeps/ieee754/float128/wcstof128_l.c:27: ../stdlib/strtod_l.c: In function '____wcstof128_l_internal': ../stdlib/strtod_l.c:1676:22: warning: array subscript -1 is below array bounds of 'mp_limb_t[4]' {aka 'long unsigned int[4]'} [-Warray-bounds] In file included from ../sysdeps/ieee754/float128/strtof128_l.c:48, from ../sysdeps/ieee754/float128/wcstof128_l.c:27: ../stdlib/strtod_l.c:523:13: note: while referencing 'retval' (Note the glibc build has been broken for other reasons lately; this issue was bisected to that commit using the attached .i file rather than based on when the glibc build worked or didn't work.) The relevant code is: # 1675 "../stdlib/strtod_l.c" for (i = (((113) + ((32) - 1)) / (32)) - 1; i >= empty; --i) retval[i] = retval[i - empty]; from which it should be clear that, as i >= empty, this warning is bogus. (i is int and empty is mp_size_t which is long int.)
My tester tripped this as well. Confirming.
The rev in question changed heuristics as to when unrolling is applied so the issue is latent (and probably has a duplicate).
_1235 = numsize.165_444 - densize_607; _1236 = retval[_1235]; we compute _1235 to be in [-4,-1]. Directly after unrolling it was [../stdlib/strtod_l.c:1675:9] if (empty_1004 <= i_1232) goto <bb 499>; [80.00%] <bb 499> [local count: 284953]: [../stdlib/strtod_l.c:1676:25] _1235 = i_1232 - empty_1004; [../stdlib/strtod_l.c:1676:22] _1236 = [../stdlib/strtod_l.c:1676:22] retval[_1235]; and forwprop "mangles" it to the above because empty_1004 = densize_425 - numsize.165_444; and i_1232 is zero here. That means the last unrolled iteration isn't reachable. Note we do complete peeling here (keeping the exit checks). I had the impression I disabled this for early unrolling... hmm, I kept it for UL_NO_GROWTH, see PR83202.
Just for the record a reduced test-case: int a[3]; void fn1(long b) { int i; for (i = 3; i >= b; --i) a[i] = a[i - b]; } where does not need -m32: $ gcc -Werror=array-bounds -O2 -c ice.i ice.i: In function ‘fn1’: ice.i:6:6: error: array subscript 3 is above array bounds of ‘int[3]’ [-Werror=array-bounds] 6 | a[i] = a[i - b]; | ~^~~ ice.i:1:5: note: while referencing ‘a’ 1 | int a[3]; | ^ cc1: some warnings being treated as errors $ gcc-9 -Werror=array-bounds -O2 -c ice.i
On Wed, 23 Oct 2019, marxin at gcc dot gnu.org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92039 > > Martin Liška <marxin at gcc dot gnu.org> changed: > > What |Removed |Added > ---------------------------------------------------------------------------- > Keywords|needs-reduction | > CC| |marxin at gcc dot gnu.org > > --- Comment #4 from Martin Liška <marxin at gcc dot gnu.org> --- > Just for the record a reduced test-case: > > int a[3]; > > void fn1(long b) { > int i; > for (i = 3; i >= b; --i) > a[i] = a[i - b]; > } > > where does not need -m32: > > $ gcc -Werror=array-bounds -O2 -c ice.i > ice.i: In function ‘fn1’: > ice.i:6:6: error: array subscript 3 is above array bounds of ‘int[3]’ > [-Werror=array-bounds] > 6 | a[i] = a[i - b]; > | ~^~~ > ice.i:1:5: note: while referencing ‘a’ > 1 | int a[3]; > | ^ > cc1: some warnings being treated as errors > > $ gcc-9 -Werror=array-bounds -O2 -c ice.i The testcase is probably misreduced since the very first iteration will write to a[3] out of bounds so it only is valid if the loop is not entered, thus if b < 3.
*** Bug 92337 has been marked as a duplicate of this bug. ***
Fixed.
Author: rguenth Date: Fri Nov 15 09:09:16 2019 New Revision: 278281 URL: https://gcc.gnu.org/viewcvs?rev=278281&root=gcc&view=rev Log: 2019-11-15 Richard Biener <rguenther@suse.de> PR tree-optimization/92039 PR tree-optimization/91975 * tree-ssa-loop-ivcanon.c (constant_after_peeling): Revert previous change, treat invariants consistently as non-constant. (tree_estimate_loop_size): Ternary ops with just the first op constant are not optimized away. * gcc.dg/tree-ssa/cunroll-2.c: Revert to state previous to unroller adjustment. * g++.dg/tree-ssa/ivopts-3.C: Likewise. Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/testsuite/g++.dg/tree-ssa/ivopts-3.C trunk/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c trunk/gcc/tree-ssa-loop-ivcanon.c