public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/63880] New: GCC overoptimization on local arrays of size 1
@ 2014-11-14 23:42 petzke at teltarif dot de
  2014-11-14 23:43 ` [Bug c/63880] " petzke at teltarif dot de
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: petzke at teltarif dot de @ 2014-11-14 23:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63880

            Bug ID: 63880
           Summary: GCC overoptimization on local arrays of size 1
           Product: gcc
           Version: 4.8.2
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: petzke at teltarif dot de

Created attachment 33979
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33979&action=edit
Overoptimized C code: The loop is unrolled to a single iteration, which the
compiler should not rely on, at least not in C.

In general, C code may rely on the fact, that structs are allocated
sequentially, even, if this is considered a somewhat bad coding practice. So,
if one has the following structures in C:

typedef struct {
    int nargs;
    char * data[1];
} arglist;

struct {
    arglist args;
    char * moredata[1000];
} par;

it is actually safe to access par.args.data[2] through par.args.data[1000], as
they get basically mapped onto par.moredata[0] through par.moredata[999].
However, GCC version 4.8.2 seems to believe, that this access is "off limits",
and actually optimizes a simple loop:
    for(i = args->nargs; --i >= 0; ) {
        if(args->data[i][0]) { cnt++; }
    }
to run at most once, when optimizing option -O3 is used. An example of a thus
over-optimized code snippet (compile with "-m64 -Wall -O3 -S" on Intel x86_64 -
cannot compile into an executable though) is attached as "overoptimized.c".

It suffices to introduce a pointer to "arglist" to turn off that
overoptimization and actually get working code again. An exmpale is added as
"works.c".

I assume, that this array size optimization is not applied on pointers to
structs, as these may be malloc()ed with the well-known trick of requesting
extra space to increase the array size of the last element. However, that trick
is not reserved to malloc(), it is also available to local vars via the
combined struct shown for "par" above. Of course, this is only true for *C*.
C++ may rip structs apart, but C may not.

Having said that:
* The loop optimization based on array size should still be applied, if the
above example "arglist" is *directly* defined as a local var.
* But if that "arglist" is part of another struct, that defines extra data
items at the end, the compiler should not assume, that the array won't be
accessed out of bounds. I know, that this out-of-bounds access is a somewhat
"bad" coding style, but there is code, that still relies on these "dirty old C
tricks".


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

* [Bug c/63880] GCC overoptimization on local arrays of size 1
  2014-11-14 23:42 [Bug c/63880] New: GCC overoptimization on local arrays of size 1 petzke at teltarif dot de
@ 2014-11-14 23:43 ` petzke at teltarif dot de
  2014-11-15  2:28 ` pinskia at gcc dot gnu.org
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: petzke at teltarif dot de @ 2014-11-14 23:43 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63880

--- Comment #1 from Kai Petzke <petzke at teltarif dot de> ---
Created attachment 33980
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33980&action=edit
A file with small modifications from overoptimized.c, that compiles correctly.


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

* [Bug c/63880] GCC overoptimization on local arrays of size 1
  2014-11-14 23:42 [Bug c/63880] New: GCC overoptimization on local arrays of size 1 petzke at teltarif dot de
  2014-11-14 23:43 ` [Bug c/63880] " petzke at teltarif dot de
@ 2014-11-15  2:28 ` pinskia at gcc dot gnu.org
  2014-11-15  2:29 ` pinskia at gcc dot gnu.org
  2014-11-17  9:42 ` rguenth at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2014-11-15  2:28 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63880

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

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

--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
>In general, C code may rely on the fact

Maybe but this is undefined code in C.


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

* [Bug c/63880] GCC overoptimization on local arrays of size 1
  2014-11-14 23:42 [Bug c/63880] New: GCC overoptimization on local arrays of size 1 petzke at teltarif dot de
  2014-11-14 23:43 ` [Bug c/63880] " petzke at teltarif dot de
  2014-11-15  2:28 ` pinskia at gcc dot gnu.org
@ 2014-11-15  2:29 ` pinskia at gcc dot gnu.org
  2014-11-17  9:42 ` rguenth at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: pinskia at gcc dot gnu.org @ 2014-11-15  2:29 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63880

--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
if you allocated an arglist via malloc (or alloca) and not have a struct which
contained arglist, it would be valid (well GCC would do the correct thing as we
define it as being valid).


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

* [Bug c/63880] GCC overoptimization on local arrays of size 1
  2014-11-14 23:42 [Bug c/63880] New: GCC overoptimization on local arrays of size 1 petzke at teltarif dot de
                   ` (2 preceding siblings ...)
  2014-11-15  2:29 ` pinskia at gcc dot gnu.org
@ 2014-11-17  9:42 ` rguenth at gcc dot gnu.org
  3 siblings, 0 replies; 5+ messages in thread
From: rguenth at gcc dot gnu.org @ 2014-11-17  9:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63880

--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
Indeed this is a case we don't handle as QOI special-case (we accept other
cases of strictly undefined code though).

In this case it is recommended to just do

arglist *p = malloc (sizeof (arglist) + sizeof (char *) * 1000);

and as Andrew said not wrap arglist inside another struct which appends a
member.


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

end of thread, other threads:[~2014-11-17  9:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-14 23:42 [Bug c/63880] New: GCC overoptimization on local arrays of size 1 petzke at teltarif dot de
2014-11-14 23:43 ` [Bug c/63880] " petzke at teltarif dot de
2014-11-15  2:28 ` pinskia at gcc dot gnu.org
2014-11-15  2:29 ` pinskia at gcc dot gnu.org
2014-11-17  9:42 ` rguenth at gcc dot gnu.org

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