public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/61131] New: [4.8 regression] ARM -Os: incorrect code generation
@ 2014-05-09 19:50 swarren at nvidia dot com
  2014-05-10 10:35 ` [Bug target/61131] " mikpelinux at gmail dot com
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: swarren at nvidia dot com @ 2014-05-09 19:50 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 61131
           Summary: [4.8 regression] ARM -Os: incorrect code generation
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: swarren at nvidia dot com

Created attachment 32771
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=32771&action=edit
Source sample that exhibits the issue when compiled

When running gcc 4.8 for ARM with -Os, the following function:

int count_entries(struct s *p)
{
    int i = 0;

    while (p->fd[i] >= 0 && i < MAX_COUNT) {
        i++;
    }

    return i;
}

... gets compiled to essentially a no-op:

000083f8 <count_entries>:
    83f8:    e5900000     ldr    r0, [r0]
    83fc:    e1e00000     mvn    r0, r0
    8400:    e1a00fa0     lsr    r0, r0, #31
    8404:    e12fff1e     bx    lr

If I don't use -Os, then I get much larger, and working, code.

If I swap the order of the two conditions in the while expression, I get
working code:

    while (i < MAX_COUNT && p->fd[i] >= 0) {

If I use gcc-4.7 insteaad, I get working code.

A complete source sample is attached.

The bug is NOT present in
gcc-linaro-arm-linux-gnueabihf-4.7-2013.04-20130415_linux.tar.xz, which is
apparently GCC 4.7.2+svn197188.

The bug IS present in gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux.tar.xz,
which is apparently GCC 4.8.3+svn208968.

I wasn't able to quickly track down any more recent gcc-4.8.x binaries, or
gcc-4.9.x binaries.

The bug IS present in some toolchain I received from a customer in directory
name yocto/gcc-4.8.1-glibc-2.18-hard/.


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

* [Bug target/61131] [4.8 regression] ARM -Os: incorrect code generation
  2014-05-09 19:50 [Bug c/61131] New: [4.8 regression] ARM -Os: incorrect code generation swarren at nvidia dot com
@ 2014-05-10 10:35 ` mikpelinux at gmail dot com
  2014-05-10 11:01 ` rearnsha at gcc dot gnu.org
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: mikpelinux at gmail dot com @ 2014-05-10 10:35 UTC (permalink / raw)
  To: gcc-bugs

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

Mikael Pettersson <mikpelinux at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mikpelinux at gmail dot com

--- Comment #1 from Mikael Pettersson <mikpelinux at gmail dot com> ---
With a bit more context it's easy to see the error:

==snip==
#define MAX_COUNT 2

struct s {
        int fd[MAX_COUNT];
        int status;
        unsigned int bogus;
};

int count_entries(struct s *p);
int count_entries(struct s *p)
{
        int i = 0;

        while (p->fd[i] >= 0 && i < MAX_COUNT) { // bad
        //while (i < MAX_COUNT && p->fd[i] >= 0) { // ok
                i++;
        }
==snip==

If ->fd[0] and ->fd[1] are both non-negative, then i will be incremented to 2,
the "bad" code will access ->fd[2], which is an out-of-bounds error, causing
undefined behaviour.  GCC sees this, "knows" that this cannot happen, and
changes the generated code accordingly with surprising results.  The "ok" code
is correct.

I've seen this bogus pattern in Linux kernel sources.  AFAIK it's been fixed
there now.


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

* [Bug target/61131] [4.8 regression] ARM -Os: incorrect code generation
  2014-05-09 19:50 [Bug c/61131] New: [4.8 regression] ARM -Os: incorrect code generation swarren at nvidia dot com
  2014-05-10 10:35 ` [Bug target/61131] " mikpelinux at gmail dot com
@ 2014-05-10 11:01 ` rearnsha at gcc dot gnu.org
  2014-05-12 16:06 ` swarren at nvidia dot com
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: rearnsha at gcc dot gnu.org @ 2014-05-10 11:01 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Earnshaw <rearnsha at gcc dot gnu.org> changed:

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

