13

I tried to compile the following function to see what gcc made of it:

#include <stdint.h>
#include <stddef.h>

typedef struct giga
{
  uint64_t g[0x10000000];
} giga;

uint64_t addfst(giga const *gptr, size_t num)
{
  uint64_t retval = 0;
  for (size_t i = 0; i < num; i++)
    {
      retval += gptr[i].g[0];
    }
  return retval;
}

And found gcc maxing out my memory, swapping itself to death.
I've found this to happen when optimizing at -O3, haven't tried to dissect the exact flag(s) responsible. Testing the function on gcc.godbolt reveals this to be gcc specific, but afflicting 4.8 and 4.9 versions.
Is this a genuine compiler bug, or is my function broken?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
EOF
  • 6,273
  • 2
  • 26
  • 50
  • 2
    Confirmed on `gcc version 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC)`. – Jonathon Reinhart Mar 22 '15 at 22:35
  • 2
    It looks like it's some combination of flags. `-O2 -ftree-vectorize` exhibits the behvior but does not without `-O2`. – Jonathon Reinhart Mar 22 '15 at 22:40
  • @JonathonReinhart: It seems you're on to something with `-ftree-vectorize`, but on my machine `GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2` it also freezes on `-O1 -ftree-vectorize`. – EOF Mar 22 '15 at 22:54
  • Confirmed on `4.9.2`. – edmz Mar 22 '15 at 23:00
  • 2
    I reported this to the gcc bugzilla. – EOF Mar 22 '15 at 23:01
  • I recommend writing up an answer (it needn't be all that long) that identifies the bug in GCC's bugzilla (give the bug number, or a URL to it). In a couple of days, you'll be able to accept it to close your question out. Having a good simple test case like the one you show makes life easier for everyone. – Jonathan Leffler Mar 22 '15 at 23:25
  • the program has a struct definition of, ~2.6843546e8 64bit entities. That could be more that the OPs total RAM and it definitely overflowed the gptr capabilites That is the root of the problem. – user3629249 Mar 23 '15 at 00:15
  • @user3629249: Nope. I should perhaps clarify that I'm using a 64-bit architecture. In fact, *increasing* the size of `giga`'s array to `0x100000000` makes the bug go away. Also, `clang` and `icc` will compile with high optimizations (though the assembly they generate is iffy). – EOF Mar 23 '15 at 00:58
  • @EOF: I stand by what user3629249, just because the optimizer gives up for larger arrays doesn't mean that he's wrong. – Mooing Duck Mar 23 '15 at 22:40
  • @MooingDuck: I strongly disagree. First of, this is a compile-time failure. Run-time memory considerations are secondary. In fact, since `num` may well be 1, even a machine with moderate physical memory can theoretically use this function, especially since the function doesn't actually *use* most of the memory (only 1 page per `num`). Second, compiling for 32-bit causes an explicit error, rather than hanging like for 64-bit. Anyway, if you disagree, you're free to visit the bugreport and try telling the devs they're wrong about the origins of the bug they've already fixed. Good luck! – EOF Mar 24 '15 at 00:14
  • @EOF: We weren't talking about run-time memory considerations. I meant that when the array is in the vicinity of 0x10000000, the compiler tries to do some crazy memory-intensive operation (single element interleaving) and _uses all the primary memory_. If the array is bigger, the compiler gives up and doesn't bother optimizing it much, so requires little memory, and succeeds at compilation quickly. I've had Visual Studio do that before. https://connect.microsoft.com/VisualStudio/feedback/details/699728/visual-studio-runs-out-of-memory-when-compiling-recursive-inline-templates-in-release – Mooing Duck Mar 24 '15 at 00:26
  • To clarify: The fact that it used all your RAM when optimizing _is_ the bug. – Mooing Duck Mar 24 '15 at 00:28
  • @MooingDuck: I really don't see how user3629249's comment relates to that. "[...]That could be more that the OPs total RAM and it definitely overflowed the gptr capabilites That is the root of the problem." would *only* be relevant to what you said if the compiler needed to allocate `struct giga`s at compile time to generate the code, which is absurd. – EOF Mar 24 '15 at 00:45
  • @EOF: I don't claim to know how the optimizer works, but it could be it's attempting to do just that in order to calculate `retval` at compile time. – Mooing Duck Mar 24 '15 at 16:29
  • @MooingDuck: Oh, I don't have the faintest clue about auto-vectorizing optimizing compilers, but if it had to allocate the `struct` at compile-time (to what end? *Simulate* the execution?), that would make cross-compilation a bit of a problem, right? Also, this is about compiling *only* `addfst()`, so the compiler *cannot* calculate `retval` at compile-time, because it has no clue what arguments will ever be passed to the function. Also, as I've said, the function itself is only a problem with regards to address space, not memory. – EOF Mar 24 '15 at 17:08
  • I haven't the faintest clue either. All I know is that it _did_ allocate a huge amount of memory at compile time when doing a "single element interleaving" optimization on the huge array. I have worked with the assumption that it allocated that memory as part of that optimization (perhaps foolishly), whereas you _appear_ to be assuming the compiler allocating a massive amount of memory was unrelated to the array. – Mooing Duck Mar 24 '15 at 17:25

1 Answers1

3

The bug is on the gcc bugzilla, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65518. It has been confirmed & apparently fixed in trunk. Here's hoping the fix eventually trickles down to my distro. Thanks everyone!

EOF
  • 6,273
  • 2
  • 26
  • 50