This is an archive of the discontinued LLVM Phabricator instance.

[LICM] Hoist widenable condition when it's the only non-invariant operand of its user
Needs ReviewPublic

Authored by aleksandr.popov on Apr 27 2023, 12:22 PM.

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald TranscriptApr 27 2023, 12:22 PM
aleksandr.popov requested review of this revision.Apr 27 2023, 12:22 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 27 2023, 12:22 PM
skatkov added inline comments.Apr 27 2023, 7:25 PM
llvm/lib/Transforms/Scalar/LICM.cpp
1243

Why do you need to iterate over uses instead of users?

mkazantsev added inline comments.Apr 27 2023, 9:39 PM
llvm/lib/Transforms/Scalar/LICM.cpp
1240

Imagine case:
Test 1:

c1 = load // can be hoisted
wc = call widenable_condition()
and = c1 & wc

Test 2:

wc = call widenable_condition()
c1 = load // can be hoisted
and = c1 & wc

If c1 is processed first and gets hoisted, then you also hoist wc and then and. But if wc is processed first, c1 is not yet made invariant, then you don't hoist neither wc nor and. I think you can construct a test demonstrating that by just putting wc ahead of c1.

The right solution would be to handle this when processing the user of wc (in this case it is and). If all of instruction's operands that are not loop-invariant are single-use widenable conditions, then all of them can be hoisted together with the and. In this case, you have a guarantee that everything that is not wc and that is hoistable has already been hoisted.