Bug 92039 - [10 Regression] Spurious -Warray-bounds warnings building 32-bit glibc
Summary: [10 Regression] Spurious -Warray-bounds warnings building 32-bit glibc
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: 10.0
Assignee: Richard Biener
URL:
Keywords: diagnostic
: 92337 (view as bug list)
Depends on:
Blocks: Warray-bounds
  Show dependency treegraph
 
Reported: 2019-10-09 20:38 UTC by Joseph S. Myers
Modified: 2019-11-15 09:09 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-10-09 00:00:00


Attachments
Preprocessed source (66.03 KB, text/plain)
2019-10-09 20:38 UTC, Joseph S. Myers
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Joseph S. Myers 2019-10-09 20:38:00 UTC
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.)
Comment 1 Jeffrey A. Law 2019-10-09 21:10:05 UTC
My tester tripped this as well.  Confirming.
Comment 2 Richard Biener 2019-10-10 06:03:49 UTC
The rev in question changed heuristics as to when unrolling is applied so the issue is latent (and probably has a duplicate).
Comment 3 Richard Biener 2019-10-10 06:45:04 UTC
_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.
Comment 4 Martin Liška 2019-10-23 11:24:05 UTC
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
Comment 5 rguenther@suse.de 2019-10-23 11:43:40 UTC
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.
Comment 6 Florian Weimer 2019-11-03 16:14:58 UTC
*** Bug 92337 has been marked as a duplicate of this bug. ***
Comment 7 Richard Biener 2019-11-15 09:09:23 UTC
Fixed.
Comment 8 Richard Biener 2019-11-15 09:09:48 UTC
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