gcc creates crashing code depending on optimisation - c++

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

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.

Related

expression is "optimized out" even with debug compile flags

My compile flags are
-mthumb -mlittle-endian -x c++ -gdwarf-2 -g3 -fomit-frame-pointer -fnothrow-opt
-ffreestanding -fverbose-asm -std=c++11 -c -fno-rtti -ffunction-sections -fdata-sections
-fno-exceptions`
Note the -gdwarf-2 -g3
However, many of the variables I attempt to read are read as
optimized out
-g adds debugging information, but it does not discourage code optimisations, so you've only asked for half the job.
Add on -O0 or -Og and have a read of the manual page on debugging options.
You've also specifically turned on one optimisation (-fomit-frame-pointer); remove that.

g++ not suppressing warnings

I am facing the weirdest thing ever. I am having a deprecation warning although I am using -Wno-deprecated flag with g++.
What am I doing wrong? Should I reorder the flags I am passing to g++?
g++ -fno-strict-aliasing -Wall -D__LINUX__ -DOS_USE_STD_IOSTREAMS -DOS_LINUX_2_2 -D__CPP -D__USE_BSD -DLINUX -Wno-sign-compare -Wno-deprecated -Wno-unused-variable -Wno-write-strings -Wno-unused -DOS_USE_STD_IOSTREAM -m64 -m64 -O3 -Werror
The deprecation warning is specifically about sys_errlist and that I should use stderror or stderror_r.
I have checked the specific header file declraing the function that uses sys_errlist and it doesn't have a diagnostic pragma.
I am using GCC 3.3.1 on a 64 bit RHE4 machine

Position of -std=c++11 in g++ command line

I am just curious if the position of the standard selection switch (-std=c++11 for my case) is relevant in g++ command line or not. The reason is that the following:
g++ -ftest-coverage -fprofile-arcs -std=c++11
-ansi -fpermissive -finline-functions -Wno-long-long
-fvisibility-inlines-hidden -m64 -Wall -Wextra
-g -o CMakeFiles/common.dir/cryptoclass.cpp.o
-c /home/work/common/cryptoclass.cpp
does not compile, while the following:
g++ -ftest-coverage -fprofile-arcs
-ansi -fpermissive -finline-functions -Wno-long-long
-fvisibility-inlines-hidden -m64 -Wall -Wextra
-g -o CMakeFiles/common.dir/cryptoclass.cpp.o
-std=c++11 -c /home/work/common/cryptoclass.cpp
does compile. The only change is that the -std=c++11 was moved to the end of the switches.
g++ gives the following warning:
error: #error This file requires compiler and
library support for the ISO C++ 2011 standard.
This support is currently experimental, and must
be enabled with the -std=c++11 or -std=gnu++11 compiler options.
Version:
g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
As per documentation, -ansi option enables the c++-98/c++-03 standard.
If you set multiple standard options, the latter option overrides the former. Same applies to other mutually exclusive options such as optimization levels.

R Makevars file to overwrite R CMD's default g++ options?

I have this standalone C++ code
that I'm trying to wrap in an R
package.
My problem is that I absolutely
want it to be compiled with the
-O3 flag on.
So in the src/Makevars file
I put:
PKG_CPPFLAGS = -I../inst/include
PKG_CXXFLAGS = -O3
CXX_STD = CXX11
and still when I install my package on my
machine, I see:
g++ -std=c++0x -I/usr/share/R/include -DNDEBUG -I../inst/include -O3 -fpic -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -g -c mycppfunctions.cpp -o mycppfunctions.o
g++ -std=c++0x -shared -Wl,-Bsymbolic-functions -Wl,-z,relro -o mycppfunctions.so mycppfunctions.o -L/usr/lib/R/lib -lR
(the dreaded -O2 flag appears to the right)
so my question is: how can I overwrite the
cpp flags used when g++ is invoked by R CMD?
Edit:
Recently, in another package, I found a way to do
something similar for a F77 code (also in an R package).
Basically, by adding this to the Makevars:
PKG_FFLAGS = $(FPICFLAGS) $(SHLIB_FFLAGS)
all: $(SHLIB)
otherf77foo.o: otherf77foo.f
$(F77) $(PGK_FFLAGS) -O3 -pipe -g -c -o otherf77foo.o otherf77foo.f
but I don't know how to do the same for a cpp code...
Edit2:
So, doing this is totally possible. Dirk Eddelbuettel question 'b)' from his answer below
guided me to the solution. So, all I had to do was to
place this in the src/Makevars file:
mycppfoo.o: mycppfoo.cpp
g++ -std=c++0x -I/usr/share/R/include -DNDEBUG -I../inst/include -fpic -g -O3 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Wformat-security -Werror=format-security -D_FORTIFY_SOURCE=2 -g -c mycppfoo.cpp -o mycppfoo.o
g++ -std=c++0x -shared -Wl,-Bsymbolic-functions -Wl,-z,relro -o mycppfoo.so mycppfoo.o -L/usr/lib/R/lib -lR
and my problem was solved!
You can't (as per a comment by Simon Urbanek on r-devel a while back).
But it should not matter as AFAIK the right-most value wins. And R puts its values to the left, and lets you add your values (eg via CXX_FLAGS from, say, ~/.R/Makevars or PKG_CXXFLAGS from the src/Makevars in your package) to the right.
So just override with -O3 and it should be -O3.
For what it is worth, my current values in ~/.R/Makevars are:
CFLAGS += -O3 -Wall -pipe -pedantic -std=gnu99
CXXFLAGS += -O3 -Wall -pipe -Wno-unused -pedantic
and you could of course throw in -mnative or your specific CPU identifier.
Lastly, if you really wanted you could edit /etc/R/Makeconf but you'd have to do that
after each upgrade of the R package. And as I argue here you do not need to as the scheme suggested here should work.
Edit: In response to your edit:
a) The clear recommendation on r-devel (please check the archives) is that you should avoid Makefile logic if you can. IIRC this echoed in the Writing R Extension manual.
b) You declared a rule to build an .o (object) file from an .f (source) file. Did you try doing the same with cpp instead of f?
Lastly, you have not explained exactly why the world is coming to an end if your file is built with -O2 rather than -O3. You should understand that as an author of source, you can't fully control with which compiler options (let alone compiler versions) people will build your package.
newedit: Okay I'm a fool. It solved the problem for Rcpp (which I don't care about), but it doesn't work for the github.com/ohdsi/cyclops.git package that I do care about. That one still gets -O2 stuck right-most. This is ridiculous. Control over command-line parameters might be the single most important piece of this entire operation. R needs a better build system.
edit: Of course after days of trouble, I figure it out right after posting. My problem was that I was using the CXX_STD = CXX11 flag. Apparently with this flag you need to use CXX11FLAGS += .... So if your Makevars file contains CXX11FLAGS += -O0 -Wall it will correctly put this to the right of the -O2 flag if you're using C++11.
No matter what I do I can't get -O0 to show up on the right. I have the following in my ~/.R/Makevars:
CFLAGS += -O0 -Wall
CXXFLAGS += -O0 -Wall
CPPFLAGS += -O0 -Wall
PKG_CFLAGS += -O0 -Wall
PKG_CXXFLAGS += -O0 -Wall
PKG_CPPFLAGS += -O0 -Wall
I have installed Rcpp from source (as a test...I'm not interested in it directly) using
install.packages(getwd(), repos = NULL, type = "source")
and that did correctly use -O0.
With my current configuration, I end up getting three different -O0's to the left and final -O2 on the right. Has anyone else run into this problem?
The software I'm installing is at github.com/ohdsi/cyclops.git, though I'm not sure what that would be important.

Overriding system defaults for C++ compilation flags from R

I'm using RcppEigen to write some C++ functions for my R code, and I'd like to optimize their compilation as much as possible. When I've used Eigen in the past, I've gotten a significant boost from -O3 and -fopenmp. Following Dirk's advice, I edited ~/.R/Makevars so that my Eigen code would be compiled with these flags:
CPPFLAGS=-O3 -fopenmp
This works--when I check what's happening during compilation (ps ax | grep cpp) I see:
27097 pts/6 R+ 0:00 /usr/libexec/gcc/x86_64-redhat-linux/4.4.7/cc1plus -quiet -I/usr/include/R -I/home/sf/R/x86_64-redhat-linux-gnu-library/3.0/Rcpp/include -I/home/sf/R/x86_64-redhat-linux-gnu-library/3.0/RcppEigen/include -D_GNU_SOURCE -D_REENTRANT -DNDEBUG -D_FORTIFY_SOURCE=2 file69b757e053ad.cpp -quiet -dumpbase file69b757e053ad.cpp -m64 -mtune=generic -auxbase-strip file69b757e053ad.o -g -O3 -O2 -Wall -fopenmp -fpic -fexceptions -fstack-protector --param ssp-buffer-size=4 -o -
The flags I wanted are there, -O3 and -fopenmp. But I also see -O2 there, which is presumably the system-wide default (I verified this by removing ~/.R/Makevars and indeed, -O2 is there but -O3 and -fopenmp are not.)
So the question: how do I get rid of the -O2? Or, does it actually matter? The g++ man page says:
-O3 Optimize yet more. -O3 turns on all optimizations specified by -O2 and also
turns on the -finline-functions, -funswitch-loops, -fpredictive-commoning, -fgcse-
after-reload, -ftree-vectorize and -fipa-cp-clone options.
So maybe it's fine to have both -O2 and -O3?
I think you need CXXFLAGS not CPPFLAGS in your ~/.R/Makevars
I set Makevars in the following repo to benchmark various C++ compiler flags in R/Rcpp
https://github.com/jackwasey/optimization-comparison
I use a function from https://github.com/jimhester/covr to do that programmatically, if that's of use to you.
Also, did you see the following? R: C++ Optimization flag when using the inline package