This is an archive of the discontinued LLVM Phabricator instance.

[GlobalOpt] Fix debug variance problem in hasOnlyColdCalls
ClosedPublic

Authored by uabelho on Sep 2 2022, 2:51 AM.

Details

Summary

hasOnlyColdCalls skipped over calls to intrinsics, but it did so after
checking the linkage of the called function. This meant that the presence
of a call to a debug intrinsic could affect the outcome of the
optimization.

In my original reproducer (for an out of tree target) it was particularly
interesting, because the actual IR after GlobalOpt was not different with
debug instrinsics present, so -print-after-all printouts didn't show
anything there.

However, without debuginfo, GlobalOpt went further and ran
BlockFrequencyAnalysis and (more importanly) LoopAnalysis, and later on in
the pipeline, instcombine behaved in different ways when LoopInfo was
present.

So a call to a dbg.declare prevented running LoopAnalysis in
GlobalOpt, which later prevented InstCombine from doing an optimization.

The dbg-intrinsic-loopanalysis.ll testcase tries to expose this.

Then I also noted that adding a dbg.declare actually made the existing
testcase colccc_coldsites.ll generate different code, so I modified that
to now test it behaves the same way with and without the dbg.declare.

Diff Detail

Event Timeline

uabelho created this revision.Sep 2 2022, 2:51 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 2 2022, 2:51 AM
uabelho requested review of this revision.Sep 2 2022, 2:51 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 2 2022, 2:51 AM
uabelho added inline comments.Sep 2 2022, 2:55 AM
llvm/lib/Transforms/IPO/GlobalOpt.cpp
1828

These checks were originally added in
https://reviews.llvm.org/D38413
but I suspect that checking if we're dealing with an intrinsic _after_ bailing out (with return false) on non-local linkage actually made the intrinsic check pointless.

So by changing the order I try to restore what I *think* was the purpose of the intrinsic check.

nikic accepted this revision.Sep 2 2022, 2:58 AM

LGTM

However, without debuginfo, GlobalOpt went further and ran

BlockFrequencyAnalysis and (more importanly) LoopAnalysis, and later on in
the pipeline, instcombine behaved in different ways when LoopInfo was
present.

We should really stop doing that, and instead pass in an argument whether InstCombine in a given pipeline position should use LoopInfo or not. Especially with the NewPM "if available" dependencies are a really bad idea, because whether a given analysis is available or not can be quite unpredictable.

This revision is now accepted and ready to land.Sep 2 2022, 2:58 AM
fhahn accepted this revision.Sep 2 2022, 3:02 AM
fhahn added a subscriber: fhahn.

Nice find! LGTM

LGTM

However, without debuginfo, GlobalOpt went further and ran

BlockFrequencyAnalysis and (more importanly) LoopAnalysis, and later on in
the pipeline, instcombine behaved in different ways when LoopInfo was
present.

We should really stop doing that, and instead pass in an argument whether InstCombine in a given pipeline position should use LoopInfo or not. Especially with the NewPM "if available" dependencies are a really bad idea, because whether a given analysis is available or not can be quite unpredictable.

Yes this really had me confused for a while when I tried to track down where the debug variance occured.
Thanks for the super quick review!

This revision was landed with ongoing or failed builds.Sep 2 2022, 3:30 AM
This revision was automatically updated to reflect the committed changes.