This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Optimize select(freeze(icmp eq/ne x, y), x, y)
ClosedPublic

Authored by aqjune on Aug 7 2020, 9:01 AM.

Details

Summary

This patch adds an optimization that folds select(freeze(icmp eq/ne x, y), x, y)
to x or y.
This was needed to resolve slowdown after D84940 is applied.

I tried to bake this logic into foldSelectInstWithICmp, but it wasn't clear.
This patch conservatively writes the pattern in a separate function,
foldSelectWithFrozenICmp.

The output does not need freeze; https://alive2.llvm.org/ce/z/X49hNE (from @nikic)

Diff Detail

Event Timeline

aqjune created this revision.Aug 7 2020, 9:01 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 7 2020, 9:01 AM
aqjune requested review of this revision.Aug 7 2020, 9:01 AM
nikic added inline comments.Aug 7 2020, 9:48 AM
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
2543

Why is it necessary to freeze the result? Alive accepts this without the freeze as well: https://alive2.llvm.org/ce/z/X49hNE

aqjune added inline comments.Aug 7 2020, 9:53 AM
llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
2543

You are correct - freeze isn't needed.
I'll remove it.

aqjune updated this revision to Diff 283940.Aug 7 2020, 10:09 AM

freeze isn't needed in an output

aqjune edited the summary of this revision. (Show Details)Aug 7 2020, 10:09 AM

Added a missing condition which is that freeze should be used by the select instruction only.

efriedma added inline comments.Aug 7 2020, 11:41 AM
llvm/test/Transforms/InstCombine/select.ll
2588

If I'm understanding correctly, the following transform would be legal:

define void @select_freeze_icmp_multuses(i32 %x, i32 %y) {
  %x.fr = freeze i32 %x
  %y.fr = freeze i32 %y
  %c = icmp ne i32 %x.fr, %y.fr
  call void @use_i1_i32(i1 %c, i32 %x.fr)
  ret void
}

Is this something we should be looking into?

nikic accepted this revision.Aug 7 2020, 1:30 PM

LGTM

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
2540

I agree the one-use check is necessary, but weirdly alive doesn't seem to require it: https://alive2.llvm.org/ce/z/hzwzM_

This revision is now accepted and ready to land.Aug 7 2020, 1:30 PM
spatel added a comment.Aug 7 2020, 2:07 PM

Is there a reason to do this in InstCombine rather than InstSimplify? We are not creating any new instructions.

Is there a reason to do this in InstCombine rather than InstSimplify? We are not creating any new instructions.

Since this transformation takes the number of uses of freeze into consideration, InstCombine is a better place to handle it IMO.

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
2540

Yes, actually there is a bug regarding this pattern: https://github.com/AliveToolkit/alive2/issues/450
I'll have a look at this.

llvm/test/Transforms/InstCombine/select.ll
2588

Yes it is legal, but it did not appear on my codebase.
If it is beneficial to place comparison just before specific operations, we can add it in SelDag.

This revision was landed with ongoing or failed builds.Aug 7 2020, 11:22 PM
This revision was automatically updated to reflect the committed changes.