This patch folds `switch(zext/sext(X))` into `switch(X)`.
The original motivation of this patch is to optimize a pattern found in
cvc5. For example:
```
%bf.load.i = load i16, ptr %d_kind.i, align 8
%bf.clear.i = and i16 %bf.load.i, 1023
%bf.cast.i = zext nneg i16 %bf.clear.i to i32
switch i32 %bf.cast.i, label %if.else [
i32 335, label %if.then
i32 303, label %if.then
]
if.then: ; preds = %entry, %entry
%d_children.i.i = getelementptr inbounds %"class.cvc5::internal::expr::NodeValue", ptr %0, i64 0, i32 3
%cmp.i.i.i.i.i = icmp eq i16 %bf.clear.i, 1023
%cond.i.i.i.i.i = select i1 %cmp.i.i.i.i.i, i32 -1, i32 %bf.cast.i
```
`%cmp.i.i.i.i.i` always evaluates to false because `%bf.clear.i` can
only be 335 or 303.
Folding `switch i32 %bf.cast.i` to `switch i16 %bf.clear.i` will help
`CVP` to handle this case.
See also
https://github.com/llvm/llvm-project/pull/76928#issuecomment-1877055722.
Compile-time impact:
http://llvm-compile-time-tracker.com/compare.php?from=7954c57124b495fbdc73674d71f2e366e4afe522&to=502b13ed34e561d995ae1f724cf06d20008bd86f&stat=instructions:u
|stage1-O3|stage1-ReleaseThinLTO|stage1-ReleaseLTO-g|stage1-O0-g|stage2-O3|stage2-O0-g|stage2-clang|
|--|--|--|--|--|--|--|
|+0.03%|+0.06%|+0.07%|+0.00%|-0.02%|-0.03%|+0.02%|
49 lines
1.3 KiB
LLVM
49 lines
1.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
|
|
; RUN: opt -S -passes='default<O3>' < %s | FileCheck %s
|
|
|
|
define i8 @test_switch_with_sext_phi(i8 %code) {
|
|
; CHECK-LABEL: define noundef i8 @test_switch_with_sext_phi(
|
|
; CHECK-SAME: i8 [[CODE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: switch i8 [[CODE]], label [[SW_EPILOG:%.*]] [
|
|
; CHECK-NEXT: i8 76, label [[SW_BB3:%.*]]
|
|
; CHECK-NEXT: i8 108, label [[SW_BB2:%.*]]
|
|
; CHECK-NEXT: ]
|
|
; CHECK: sw.bb2:
|
|
; CHECK-NEXT: br label [[SW_EPILOG]]
|
|
; CHECK: sw.bb3:
|
|
; CHECK-NEXT: br label [[SW_EPILOG]]
|
|
; CHECK: sw.epilog:
|
|
; CHECK-NEXT: [[PEP_CODE:%.*]] = phi i8 [ 81, [[SW_BB3]] ], [ 113, [[SW_BB2]] ], [ [[CODE]], [[ENTRY:%.*]] ]
|
|
; CHECK-NEXT: ret i8 [[PEP_CODE]]
|
|
;
|
|
entry:
|
|
%conv = sext i8 %code to i32
|
|
switch i32 %conv, label %sw.default [
|
|
i32 105, label %sw.epilog
|
|
i32 73, label %sw.bb1
|
|
i32 108, label %sw.bb2
|
|
i32 76, label %sw.bb3
|
|
i32 63, label %sw.bb4
|
|
]
|
|
|
|
sw.bb1:
|
|
br label %sw.epilog
|
|
|
|
sw.bb2:
|
|
br label %sw.epilog
|
|
|
|
sw.bb3:
|
|
br label %sw.epilog
|
|
|
|
sw.bb4:
|
|
br label %sw.epilog
|
|
|
|
sw.default:
|
|
br label %sw.epilog
|
|
|
|
sw.epilog:
|
|
%pep_code = phi i8 [ %code, %sw.default ], [ 63, %sw.bb4 ], [ 81, %sw.bb3 ], [ 113, %sw.bb2 ], [ 73, %sw.bb1 ], [ 105, %entry ]
|
|
ret i8 %pep_code
|
|
}
|