GCC: using -O3 optimization flag with the linker - gcc

I am using g++ 4.8.4 on Linux 14.04 x64. I am compiling my project with -O3 and -flto flags both during compilation and linking i.e., both CFLAGS and LDFLAGS in my Makefile have these options.
I just discovered that the optimized binary behaves differently (i.e., wrongly) when it comes to computations involving float/double. Removing the -O3 from LDFLAGS alone seems to be solving the problem.
I remember reading somewhere that it is generally safe to specify the same set of optimization flags to both the compiler and the linker. Am I wrong in my understanding? Thanks in advance.

While using LTO, compiler during compilation step dumps intermediate code representation (a.k.a. GIMPLE) into special sections of the object files.
Actual compilation to machine codes and optimization happens during linking stage.
So yes, if your code is causing UB or just mis-optimized with -O3 option, it might behave differently (as expected) if you change it to -O0, -Og etc
So you have to find out whether it is your code misbehaving, or actual GCC LTO bug

Related

What is the gcc equivilant for Xlc '-qthreaded' compiler option?

I am currently porting my compiler from AIX XLC compiler to GCC compiler on AIX.
I want to know if there is an GCC equivalent compiler option available for the -qthreaded (XLC).
-pthread is the closest GCC option for use cases where -qthreaded is applied for XL; however, it is not equivalent to the -qthreaded option for IBM XL.
The GCC documentation for -pthread merely states that it sets macros (http://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html#index-pthread) and modifies the link step (http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#index-pthread-1). -qthreaded does not cause _THREAD_SAFE to be defined as a macro, nor does it cause -lpthreads to be present in the link step. GCC's -pthread is more like XL's _r invocations (which does set the macro and modify the link step).
What -qthreaded does is to disable optimizations that are unsafe for multithreaded programs. It appears that, at least historically, -fno-tree-loop-if-convert-stores would at least partially be a GCC equivalent to -qthreaded.

gcc 4.8.1 compiling .c files as c++ in ubuntu 12.04

One of my users is getting an error message when trying to compile a C part of our mixed C/C++ codebase on ubuntu 12.04 with gcc 4.8.1
We have a library in C++ with some C-linkage functions in, and want to compile a C program linking to it. The library is compiled with g++ and builds fine. The c program fails like this:
> gcc -O3 -g -fPIC -I/media/Repo/lcdm/code/cosmosis/ -Wall -Wextra -pedantic -Werror -std=c99 -o c_datablock_t c_datablock_test.c -L . -lcosmosis
cc1plus: error: command line option ‘-std=c99’ is valid for C/ObjC but not for C++ [-Werror]
The program has a lower case .c file suffix, so why does gcc try to compile it as c++ ? We have not seen this on other OSes.
(I know we could kick the problem down the road by removing -Werror or handle this particular file with -x c but I'd like to solve the real problem.)
why does gcc try to compile it as c++
I can think of only two plausible explanations, and they both are end-user's fault.
It could be that the user transferred sources via Windows, and the file is really called C_DATABLOCK_TEST.C, and the user is misleading you.
It could also be that the user overwrote his gcc with g++ (surprisingly many people believe that gcc and g++ are the same thing, but they are not).
To disprove the first possibility, ask the user to execute his build commands under script, and send you resulting typescript.
To disprove the second, ask the user to add -v to the compile command.
This look like GCC Bug 54641, which has been fixed in a later release of GCC. It is only a warning, but your compile flags are causing GCC to treat all warnings as errors.

What flags or environment variables can I pass to Clang to get maximum debugging on both BSD and Linux?

I'm interested in answers, approaches, and ideas out of the box. At a high level, the main page is pretty sparse and they mainly list -g, with one level, suggesting that -O0 is also either very helpful or essential.
But I'm wondering what other clang flags can be given to give maximum debugging. Is there an equivalent to gcc's -ggdb3 which includes some of the source or annotations directly in the object output? Or could there be? Is it possible and helpful to recompile the OS and its original libraries to have debugging (and if so, if I'm using Debian, can I have it write the debugging into the main .deb package instead of putting a separate debugged .deb package which stores debugging data in /usr/lib/debug?)? Will a static build of a binary affect the ability to see a good stacktrace? And is there anything that needs to be done to ensure that addr2line works well? Is it needed to compile all libraries (even glibc) with clang to get the maximum debugging benefit? I note that there is a project to recompile Debian with clang, and otherwise am open to a distribution that does so or otherwise places emphasis on debugging.
On Linux there are also options like an LD_PRELOAD set to /lib/libSegFault.so, or a set of LD_LIBRARY_PATH reassignments to /usr/lib/debug instead of the usual /usr/lib location (including redirecting libc itself to the debugged version). Is there a central place or external sources for answers to this question of how to enhance debuggability of a binary? The bigger mystery is clang, since I see in the long gcc man page that there are various options which can increase debugging (or reduce optimisations), but on the other hand the documentation for clang only shows a smaller set. It's possible that clang will accept more options than given, including gcc flags (which may either translate to a no-op or to more debugging - hard to tell without a canonical source of information).
Also from a package build perspective, since an external package may not respect CFLAGS, I've redirected /usr/bin/strip to be a no-op command that always succeeds, but other ideas on ensuring compliance are suggested (I believe that pkgsrc does a good job of wrapping gcc and the linker in shell scripts - useful to insert mandatory flags). Also there may be various ld options that can be passed to increase debugging of the outputted target. Also, it's quite possible that BSD (including FreeBSD 10, based upon clang) may have a different linking architecture which could make it easier to request and find debugged symbols in the generated libraries and executables.
To take debugging more broadly defined, I've set LD_WARN=yes, LD_DEBUG=unused, SEGFAULT_SIGNALS="all", LD_PRELOAD=.../libSegFault.so (as mentioned above), and LD_BIND_NOW=yes. Also I believe I can prefer that gcc search for libraries in /usr/lib/debug - above the standard search paths using strategic -Bs. Also, using --whole-archive for a static build might ensure that more objects are included in the linked output. There's also ulimit -c unlimited, and on Linux a nice way to differentiate core files like:
sysctl -w kernel.core_pattern="core.%t.SIG-%s.PID-%p.ID-%g-%u.%h.%E"
For gcc I've used and seen flags like: -O0 -fno-omit-frame-pointer -fverbose-asm -ggdb3 -mno-omit-leaf-frame-pointer -mtune=generic -fvar-tracking -D_GLIBCXX_DEBUG=1 -frecord-gcc-switches -femit-class-debug-always -fmath-errno -fno-eliminate-unused-debug-symbols -fno-eliminate-unused-debug-types -fno-merge-debug-strings -mieee-fp -mtune=generic -static-libgcc -fexceptions -fvar-tracking -fbounds-check -rdynamic -UNDEBUG -DDEBUG=1 (-ffreestanding -static-libgcc -pass-exit-codes) -fno-stack-check (since I believe I've read that the latter can interfere with debugging)
Other flags are there for other reasons but the emphasis is to be on maximum debugging. With all or most of the above, it's unclear to what extent clang would support or use there, or whether there are other options.
Clang does not support the -ggdb3 flag, only -g, as you have noticed. If you try to use it, you'll get the message:
clang: warning: argument unused during compilation: '-ggdb3'
so you can run your entire command line through Clang and it will tell you which of those GCC flags it supports and which it does not, some will print warnings, others may error out, but Clang will not silently ignore them. Here are the ones that Clang rejected when I tried your long command: -static-libgcc and -pass-exit-codes.
As pointed out in another SO answer, clang -cc1 --help can be used to list supported compilation flags, where we see the following which may be of interest to you:
-disable-llvm-optzns: Don't run LLVM optimization passes
-fno-elide-constructors: Disable C++ copy constructor elision
-mdisable-fp-elim: Disable frame pointer elimination optimization

How to compile MPI with gcc?

Does anyone know if it is possible to compile MPI with gcc?. I need to use gcc, no mpicc.
mpicc is just a wrapper around certain set of compilers. Most implementations have their mpicc wrappers understand a special option like -showme (Open MPI) or -show (Open MPI, MPICH and derivates) that gives the full list of options that the wrapper passes on to the backend compiler.
For example, in Open MPI, wrappers are C++ programs that read plain text configuration files and build command line options that are further passed on to the compiler. mpicc -showme shows the full list of such options:
$ mpicc -showme
icc
-I/opt/MPI/openmpi-1.5.3/linux/intel/include
-I/opt/MPI/openmpi-1.5.3/linux/intel/include/openmpi
-fexceptions
-pthread
-I/opt/MPI/openmpi-1.5.3/linux/intel/lib
-Wl,-rpath,/opt/MPI/openmpi-1.5.3/linux/intel/lib
-I/opt/MPI/openmpi-1.5.3/linux/intel/lib
-L/opt/MPI/openmpi-1.5.3/linux/intel/lib
-lmpi
-ldl
-Wl,--export-dynamic
-lnsl
-lutil
(it's really a single line that I have split here to improve readability)
It that particular case Intel C Compiler icc is used as the backend compiler but we also have variants that use GCC. You can also get the list of options needed for the comple phase (usually known as CFLAGS) with mpicc -showme:compile:
$ mpicc -showme:compile
-I/opt/MPI/openmpi-1.5.3/linux/intel/include
-I/opt/MPI/openmpi-1.5.3/linux/intel/include/openmpi
-fexceptions
-pthread
-I/opt/MPI/openmpi-1.5.3/linux/intel/lib
as well as the list of options that you need to pass to the linker (known as LDFLAGS) with mpicc -showme:link:
$ mpicc -showme:link
-fexceptions
-pthread
-I/opt/MPI/openmpi-1.5.3/linux/intel/lib
-Wl,-rpath,/opt/MPI/openmpi-1.5.3/linux/intel/lib
-I/opt/MPI/openmpi-1.5.3/linux/intel/lib
-L/opt/MPI/openmpi-1.5.3/linux/intel/lib
-lmpi
-ldl
-Wl,--export-dynamic
-lnsl
-lutil
These could be used, e.g. in a Makefile, like this:
...
CFLAGS += $(shell mpicc -showme:compile)
LDFLAGS += $(shell mpicc -showme:link)
...
As far as I know -showme:compile and -showme:link are specific to Open MPI and other implementations only give the full list of options when called with -show.
I still think it's better to use mpicc directly because if it happens that something in the MPI setup is changed, it will be immediately reflected in the wrapper while you would have to change your build script / Makefile manually (unless you use -showme:compile and -showme:link to obtain the options automatically).
mpicc -compile_info for MPICH.
Yes, you can use gcc actually. But in my case (on Ubuntu) mpicc is just a wrapper of gcc, here is the output of command mpicc -showme:
gcc -I/usr/lib/openmpi/include/openmpi/opal/mca/event/libevent2021/libevent -I/usr/lib/openmpi/include/openmpi/opal/mca/event/libevent2021/libevent/include -I/usr/lib/openmpi/include -I/usr/lib/openmpi/include/openmpi -pthread -Wl,-rpath -Wl,/usr/lib/openmpi/lib -Wl,--enable-new-dtags -L/usr/lib/openmpi/lib -lmpi
While in Open MPI docs:
The Open MPI team strongly recommends that you simply use Open MPI's "wrapper" compilers to compile your MPI applications. That is, instead of using (for example) gcc to compile your program, use mpicc.
We repeat the above statement: the Open MPI Team strongly recommends that the use the wrapper compilers to compile and link MPI applications.
If you find yourself saying, "But I don't want to use wrapper compilers!", please humor us and try them. See if they work for you. Be sure to let us know if they do not work for you.
Many people base their "wrapper compilers suck!" mentality on bad behavior from poorly-implemented wrapper compilers in the mid-1990's. Things are much better these days; wrapper compilers can handle almost any situation, and are far more reliable than you attempting to hard-code the Open MPI-specific compiler and linker flags manually.
That being said, there are some -- very, very few -- situations where using wrapper compilers can be problematic -- such as nesting multiple wrapper compilers of multiple projects. Hence, Open MPI provides a workaround to find out what command line flags you need to compile MPI applications.
Here this answer is useful for you.
For MPICH, according to the mpicc man pages, mpicc -compile_info shows the flags for compiling a program, and mpicc -link_info shows the flags for linking a program.
Yes, you can certainly compile an MPI program without the convenience of the mpicc wrapper. On most implementations mpicc is a shell script (or similar) which sets environment variables, finds and links various libraries, all the sort of stuff that you might otherwise put into a Makefile.
I suggest that you find an instance of the mpicc script and deconstruct it.
mpicc is already using gcc as a backend

How to use gcc and -msoft-float on an i386/x86-64? [duplicate]

Is it (easily) possible to use software floating point on i386 linux without incurring the expense of trapping into the kernel on each call? I've tried -msoft-float, but it seems the normal (ubuntu) C libraries don't have a FP library included:
$ gcc -m32 -msoft-float -lm -o test test.c
/tmp/cc8RXn8F.o: In function `main':
test.c:(.text+0x39): undefined reference to `__muldf3'
collect2: ld returned 1 exit status
It is surprising that gcc doesn't support this natively as the code is clearly available in the source within a directory called soft-fp. It's possible to compile that library manually:
$ svn co svn://gcc.gnu.org/svn/gcc/trunk/libgcc/ libgcc
$ cd libgcc/soft-fp/
$ gcc -c -O2 -msoft-float -m32 -I../config/arm/ -I.. *.c
$ ar -crv libsoft-fp.a *.o
There are a few c files which don't compile due to errors but the majority does compile. After copying libsoft-fp.a into the directory with our source files they now compile fine with -msoft-float:
$ gcc -g -m32 -msoft-float test.c -lsoft-fp -L.
A quick inspection using
$ objdump -D --disassembler-options=intel a.out | less
shows that as expected no x87 floating point instructions are called and the code runs considerably slower as well, by a factor of 8 in my example which uses lots of division.
Note: I would've preferred to compile the soft-float library with
$ gcc -c -O2 -msoft-float -m32 -I../config/i386/ -I.. *.c
but that results in loads of error messages like
adddf3.c: In function '__adddf3':
adddf3.c:46: error: unknown register name 'st(1)' in 'asm'
Seems like the i386 version is not well maintained as st(1) points to one of the x87 registers which are obviously not available when using -msoft-float.
Strangely or luckily the arm version compiles fine on an i386 and seems to work just fine.
Unless you want to bootstrap your entire toolchain by hand, you could start with uclibc toolchain (the i386 version, I imagine) -- soft float is (AFAIK) not directly supported for "native" compilation on debian and derivatives, but it can be used via the "embedded" approach of the uclibc toolchain.
GCC does not support this without some extra libraries. From the 386 documentation:
-msoft-float Generate output containing library calls for floating
point. Warning: the requisite
libraries are not part of GCC.
Normally the facilities of the
machine's usual C compiler are used,
but this can't be done directly in
cross-compilation. You must make your
own arrangements to provide suitable
library functions for
cross-compilation.
On machines where a function returns
floating point results in the 80387
register stack, some floating point
opcodes may be emitted even if
-msoft-float is used
Also, you cannot set -mfpmath=unit to "none", it has to be sse, 387 or both.
However, according to this gnu wiki page, there is fp-soft and ieee. There is also SoftFloat.
(For ARM there is -mfloat-abi=softfp, but it does not seem like something similar is available for 386 SX).
It does not seem like tcc supports software floating point numbers either.
Good luck finding a library that works for you.
G'day,
Unless you're targetting a platform that doesn't have inbuilt FP support, I can't think of a reason why you'd want to emulate FP support.
Doesn't your x386 platform have external FPU support? Pity it's not a x486 with the FPU built in!
In my experience, any soft emulation is bound to be much slower than its hardware equivalent.
That's why I finished up writing a package in Ada to taget the onboard 68k FPU instead of using the soft emulation provided by the compiler manufacturer at the time. They finished up bundling it in their compiler as a matter of fact.
Edit: Just seen your comment below. Hmmm, if you don't need a full suite of FP support is it possible to roll your own for the few math functions you do need? That how the Ada package I mentioned got started.
HTH
cheers,

Resources