public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug tree-optimization/59932] New: spurious undefined behavior warning on valid code
@ 2014-01-24  3:09 su at cs dot ucdavis.edu
  2014-01-24  3:20 ` [Bug tree-optimization/59932] " su at cs dot ucdavis.edu
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: su at cs dot ucdavis.edu @ 2014-01-24  3:09 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59932

            Bug ID: 59932
           Summary: spurious undefined behavior warning on valid code
           Product: gcc
           Version: 4.9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: su at cs dot ucdavis.edu

The current gcc trunk issues a spurious undefined behavior warning when
compiling the following valid code at -Os and above in both 32-bit and 64-bit
mode. 

It does not affect gcc 4.8 though, so it is a regression from 4.8.x. 

Interestingly, the code also causes clang (from 3.2 to its current trunk) to
hang at -Os and above. 


$ gcc-trunk -v
Using built-in specs.
COLLECT_GCC=gcc-trunk
COLLECT_LTO_WRAPPER=/usr/local/gcc-trunk/libexec/gcc/x86_64-unknown-linux-gnu/4.9.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-trunk/configure --prefix=/usr/local/gcc-trunk
--enable-languages=c,c++ --disable-werror --enable-multilib
Thread model: posix
gcc version 4.9.0 20140123 (experimental) [trunk revision 206958] (GCC) 
$ 
$ gcc-trunk -O1 small.c; a.out
$ gcc-4.8.2 -Os small.c; a.out
$ 
$ gcc-trunk -Os small.c
small.c: In function ‘main’:
small.c:27:16: warning: iteration 2147483646u invokes undefined behavior
[-Waggressive-loop-optimizations]
   for (; p1; p1++)
                ^
small.c:27:3: note: containing loop
   for (; p1; p1++)
   ^
$ 
$ timeout -s 9 30 clang-trunk -Os small.c
Killed
$ 
$ 


---------------------------------------


int a, b, c, e[1], f, g, h, i, k, m, n;
short j;

struct
{
  short f1;
} d;

static int
fn1 (int p1)
{
  int l = 64696;
  for (f = 0; f != 1; f--)
    {
      if (d.f1 > l)
    {
      h = p1;
      if (!h)
        l = 0;
    }
      else
    return b;
      for (; a; a++)
    if (e[a])
      break;
    }
  for (; p1; p1++)
    {
      if (h)
    continue;
      if (l)
    i = j = k = g && d.f1 != p1;
      for (; h != 1; h++)
    ;
    }
  return 0;
}

int
main ()
{
  m = c = 1;
  n = fn1 (c);
  return 0;
}
>From gcc-bugs-return-441397-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org Fri Jan 24 03:12:44 2014
Return-Path: <gcc-bugs-return-441397-listarch-gcc-bugs=gcc.gnu.org@gcc.gnu.org>
Delivered-To: listarch-gcc-bugs@gcc.gnu.org
Received: (qmail 21107 invoked by alias); 24 Jan 2014 03:12:43 -0000
Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm
Precedence: bulk
List-Id: <gcc-bugs.gcc.gnu.org>
List-Archive: <http://gcc.gnu.org/ml/gcc-bugs/>
List-Post: <mailto:gcc-bugs@gcc.gnu.org>
List-Help: <mailto:gcc-bugs-help@gcc.gnu.org>
Sender: gcc-bugs-owner@gcc.gnu.org
Delivered-To: mailing list gcc-bugs@gcc.gnu.org
Received: (qmail 21065 invoked by uid 48); 24 Jan 2014 03:12:39 -0000
From: "pinskia at gcc dot gnu.org" <gcc-bugzilla@gcc.gnu.org>
To: gcc-bugs@gcc.gnu.org
Subject: [Bug tree-optimization/59932] spurious undefined behavior warning on valid code
Date: Fri, 24 Jan 2014 03:12:00 -0000
X-Bugzilla-Reason: CC
X-Bugzilla-Type: changed
X-Bugzilla-Watch-Reason: None
X-Bugzilla-Product: gcc
X-Bugzilla-Component: tree-optimization
X-Bugzilla-Version: 4.9.0
X-Bugzilla-Keywords:
X-Bugzilla-Severity: normal
X-Bugzilla-Who: pinskia at gcc dot gnu.org
X-Bugzilla-Status: UNCONFIRMED
X-Bugzilla-Priority: P3
X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org
X-Bugzilla-Target-Milestone: ---
X-Bugzilla-Flags:
X-Bugzilla-Changed-Fields:
Message-ID: <bug-59932-4-O8KO3qxx4Y@http.gcc.gnu.org/bugzilla/>
In-Reply-To: <bug-59932-4@http.gcc.gnu.org/bugzilla/>
References: <bug-59932-4@http.gcc.gnu.org/bugzilla/>
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/
Auto-Submitted: auto-generated
MIME-Version: 1.0
X-SW-Source: 2014-01/txt/msg02539.txt.bz2
Content-length: 271

http://gcc.gnu.org/bugzilla/show_bug.cgi?idY932

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
I don't see why you think this is not undefined behavior.
If p1 starts at 1, it cannot turn into 0 as p1++ overflows during the
2147483646th iteration.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/59932] spurious undefined behavior warning on valid code
  2014-01-24  3:09 [Bug tree-optimization/59932] New: spurious undefined behavior warning on valid code su at cs dot ucdavis.edu
@ 2014-01-24  3:20 ` su at cs dot ucdavis.edu
  2014-01-24  4:16 ` pinskia at gcc dot gnu.org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: su at cs dot ucdavis.edu @ 2014-01-24  3:20 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59932

--- Comment #2 from Zhendong Su <su at cs dot ucdavis.edu> ---
(In reply to Andrew Pinski from comment #1)
> I don't see why you think this is not undefined behavior.
> If p1 starts at 1, it cannot turn into 0 as p1++ overflows during the
> 2147483646th iteration.

Andrew, because "d.f1 > l" is false, so the code simply returns ("return b;"). 

I also always double-check with CompCert's reference interpreter and Frama-C if
possible.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/59932] spurious undefined behavior warning on valid code
  2014-01-24  3:09 [Bug tree-optimization/59932] New: spurious undefined behavior warning on valid code su at cs dot ucdavis.edu
  2014-01-24  3:20 ` [Bug tree-optimization/59932] " su at cs dot ucdavis.edu