--- Comment #2 from Richard Earnshaw <rearnsha at gcc dot gnu.org> ---
As described, the bounds check has to be applied before dereferencing the
array, not afterwards.


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

* [Bug target/61131] [4.8 regression] ARM -Os: incorrect code generation
  2014-05-09 19:50 [Bug c/61131] New: [4.8 regression] ARM -Os: incorrect code generation swarren at nvidia dot com
  2014-05-10 10:35 ` [Bug target/61131] " mikpelinux at gmail dot com
  2014-05-10 11:01 ` rearnsha at gcc dot gnu.org
@ 2014-05-12 16:06 ` swarren at nvidia dot com
  2014-05-12 16:22 ` pinskia at gcc dot gnu.org
  2014-05-12 17:26 ` mikpelinux at gmail dot com
  4 siblings, 0 replies; 6+ messages in thread
From: swarren at nvidia dot com @ 2014-05-12 16:06 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from Stephen Warren <swarren at nvidia dot com> ---
This certainly violates the principle of least-surprise...

Once i==2, "p->fd[i] >= 0" is certainly undefined. Surely "undefined && false"
is false though, since "anything && false" is false; short-circuit evaluation
should surely only apply if "anything" was known to be false, and presumably
"undefined" isn't known to be false. Or is the definition of undefined such
that it propagates through the entire expression irrespective of the
expression's logic? I suppose that could be the case, but it's certainly not
the most useful definition of undefined:-)


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

* [Bug target/61131] [4.8 regression] ARM -Os: incorrect code generation
  2014-05-09 19:50 [Bug c/61131] New: [4.8 regression] ARM -Os: incorrect code generation swarren at nvidia dot com
                   ` (2 preceding siblings ...)
  2014-05-12 16:06 ` swarren at nvidia dot com
@ 2014-05-12 16:22 ` pinskia at gcc dot gnu.org
  2014-05-12 17:26 ` mikpelinux at gmail dot com
  4 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu.org @ 2014-05-12 16:22 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Stephen Warren from comment #3)
> This certainly violates the principle of least-surprise...
> 
> Once i==2, "p->fd[i] >= 0" is certainly undefined. Surely "undefined &&
> false" is false though, since "anything && false" is false; short-circuit
> evaluation should surely only apply if "anything" was known to be false, and
> presumably "undefined" isn't known to be false. Or is the definition of
> undefined such that it propagates through the entire expression irrespective
> of the expression's logic? I suppose that could be the case, but it's
> certainly not the most useful definition of undefined:-)

The undefined basically gets turned into a continue. Also the value is not just
undefined, the effect of doing an out of bounds is undefined and could even
crash.


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

* [Bug target/61131] [4.8 regression] ARM -Os: incorrect code generation
  2014-05-09 19:50 [Bug c/61131] New: [4.8 regression] ARM -Os: incorrect code generation swarren at nvidia dot com
                   ` (3 preceding siblings ...)
  2014-05-12 16:22 ` pinskia at gcc dot gnu.org
@ 2014-05-12 17:26 ` mikpelinux at gmail dot com
  4 siblings, 0 replies; 6+ messages in thread
From: mikpelinux at gmail dot com @ 2014-05-12 17:26 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #5 from Mikael Pettersson <mikpelinux at gmail dot com> ---
(In reply to Stephen Warren from comment #3)
> Or is the definition of
> undefined such that it propagates through the entire expression irrespective
> of the expression's logic?

It is.  Once execution hits undefined behaviour all bets are off.

"Undefined" is not some unspecified value you can choose to ignore.


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

end of thread, other threads:[~2014-05-12 17:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-09 19:50 [Bug c/61131] New: [4.8 regression] ARM -Os: incorrect code generation swarren at nvidia dot com
2014-05-10 10:35 ` [Bug target/61131] " mikpelinux at gmail dot com
2014-05-10 11:01 ` rearnsha at gcc dot gnu.org
2014-05-12 16:06 ` swarren at nvidia dot com
2014-05-12 16:22 ` pinskia at gcc dot gnu.org
2014-05-12 17:26 ` mikpelinux at gmail dot com

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).