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 is 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).