@ 2014-01-24  4:16 ` pinskia at gcc dot gnu.org
  2014-01-24 20:49 ` su at cs dot ucdavis.edu
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: pinskia at gcc dot gnu.org @ 2014-01-24  4:16 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59932

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Zhendong Su from comment #2)
> (In reply to Andrew Pinski from comment #1)
> > I don't see why you think this is not undefined behavior.
> > If p1 starts at 1, it cannot turn into 0 as p1++ overflows during the
> > 2147483646th iteration.
> 
> Andrew, because "d.f1 > l" is false, so the code simply returns ("return
> b;"). 
> 
> I also always double-check with CompCert's reference interpreter and Frama-C
> if possible.

I see what is happening.  It is a true warning that happens due to optimizing
order differences.  The place we warn does not know that f is zero the first
time through the loop.  Since -Os disables copy headers, we don't get a
different copy of the header.  So the code does not optimize away the header.

This is where I am going to say there is a false positive due to optimizing.  I
want to close it as won't fix because if we change the value of l to be 0xfe,
then we always warn.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/59932] spurious undefined behavior warning on valid code
  2014-01-24  3:09 [Bug tree-optimization/59932] New: spurious undefined behavior warning on valid code su at cs dot ucdavis.edu
  2014-01-24  3:20 ` [Bug tree-optimization/59932] " su at cs dot ucdavis.edu
  2014-01-24  4:16 ` pinskia at gcc dot gnu.org
@ 2014-01-24 20:49 ` su at cs dot ucdavis.edu
  2014-01-28 16:20 ` jakub at gcc dot gnu.org
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: su at cs dot ucdavis.edu @ 2014-01-24 20:49 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59932

--- Comment #4 from Zhendong Su <su at cs dot ucdavis.edu> ---
(In reply to Andrew Pinski from comment #3)
> (In reply to Zhendong Su from comment #2)
> > (In reply to Andrew Pinski from comment #1)
> > > I don't see why you think this is not undefined behavior.
> > > If p1 starts at 1, it cannot turn into 0 as p1++ overflows during the
> > > 2147483646th iteration.
> > 
> > Andrew, because "d.f1 > l" is false, so the code simply returns ("return
> > b;"). 
> > 
> > I also always double-check with CompCert's reference interpreter and Frama-C
> > if possible.
> 
> I see what is happening.  It is a true warning that happens due to
> optimizing order differences.  The place we warn does not know that f is
> zero the first time through the loop.  Since -Os disables copy headers, we
> don't get a different copy of the header.  So the code does not optimize
> away the header.
> 
> This is where I am going to say there is a false positive due to optimizing.
> I want to close it as won't fix because if we change the value of l to be
> 0xfe, then we always warn.

Andrew, sorry, I'm baffled by your comments above. 

Please note: 
1) The issue isn't only triggered at -Os, but also at -O2 and -O3. 
2) It doesn't affect GCC 4.8.
3) I don't see how changing l to 0xfe has changed anything. 
4) Also optimizations shouldn't really change the warnings issued. 

Perhaps I have some misunderstandings, so could you clarify?  Thanks.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/59932] spurious undefined behavior warning on valid code
  2014-01-24  3:09 [Bug tree-optimization/59932] New: spurious undefined behavior warning on valid code su at cs dot ucdavis.edu
                   ` (2 preceding siblings ...)
  2014-01-24 20:49 ` su at cs dot ucdavis.edu
