
Allow a duplicate basic block with multiple predecessors to the jump table to be simplified, by considering that the same basic block may appear in more switch cases.
202 lines
5.7 KiB
LLVM
202 lines
5.7 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S \
|
|
; RUN: | FileCheck %s -check-prefix=SIMPLIFY-CFG
|
|
|
|
define i32 @switch_all_duplicate_arms(i32 %0, i32 %1, i32 %2, i32 %3) {
|
|
; SIMPLIFY-CFG-LABEL: define i32 @switch_all_duplicate_arms(
|
|
; SIMPLIFY-CFG-SAME: i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]]) {
|
|
; SIMPLIFY-CFG-NEXT: switch i32 [[TMP1]], label %[[BB6:.*]] [
|
|
; SIMPLIFY-CFG-NEXT: i32 0, label %[[BB5:.*]]
|
|
; SIMPLIFY-CFG-NEXT: i32 1, label %[[BB5]]
|
|
; SIMPLIFY-CFG-NEXT: ]
|
|
; SIMPLIFY-CFG: [[BB5]]:
|
|
; SIMPLIFY-CFG-NEXT: br label %[[BB6]]
|
|
; SIMPLIFY-CFG: [[BB6]]:
|
|
; SIMPLIFY-CFG-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP3]], [[TMP4:%.*]] ], [ [[TMP2]], %[[BB5]] ]
|
|
; SIMPLIFY-CFG-NEXT: ret i32 [[TMP8]]
|
|
;
|
|
switch i32 %1, label %7 [
|
|
i32 0, label %5
|
|
i32 1, label %6
|
|
]
|
|
|
|
5:
|
|
br label %7
|
|
|
|
6:
|
|
br label %7
|
|
|
|
7:
|
|
%8 = phi i32 [ %3, %4 ], [ %2, %6 ], [ %2, %5 ]
|
|
ret i32 %8
|
|
}
|
|
|
|
define i32 @switch_some_duplicate_arms(i32 %0, i32 %1, i32 %2, i32 %3, i32 %4) {
|
|
; SIMPLIFY-CFG-LABEL: define i32 @switch_some_duplicate_arms(
|
|
; SIMPLIFY-CFG-SAME: i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]], i32 [[TMP4:%.*]]) {
|
|
; SIMPLIFY-CFG-NEXT: switch i32 [[TMP1]], label %[[BB8:.*]] [
|
|
; SIMPLIFY-CFG-NEXT: i32 0, label %[[BB6:.*]]
|
|
; SIMPLIFY-CFG-NEXT: i32 1, label %[[BB6]]
|
|
; SIMPLIFY-CFG-NEXT: i32 2, label %[[BB7:.*]]
|
|
; SIMPLIFY-CFG-NEXT: ]
|
|
; SIMPLIFY-CFG: [[BB6]]:
|
|
; SIMPLIFY-CFG-NEXT: br label %[[BB8]]
|
|
; SIMPLIFY-CFG: [[BB7]]:
|
|
; SIMPLIFY-CFG-NEXT: br label %[[BB8]]
|
|
; SIMPLIFY-CFG: [[BB8]]:
|
|
; SIMPLIFY-CFG-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP3]], [[TMP5:%.*]] ], [ [[TMP4]], %[[BB7]] ], [ [[TMP2]], %[[BB6]] ]
|
|
; SIMPLIFY-CFG-NEXT: ret i32 [[TMP10]]
|
|
;
|
|
switch i32 %1, label %9 [
|
|
i32 0, label %6
|
|
i32 1, label %7
|
|
i32 2, label %8
|
|
]
|
|
|
|
6:
|
|
br label %9
|
|
|
|
7:
|
|
br label %9
|
|
|
|
8:
|
|
br label %9
|
|
|
|
9:
|
|
%10 = phi i32 [ %3, %5 ], [ %4, %8 ], [ %2, %7 ], [ %2, %6 ]
|
|
ret i32 %10
|
|
}
|
|
|
|
define i32 @switch_duplicate_arms_multipred(i1 %0, i32 %1, i32 %2, i32 %3, i32 %4) {
|
|
; SIMPLIFY-CFG-LABEL: define i32 @switch_duplicate_arms_multipred(
|
|
; SIMPLIFY-CFG-SAME: i1 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]], i32 [[TMP4:%.*]]) {
|
|
; SIMPLIFY-CFG-NEXT: br i1 [[TMP0]], label %[[BB6:.*]], label %[[BB7:.*]]
|
|
; SIMPLIFY-CFG: [[BB6]]:
|
|
; SIMPLIFY-CFG-NEXT: switch i32 [[TMP2]], label %[[BB9:.*]] [
|
|
; SIMPLIFY-CFG-NEXT: i32 0, label %[[BB7]]
|
|
; SIMPLIFY-CFG-NEXT: i32 1, label %[[BB8:.*]]
|
|
; SIMPLIFY-CFG-NEXT: ]
|
|
; SIMPLIFY-CFG: [[BB7]]:
|
|
; SIMPLIFY-CFG-NEXT: br label %[[BB9]]
|
|
; SIMPLIFY-CFG: [[BB8]]:
|
|
; SIMPLIFY-CFG-NEXT: br label %[[BB9]]
|
|
; SIMPLIFY-CFG: [[BB9]]:
|
|
; SIMPLIFY-CFG-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP4]], %[[BB6]] ], [ [[TMP3]], %[[BB8]] ], [ [[TMP3]], %[[BB7]] ]
|
|
; SIMPLIFY-CFG-NEXT: ret i32 [[TMP10]]
|
|
;
|
|
br i1 %0, label %6, label %7
|
|
6:
|
|
switch i32 %2, label %9 [
|
|
i32 0, label %7
|
|
i32 1, label %8
|
|
]
|
|
|
|
7:
|
|
br label %9
|
|
|
|
8:
|
|
br label %9
|
|
|
|
9:
|
|
%10 = phi i32 [ %4, %6 ], [ %3, %8 ], [ %3, %7 ]
|
|
ret i32 %10
|
|
}
|
|
|
|
define i32 @switch_dup_default(i32 %0, i32 %1, i32 %2, i32 %3) {
|
|
; SIMPLIFY-CFG-LABEL: define i32 @switch_dup_default(
|
|
; SIMPLIFY-CFG-SAME: i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[TMP3:%.*]]) {
|
|
; SIMPLIFY-CFG-NEXT: [[COND:%.*]] = icmp eq i32 [[TMP1]], 0
|
|
; SIMPLIFY-CFG-NEXT: [[TMP8:%.*]] = select i1 [[COND]], i32 [[TMP3]], i32 [[TMP2]]
|
|
; SIMPLIFY-CFG-NEXT: ret i32 [[TMP8]]
|
|
;
|
|
switch i32 %1, label %7 [
|
|
i32 0, label %5
|
|
i32 1, label %6
|
|
]
|
|
|
|
5:
|
|
br label %8
|
|
|
|
6:
|
|
br label %8
|
|
|
|
7:
|
|
br label %8
|
|
|
|
8:
|
|
%9 = phi i32 [ %3, %5 ], [ %2, %6 ], [ %2, %7 ]
|
|
ret i32 %9
|
|
}
|
|
|
|
define i32 @switch_dup_exit(i32 %val) {
|
|
; SIMPLIFY-CFG-LABEL: define i32 @switch_dup_exit(
|
|
; SIMPLIFY-CFG-SAME: i32 [[VAL:%.*]]) {
|
|
; SIMPLIFY-CFG-NEXT: [[ENTRY:.*]]:
|
|
; SIMPLIFY-CFG-NEXT: switch i32 [[VAL]], label %[[DEFAULT:.*]] [
|
|
; SIMPLIFY-CFG-NEXT: i32 1, label %[[EXIT:.*]]
|
|
; SIMPLIFY-CFG-NEXT: i32 11, label %[[EXIT]]
|
|
; SIMPLIFY-CFG-NEXT: i32 22, label %[[BB1:.*]]
|
|
; SIMPLIFY-CFG-NEXT: ]
|
|
; SIMPLIFY-CFG: [[BB1]]:
|
|
; SIMPLIFY-CFG-NEXT: br label %[[EXIT]]
|
|
; SIMPLIFY-CFG: [[DEFAULT]]:
|
|
; SIMPLIFY-CFG-NEXT: br label %[[EXIT]]
|
|
; SIMPLIFY-CFG: [[EXIT]]:
|
|
; SIMPLIFY-CFG-NEXT: [[RET:%.*]] = phi i32 [ 0, %[[DEFAULT]] ], [ 3, %[[BB1]] ], [ 1, %[[ENTRY]] ], [ 1, %[[ENTRY]] ]
|
|
; SIMPLIFY-CFG-NEXT: ret i32 [[RET]]
|
|
;
|
|
entry:
|
|
switch i32 %val, label %default [
|
|
i32 1, label %exit
|
|
i32 11, label %exit
|
|
i32 22, label %bb1
|
|
i32 15, label %bb2
|
|
i32 0, label %bb2
|
|
]
|
|
|
|
bb1:
|
|
br label %exit
|
|
|
|
bb2:
|
|
br label %exit
|
|
|
|
default:
|
|
br label %exit
|
|
|
|
exit:
|
|
%ret = phi i32 [ 0, %default ], [ 0, %bb2 ], [ 3, %bb1 ], [ 1, %entry ], [ 1, %entry ]
|
|
ret i32 %ret
|
|
}
|
|
|
|
define i64 @switch_dup_exit_2(i32 %val) {
|
|
; SIMPLIFY-CFG-LABEL: define i64 @switch_dup_exit_2(
|
|
; SIMPLIFY-CFG-SAME: i32 [[VAL:%.*]]) {
|
|
; SIMPLIFY-CFG-NEXT: [[ENTRY:.*:]]
|
|
; SIMPLIFY-CFG-NEXT: [[SWITCH_SELECTCMP_CASE1:%.*]] = icmp eq i32 [[VAL]], 1
|
|
; SIMPLIFY-CFG-NEXT: [[SWITCH_SELECTCMP_CASE2:%.*]] = icmp eq i32 [[VAL]], 11
|
|
; SIMPLIFY-CFG-NEXT: [[SWITCH_SELECTCMP:%.*]] = or i1 [[SWITCH_SELECTCMP_CASE1]], [[SWITCH_SELECTCMP_CASE2]]
|
|
; SIMPLIFY-CFG-NEXT: [[RET:%.*]] = select i1 [[SWITCH_SELECTCMP]], i64 1, i64 0
|
|
; SIMPLIFY-CFG-NEXT: ret i64 [[RET]]
|
|
;
|
|
entry:
|
|
switch i32 %val, label %default [
|
|
i32 1, label %bb2
|
|
i32 11, label %exit
|
|
i32 13, label %bb1
|
|
i32 0, label %bb1
|
|
]
|
|
|
|
bb1:
|
|
br label %exit
|
|
|
|
bb2:
|
|
br label %exit
|
|
|
|
default:
|
|
br label %exit
|
|
|
|
exit:
|
|
%ret = phi i64 [ 0, %default ], [ 0, %bb1 ], [ 1, %entry ], [ 1, %bb2 ]
|
|
ret i64 %ret
|
|
}
|