[llvm] [SimplifyCFG] Simplify switch with implicit default (PR #95665)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 16 07:16:18 PDT 2024


DianQK wrote:

I'm concerned whether consuming this UB here is reasonable. Consider the following code:
```llvm
define i32 @foo(i32 %x) {
  %c = icmp ult i32 %x, 3
  %v = select i1 %c, i32 %x, i32 1
  switch i32 %v, label %default [
  i32 0, label %case0
  i32 1, label %case1
  i32 2, label %case2
  ]

default:
  unreachable

case0:
  br label %end

case1:
  br label %end

case2:
  br label %end

end:
  %r = phi i32 [ 0, %case0 ], [ 1, %case1 ], [ 2, %case2 ]
  ret i32 %r
}
```

This PR will transform to this code:

```llvm
; -passes=simplifycfg
define i32 @foo(i32 %x) {
end:
  %c = icmp ult i32 %x, 3
  %v = select i1 %c, i32 %x, i32 1
  %switch.selectcmp = icmp eq i32 %x, 2
  %switch.select = select i1 %switch.selectcmp, i32 2, i32 1
  %switch.selectcmp1 = icmp eq i32 %x, 0
  %switch.select2 = select i1 %switch.selectcmp1, i32 0, i32 %switch.select
  ret i32 %switch.select2
}

; -O2
define range(i32 0, 3) i32 @foo(i32 %x) local_unnamed_addr #0 {
end:
  %switch.selectcmp = icmp eq i32 %x, 2
  %switch.select = select i1 %switch.selectcmp, i32 2, i32 1
  %switch.selectcmp1 = icmp eq i32 %x, 0
  %switch.select2 = select i1 %switch.selectcmp1, i32 0, i32 %switch.select
  ret i32 %switch.select2
}
```

But this IR can be transformed to:

```llvm
define i32 @foo(i32 %x) local_unnamed_addr #0 {
end:
  %c = icmp ult i32 %x, 3
  %v = select i1 %c, i32 %x, i32 1
  ret i32 %v
}
```

https://github.com/llvm/llvm-project/pull/95665


More information about the llvm-commits mailing list