This is an archive of the discontinued LLVM Phabricator instance.

[SimplifyCFG] Propagating case value when turning switch range into icmp
AbandonedPublic

Authored by wwei on Feb 15 2022, 6:14 AM.

Details

Summary

When converting switch range into an icmp, the initial case value may be lost,
which may prevent instructions in successors from being optimized.
For example:

define i64 @demo(i64 %x) {
  entry:
      switch i64 %x, label %bb3 [
          i64 0, label %bb1
          i64 1, label %bb2
      ]
  bb1:
      ret i64 0
  bb2:
      ; this will necessarily be false because %x == 1
      %0 = icmp eq i64 %x, 100
      br i1 %0, label %bb4, label %bb5
  bb3:
      unreachable
  bb4:
      ret i64 200
  bb5:
      ret i64 10
}

Ideally, the result after SimplifyCFG should be as follows:

define i64 @demo(i64 %x) {
  %entry:
    %switch = icmp eq i64 %x, 0
    %. = select i1 %switch, i64 0, i64 10
    ret i64 %.
}

After applying this patch, the case value will be Propagated to the instructions in successors.
issue: SimplifyCFG Need to remove useless comparison after turning switch to icmp

Diff Detail

Event Timeline

wwei created this revision.Feb 15 2022, 6:14 AM
wwei requested review of this revision.Feb 15 2022, 6:14 AM

It doesn't look like something SimplifyCFG should be dealing with.

wwei added a comment.Feb 15 2022, 7:11 AM

It doesn't look like something SimplifyCFG should be dealing with.

@lebedev.ri The reason is that after switch range is converted to icmp, the original case value no longer exists in the IR, and there is no chance for other pass to eliminate this comparison instruction. Look at the IR after simplifycfg:

define i64 @demo(i64 %x) {
entry:
  %switch = icmp ult i64 %x, 1
  %0 = icmp eq i64 %x, 100     ; %x == 1?  no pass can get this result!
  %. = select i1 %0, i64 200, i64 10
  %common.ret.op = select i1 %switch, i64 0, i64 %.
  ret i64 %common.ret.op
}

So It's impossible to remove %0 = icmp eq i64 %x, 100. Maybe simplifycfg has the responsibility to do constant propagation if switch to icmp transformation is performed.
I can't find other solutions at the moment, do you have better suggestions or deas?

lebedev.ri added inline comments.Feb 15 2022, 7:33 AM
llvm/lib/Transforms/Utils/SimplifyCFG.cpp
6577–6580

Perhaps TurnSwitchRangeIntoICmp() simply should have similar treatment to SwitchToLookupTable()?

Will post patch in a sec.

This revision now requires changes to proceed.Feb 15 2022, 8:56 AM

Abandon this?

wwei abandoned this revision.Feb 17 2022, 5:09 PM

Abandon this?

Sure.