This is related to Determine cause of segfault when using -O3? In the question, I'm catching a segfault in a particular function when compiled with -O3
using a particular version of GCC. At -O3
, vectorization instructions are used (at -O2
, they are not used).
I want to wrap a single function in a lower optimization level. According to Switching off optimization for a specific function in GCC 4.2.2, I can do it. However, following the various links in the question and answers, I don't find an answer for "how, exactly, to do it".
How do I mark a single function to use a different optimization level?
Related, I don't want to move this function to a separate file, and then provide a different makefile recipe for it. Doing that opens another can of worms, like applying it to GCC 4.9 only on some platforms.
I know this question is tagged as GCC, but I was just looking into doing this portably and thought the results may come in handy for someone, so:
optimize(X)
function attributeoptnone
and minsize
function attributes (use __has_attribute
to test for support). Since I believe 3.5 it also has #pragma clang optimize on|off
.#pragma intel optimization_level 0
which applies to the next function after the pragma#pragma optimize
, which applies to the first function after the pragma#pragma option_override(funcname, "opt(level,X)")
. Note that 13.1.6 (at least) returns true for __has_attribute(optnone)
but doesn't actually support it.#pragma Onum
, which can be coupled with #pragma push/pop
#pragma opt X (funcname)
#pragma _CRI [no]opt
#pragma FUNCTION_OPTIONS(func,"…")
(C) and #pragma FUNCTION_OPTIONS("…")
(C++)#pragma optimize=...
#pragma optimize time/size/none
So, for GCC/ICC/MSVC/clang/IAR/Pelles and TI C++, you could define a macro that you just put before the function. If you want to support XL, ODS, and TI C you could add the function name as an argument. ARM would require another macro after the function to pop the setting. For Cray AFAIK you can't restore the previous value, only turn optimization off and on.
I think the main reason for this is to disable optimizations for a buggy compiler (or a compiler which exposes bugs in your code), so a unified portable experience probably isn't critical, but hopefully this list helps someone find the right solution for their compiler.
Edit: It's also worth noting that it's relatively common to disable optimizations because code which was working before no longer does. While it's possible that there is a bug in the compiler, it's much more likely that your code was relying on undefined behavior and newer, smarter compilers can and will elide the undefined case. The right answer in situations like this is not to disable optimizations, but instead to fix your code. UBsan on clang and gcc can help a lot here; compile with -fsanitize=undefined
and lots of undefined behavior will start emitting warnings at runtime. Also, try compiling with all the warning options you can enabled; for GCC that means -Wall -Wextra
, for clang throw in -Weverything
.