clang ignoring attribute noinline
Asked Answered
G

1

19

I expected __attribute__((noinline)), when added to a function, to make sure that that function gets emitted. This works with gcc, but clang still seems to inline it.

Here is an example, which you can also open on Godbolt:

namespace {

__attribute__((noinline))
int inner_noinline() {
    return 3;
}

int inner_inline() {
    return 4;
}

int outer() {
    return inner_noinline() + inner_inline();
}

}

int main() {
    return outer();
}

When build with -O3, gcc emits inner_noinline, but not inner_inline:

(anonymous namespace)::inner_noinline():
        mov     eax, 3
        ret
main:
        call    (anonymous namespace)::inner_noinline()
        add     eax, 4
        ret

Clang insists on inlining it:

main: # @main
  mov eax, 7
  ret

If adding a parameter to the functions and letting them perform some trivial work, clang respects the noinline attribute: https://godbolt.org/z/NNSVab

Shouldn't noinline be independent of how complex the function is? What am I missing?

Goodill answered 1/2, 2019 at 14:50 Comment(4)
Does clang support noinline attribute?Koniology
It doesn't have its own category in the list of attributes, but if you search for noinline there, you will find it mentioned several times.Goodill
Also, looking at the version with parameters, if I remove it there, both functions are inlined. So clang seems to at least know it.Goodill
related: github.com/emscripten-core/emscripten/issues/3409Vincents
D
25

__attribute__((noinline)) prevents the compiler from inlining the function. It doesn't prevent it from doing constant folding. In this case, the compiler was able to recognize that there was no need to call inner_noinline, either as an inline insertion or an out-of-line call. It could just replace the function call with the constant 3.

It sounds like you want to use the optnone attribute instead, to prevent the compiler from applying even the most obvious of optimizations (as this one is).

Denature answered 1/2, 2019 at 15:4 Comment(1)
This, together with @YSC's comment, makes sense. It's interesting that clang and gcc seem to have different opinion of what constitutes inlining.Goodill

© 2022 - 2024 — McMap. All rights reserved.