2

I have a rather complex multithreaded code, which I compile using gcc 4.8.1. When compiling with

g++ -c file.cc -march=native -mfpmath=sse -mpreferred-stack-boundary=4
--param inline-unit-growth=50 -ggdb3 -Wall -Wextra -Winit-self
-O2 -fPIC -funroll-loops -fforce-addr -rdynamic

the code produced crashes with segfault (which I was unable to debug, but the address of a struct all of a sudden differs from what it was when constructed, in particular, is no longer aligned to 32bytes as required by the code but only to 8bytes).

When compiling with -O1 instead, the code works fine. I then added all the optimisation flags that make the difference between -O1 and -O2. (To this end, I created two files O1-opts and O2-opts via

g++ -march=native -mfpmath=sse -mpreferred-stack-boundary=4
--param inline-unit-growth=50 -ggdb3 -Wall -Wextra -Winit-self
-O1 -fPIC -funroll-loops -fforce-addr -rdynamic
-Q --help=optimizers > O1-opts

g++ -march=native -mfpmath=sse -mpreferred-stack-boundary=4
--param inline-unit-growth=50 -ggdb3 -Wall -Wextra -Winit-self
-O2 -fPIC -funroll-loops -fforce-addr -rdynamic
-Q --help=optimizers > O2-opts

when diff O1-opts O2-opts provides the option differences). When adding all the option differences to -O1, the code generated still does not crash. This puzzles me. So my question is: shouldn't this give exactly the same result as with -O2? (and also: what is the likely cause of my problem?)

Walter
  • 44,150
  • 20
  • 113
  • 196
  • 10
    Crashing depending on optimization level sounds like undefined behavior but we don't have enough information. – Shafik Yaghmour Mar 17 '15 at 14:57
  • 1
    @ShafikYaghmour I know, but that was not the main question. – Walter Mar 17 '15 at 14:58
  • 2
    @Walter which is probably why he answered your secondary question in a comment rather than an answer. – eerorika Mar 17 '15 at 15:01
  • 2
    I have tried similar experiments without success and the best guess I have is that the documented flags do not fully cover the differences. – Shafik Yaghmour Mar 17 '15 at 15:02
  • As always: Give a newer GCC like 4.9 or 5 a try. Maybe they fixed the problem and then you know it was a compiler bug. Additionally you can use sanitizers, I am amazed how ofter they give me useful hints. – usr1234567 Mar 17 '15 at 15:09
  • 2
    Undefined behaviour is, by definition, not guaranteed to give *exactly the same results* from one compilation to another regardless of flags used. Or even from one run of the program to the next *even without* recompiling. – Galik Mar 17 '15 at 15:11
  • possible duplicate of [GCC: Whats the difference between -O3 and -O2 + x?](http://stackoverflow.com/questions/6454415/gcc-whats-the-difference-between-o3-and-o2-x) – OmnipotentEntity Mar 17 '15 at 15:42

1 Answers1

3

The point is that the -O2 option not only sets different flags, but also enables additional optimizations in contrast to -O1.

The FAQ section of the GCC Wiki has an appropriate entry for this.

user0815
  • 1,376
  • 7
  • 8