Misleading optimization remark caused by lambda?

(godbolt link: Compiler Explorer)

This code, in the upper half of the godbolt link:

#include <iostream>
void f();
void g(int arg) {
    [&]() {
        f();
        std::cout <<  arg; // <-- opt remark: load of arg not eliminated because it is clobbered by the f() call
    }();
}

emits the said remark on the line std::cout << arg. The remark seems false: not only does inspection of disassembly show that arg is in fact not re-loaded, if we stop wrapping the calls in a lambda (bottom half of the godbolt link) the generated assembly is identical and the opt remark is gone:

#include <iostream>
void f();
void g(int arg) {
        f();
        std::cout <<  arg; // only a remark about not inlining std::cout<<
}

Is this opt-remark a bug?

The remark is not necessarily incorrect unfortunately. AFAICT this is GVN telling us that it could not remove the load. What is likely happening is that a pass later on is able to remove the load, but at the moment there’s no way to ‘invalidate’ the earlier remark.

In general, the GVN remarks can be very noisy and enabling them unconditionally may not provide the best user experience.

It would be good to improve the situation and I think this invalidation has been discussed elsewhere on Discourse, but so far work in that direction hasn’t started yet.

1 Like

@fhahn thanks, I suspected as much. What do you mean by ‘enabling them [gvn remarks] unconditionally’? Is there a way to enable some subset of them?

By default, -fsave-optimization-record will save all remarks from all passes. User tools like opt-viewer are then able to filter remarks.

There’s also a Clang option to do the filtering before emitting remarks in Clang: -foptimization-record-passes= (more details here Clang Compiler User’s Manual — Clang 16.0.0git documentation)

Here’s an example use Compiler Explorer

Another idea that has been floating around is to only enable remarks by default that have high signal-to-noise ratio and in general have very few false positives. For example, loop-vectorization remarks should have very few false positives. Others include the asm-printer and lower-matrix-intrinsics remarks.

I’d consider remarks from passes like GVN very low signal-to-noise and likely to include false positives.

@fhann Thanks to your comment I discovered you can select specific passes within the optimization view in compiler explorer with -foptimization-record-passes. Nice!

In my experience the remarks that are potentially actionable to developers come from gvn or licm. I wasn’t aware they’re known to be noisy, that’s rather unfortunate.