Issue 152626
Summary `switch (p ? a + C1 : C2)` should eliminate the add
Labels new issue
Assignees
Reporter scottmcm
    Here's some IR I got from rust on LLVM21 when matching on an enum:

```llvm
define noundef range(i8 0, 101) i8 @match5(i8 noundef range(i8 0, 5) %0) unnamed_addr #2 {
start:
  %1 = icmp ne i8 %0, 3
  tail call void @llvm.assume(i1 %1)
  %2 = add nsw i8 %0, -2
 %3 = zext i8 %2 to i64
  %4 = icmp samesign ugt i8 %0, 1
  %5 = add nuw nsw i64 %3, 257         // <--
  %_2 = select i1 %4, i64 %5, i64 258  // <--
  switch i64 %_2, label %bb1 [         // <--
    i64 257, label %bb5
 i64 258, label %bb3
    i64 259, label %bb2
  ]

bb1: ; preds = %start
  unreachable

bb3: ; preds = %start
  %6 = and i8 %0, 1
 br label %bb5

bb2:                                              ; preds = %start
  br label %bb5

bb5: ; preds = %start, %bb2, %bb3
  %_0.sroa.0.0 = phi i8 [ %6, %bb3 ], [ 100, %bb2 ], [ 13, %start ]
  ret i8 %_0.sroa.0.0
}
```

Where on trunk it's a bit improved by not using `i64` <https://llvm.godbolt.org/z/4TqMdTKjW>, but could still be much better.

Most notably, that `%5 = add` is only used in the `select`, which is only used in the `switch`.  As such, it can be removed entirely by adjusting the `switch` arms accordingly: <https://alive2.llvm.org/ce/z/mR6wBE>
```llvm
  %_2 = select i1 %4, i64 %3, i64 1
  switch i64 %_2, label %bb1 [
    i64 0, label %bb5
    i64 1, label %bb3
    i64 2, label %bb2
  ]
```

And that would unblock other optimizations as well, for example having done it `opt` can already remove the `zext` as well, letting the `switch` can stay over `i8` (instead of `i9` or `i64`): <https://llvm.godbolt.org/z/Ybf8zafGE>

---

This is basically a follow-up to #134024 and #134086 and https://github.com/rust-lang/rust/pull/144764, all of which are motivated by improving `match`ing in Rust.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to