This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Simplify PHI node whose type and type of its cond differ
Changes PlannedPublic

Authored by hkmatsumoto on Apr 1 2022, 8:43 AM.

Details

Reviewers
nikic
Summary

Currently LLVM optimizes the code below:

define i8 @foo(i8 %cond) {
entry:
  switch i8 %cond, label %default [
  i8 -1, label %sw.-1
  i8 0, label %sw.0
  i8 1, label %sw.1
  ]

default:
  unreachable

sw.-1:
  br label %merge

sw.0:
  br label %merge

sw.1:
  br label %merge

merge:
  %ret = phi i8 [ 1, %sw.1 ], [ 0, %sw.0 ], [ -1, %sw.-1 ]
  ret i8 %ret
}

to:

define i8 @foo(i8 %cond) {
  ret i8 %cond
}

But once we make @foo return larger types, say i32 it no longer
optimizes. This patch covers such cases.

Fixes https://github.com/llvm/llvm-project/issues/54561

Diff Detail

Event Timeline

hkmatsumoto created this revision.Apr 1 2022, 8:43 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 1 2022, 8:43 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
hkmatsumoto requested review of this revision.Apr 1 2022, 8:43 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 1 2022, 8:43 AM
hkmatsumoto added inline comments.Apr 1 2022, 8:53 AM
llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
1292

Since we now have to store integers of heterogeneous types (e.g. i8 1 vs i32 1), we have to align integer types to the biggest one when accessing to SmallDenseMap. APInt has an API for aligning integers types (sextOrSelf) but not for ConstantInt AFAIK, that's why the type had to be changed.

hkmatsumoto edited the summary of this revision. (Show Details)Apr 1 2022, 8:55 AM
nikic added inline comments.Apr 5 2022, 8:28 AM
llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
1277

All inputs of a phi will have the same size (which is the same as the phi result type width), so computing a max in a loop doesn't make sense to me.

1295

I don't like the fact that this privileges sext. The same optimization is also possible with zext (depending on values used) and in some cases both are possible -- in which case our policy is to prefer zext over sext. I think we should be adding zext and sext support at the same time.

Also, we need a test with switch width wider than phi width rather than the other way around. I think you'll currently assert in that case.

llvm/test/Transforms/InstCombine/pr54561.ll
2

Please drop the sroa run here and only use the phi representation. If you want to do an end-to-end tests, add it to PhaseOrdering (e.g. llvm/test/Transforms/PhaseOrdering/simplifycfg-switch-lowering-vs-correlatedpropagation.ll is related).

hkmatsumoto planned changes to this revision.Apr 25 2022, 8:58 PM

Sorry, currently I don't have the bandwidth to push this forward due to the university assignments. If someone's interested in taking this over, you can do so.