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