Take this toy code (godbolt link):
int somefunc(const int&);
void nothing();
int f(int i) {
i = somefunc(i);
i++;
nothing();
i++;
nothing();
i++;
return i;
}
As can be seen in the disassembly at the link, the compiler reloads i
from the stack 3 times, increments and stores back.
If somefunc
is modified to accept int
by value, this doesn't happen.
(1) Is the optimizer 'afraid' that since somefunc
has access to i
s address, it can indirectly modify it? Can you give an example of well defined code that does that? (remember that const_cast'ing away and modifying is undefined behavior).
(2) Even if that was true, I'd expect that decorating somefunc
with __attribute__((pure))
would stop that pessimization. It doesn't. Why?
Are these llvm missed optimizations?
Edit: If somefunc
returns void, __attribute__((pure))
does kick in as expected:
void somefunc(const int&) __attribute__((pure));
void nothing();
int f(int i) {
somefunc(i);
i++;
nothing();
i++;
nothing();
i++;
return i;
}
Maybe this attribute is sort of half baked (it is rare in practice).