This is an archive of the discontinued LLVM Phabricator instance.

[NARY] Don't optimize min/max if there are side uses
ClosedPublic

Authored by ebrevnov on Apr 9 2021, 3:22 AM.

Details

Summary

Say we have
%1=min(%a,%b)
%2=min(%b,%c)
%3=min(%2,%a)

The optimization will try to reassociate the later one so that we can rewrite it to %3=min(%1, %c) and remove %2.
But if %2 has another uses outside of %3 then we can't remove %2 and end up with:

%1=min(%a,%b)
%2=min(%b,%c)
%3=min(%1, %c)

This doesn't harm by itself except it is not profitable and changes IR for no good reason.
What is bad it triggers next iteration which finds out that optimization is applicable to %2 and %3 and generates:

%1=min(%a,%b)
%2=min(%b,%c)
%3=min(%1,%c)
%4=min(%2,%a)

and so on...

The solution is to prevent optimization in the first place if intermediate result (%2) has side uses and
known to be not removed.

Diff Detail

Event Timeline

ebrevnov created this revision.Apr 9 2021, 3:22 AM
ebrevnov requested review of this revision.Apr 9 2021, 3:22 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 9 2021, 3:22 AM
mkazantsev accepted this revision.Apr 11 2021, 9:37 PM

LGTM

llvm/test/Transforms/NaryReassociate/nary-req.ll
5

Please precommit the test with current output and put your patch on top of it so that it clearly shows the difference.

This revision is now accepted and ready to land.Apr 11 2021, 9:37 PM
This revision was landed with ongoing or failed builds.Apr 11 2021, 10:45 PM
This revision was automatically updated to reflect the committed changes.
vdmitrie added inline comments.
llvm/lib/Transforms/Scalar/NaryReassociate.cpp
595

Just a hint:
/ This is a linear time operation. Use hasOneUse, hasNUses, or
/ hasNUsesOrMore to check for specific values.

Thanks for noting. Fixed.