@ 2014-01-28 16:20 ` jakub at gcc dot gnu.org
  2014-01-28 18:15 ` su at cs dot ucdavis.edu
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-01-28 16:20 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59932

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Zhendong Su from comment #2)
> (In reply to Andrew Pinski from comment #1)
> > I don't see why you think this is not undefined behavior.
> > If p1 starts at 1, it cannot turn into 0 as p1++ overflows during the
> > 2147483646th iteration.
> 
> Andrew, because "d.f1 > l" is false, so the code simply returns ("return
> b;"). 
> 
> I also always double-check with CompCert's reference interpreter and Frama-C
> if possible.

There clearly is a loop with undefined behavior if it is every entered (several
of them), but you just never happen to enter it.  Whether to warn about bugs in
obviously dead code is a heated debate, some people ask for it, others don't
want it, but in this case whether the compiler knows it is dead code or not
depends on optimizations.  GCC doesn't warn about the other loops because they
have multiple exits and the -Waggressive-loop-optimization warning is, in order
to have as few false positives as possible, only used for the most simple
loops.

Anyway, in this case IMHO it is very well worth the false positive in this
case, rather than never warning because we can't be 100% sure if it isn't in
dead code.
After all, we couldn't then warn about
int a[3];
void foo (void)
{
  for (int i = 0; i < 4; i++)
    a[i]++;
}
just because main might not call foo at all and thus you'd never invoke the
undefined behavior.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/59932] spurious undefined behavior warning on valid code
  2014-01-24  3:09 [Bug tree-optimization/59932] New: spurious undefined behavior warning on valid code su at cs dot ucdavis.edu
                   ` (3 preceding siblings ...)
  2014-01-28 16:20 ` jakub at gcc dot gnu.org
@ 2014-01-28 18:15 ` su at cs dot ucdavis.edu
  2014-01-28 21:45 ` jakub at gcc dot gnu.org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: su at cs dot ucdavis.edu @ 2014-01-28 18:15 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59932

--- Comment #6 from Zhendong Su <su at cs dot ucdavis.edu> ---
Thanks for your explanation Jakub. It's more clear now, but I still don't fully
understand the difference in behavior from 4.8 to the current trunk. 

Is it because 4.8's support for warning undefined behaviors is weaker than
4.9's, and with that enhanced support, 4.9 sometimes gives false warnings like
the one reported here?


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/59932] spurious undefined behavior warning on valid code
  2014-01-24  3:09 [Bug tree-optimization/59932] New: spurious undefined behavior warning on valid code su at cs dot ucdavis.edu
                   ` (4 preceding siblings ...)
  2014-01-28 18:15 ` su at cs dot ucdavis.edu
