Files
clang-p2996/llvm/test/Transforms/PhaseOrdering/switch-sext.ll
Yingwei Zheng 7c3bcc307a [InstCombine] Fold switch(zext/sext(X)) into switch(X) (#76988)
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%|
2024-01-06 04:30:07 +08:00

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
}