@ 2014-01-28 21:45 ` jakub at gcc dot gnu.org
  2014-01-30  1:38 ` su at cs dot ucdavis.edu
  2014-01-30  1:40 ` su at cs dot ucdavis.edu
  7 siblings, 0 replies; 9+ messages in thread
From: jakub at gcc dot gnu.org @ 2014-01-28 21:45 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59932

--- Comment #7 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Zhendong Su from comment #6)
> Thanks for your explanation Jakub. It's more clear now, but I still don't
> fully understand the difference in behavior from 4.8 to the current trunk. 
> 
> Is it because 4.8's support for warning undefined behaviors is weaker than
> 4.9's, and with that enhanced support, 4.9 sometimes gives false warnings
> like the one reported here?

4.8 only warned about this in later passes when the loops have been already
constructed and preserved, so it wouldn't warn e.g. if it was cunrolli (as in
this case) that found the undefined behavior.  GCC 4.9 creates loops
immediately after cfg is created and the warning is thus enabled much earlier. 
This means we warn in more cases when it is desirable to warn, but as this
testcase shows also sometimes means there can be false positives.  The loop
with the undefined behavior is there for many passes, from cunrolli where it
warns another 20 passes until dom1 is able to find out the code is dead.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/59932] spurious undefined behavior warning on valid code
  2014-01-24  3:09 [Bug tree-optimization/59932] New: spurious undefined behavior warning on valid code su at cs dot ucdavis.edu
                   ` (5 preceding siblings ...)
  2014-01-28 21:45 ` jakub at gcc dot gnu.org
@ 2014-01-30  1:38 ` su at cs dot ucdavis.edu
  2014-01-30  1:40 ` su at cs dot ucdavis.edu
  7 siblings, 0 replies; 9+ messages in thread
From: su at cs dot ucdavis.edu @ 2014-01-30  1:38 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59932

Zhendong Su <su at cs dot ucdavis.edu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |FIXED

--- Comment #8 from Zhendong Su <su at cs dot ucdavis.edu> ---
(In reply to Jakub Jelinek from comment #7)
> (In reply to Zhendong Su from comment #6)
> > Thanks for your explanation Jakub. It's more clear now, but I still don't
> > fully understand the difference in behavior from 4.8 to the current trunk. 
> > 
> > Is it because 4.8's support for warning undefined behaviors is weaker than
> > 4.9's, and with that enhanced support, 4.9 sometimes gives false warnings
> > like the one reported here?
> 
> 4.8 only warned about this in later passes when the loops have been already
> constructed and preserved, so it wouldn't warn e.g. if it was cunrolli (as
> in this case) that found the undefined behavior.  GCC 4.9 creates loops
> immediately after cfg is created and the warning is thus enabled much
> earlier.  This means we warn in more cases when it is desirable to warn, but
> as this testcase shows also sometimes means there can be false positives. 
> The loop with the undefined behavior is there for many passes, from cunrolli
> where it warns another 20 passes until dom1 is able to find out the code is
> dead.

Thanks


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Bug tree-optimization/59932] spurious undefined behavior warning on valid code
  2014-01-24  3:09 [Bug tree-optimization/59932] New: spurious undefined behavior warning on valid code su at cs dot ucdavis.edu
                   ` (6 preceding siblings ...)
  2014-01-30  1:38 ` su at cs dot ucdavis.edu
@ 2014-01-30  1:40 ` su at cs dot ucdavis.edu
  7 siblings, 0 replies; 9+ messages in thread
From: su at cs dot ucdavis.edu @ 2014-01-30  1:40 UTC (permalink / raw)
  To: gcc-bugs

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59932

Zhendong Su <su at cs dot ucdavis.edu> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|FIXED                       |WONTFIX

--- Comment #9 from Zhendong Su <su at cs dot ucdavis.edu> ---
Thanks Jakub; I follow now. 

Let me mark it as RESOLVED/WONTFIX.


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-01-30  1:40 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-24  3:09 [Bug tree-optimization/59932] New: spurious undefined behavior warning on valid code su at cs dot ucdavis.edu
2014-01-24  3:20 ` [Bug tree-optimization/59932] " su at cs dot ucdavis.edu
2014-01-24  4:16 ` pinskia at gcc dot gnu.org
2014-01-24 20:49 ` su at cs dot ucdavis.edu
2014-01-28 16:20 ` jakub at gcc dot gnu.org
2014-01-28 18:15 ` su at cs dot ucdavis.edu
2014-01-28 21:45 ` jakub at gcc dot gnu.org
2014-01-30  1:38 ` su at cs dot ucdavis.edu
2014-01-30  1:40 ` su at cs dot ucdavis.edu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).