Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / Transforms / SimplifyCFG / hoist-common-code-with-unreachable.ll
blob6cda8d188fee0abdc85fd312028bbfc80fee87d6
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes='simplifycfg<hoist-common-insts;no-sink-common-insts>' -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
4 define i1 @common_instr_with_unreachable(i64 %a, i64 %b, i64 %c) {
5 ; CHECK-LABEL: @common_instr_with_unreachable(
6 ; CHECK-NEXT:  start:
7 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
8 ; CHECK-NEXT:    ret i1 [[TMP0]]
10 start:
11   switch i64 %a, label %unreachable [
12   i64 0, label %bb0
13   i64 1, label %bb1
14   i64 2, label %bb2
15   ]
17 unreachable:
18   unreachable
20 bb0:                                              ; preds = %start
21   %0 = icmp eq i64 %b, %c
22   br label %exit
24 bb1:                                              ; preds = %start
25   %1 = icmp eq i64 %b, %c
26   br label %exit
28 bb2:                                              ; preds = %start
29   %2 = icmp eq i64 %b, %c
30   br label %exit
32 exit:                                             ; preds = %bb2, %bb1, %bb0
33   %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
34   ret i1 %result
37 define i1 @common_instr_with_unreachable_2(i64 %a, i64 %b, i64 %c) {
38 ; CHECK-LABEL: @common_instr_with_unreachable_2(
39 ; CHECK-NEXT:  start:
40 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
41 ; CHECK-NEXT:    ret i1 [[TMP0]]
43 start:
44   switch i64 %a, label %bb1 [
45   i64 0, label %bb0
46   i64 1, label %unreachable
47   i64 2, label %bb2
48   ]
50 unreachable:
51   unreachable
53 bb0:                                              ; preds = %start
54   %0 = icmp eq i64 %b, %c
55   br label %exit
57 bb1:                                              ; preds = %start
58   %1 = icmp eq i64 %b, %c
59   br label %exit
61 bb2:                                              ; preds = %start
62   %2 = icmp eq i64 %b, %c
63   br label %exit
65 exit:                                             ; preds = %bb2, %bb1, %bb0
66   %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
67   ret i1 %result
70 define i1 @not_only_unreachable(i64 %a, i64 %b, i64 %c) {
71 ; CHECK-LABEL: @not_only_unreachable(
72 ; CHECK-NEXT:  start:
73 ; CHECK-NEXT:    switch i64 [[A:%.*]], label [[UNREACHABLE:%.*]] [
74 ; CHECK-NEXT:      i64 0, label [[BB0:%.*]]
75 ; CHECK-NEXT:      i64 1, label [[BB1:%.*]]
76 ; CHECK-NEXT:      i64 2, label [[BB2:%.*]]
77 ; CHECK-NEXT:    ]
78 ; CHECK:       unreachable:
79 ; CHECK-NEXT:    call void @no_return()
80 ; CHECK-NEXT:    unreachable
81 ; CHECK:       bb0:
82 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
83 ; CHECK-NEXT:    call void @foo()
84 ; CHECK-NEXT:    br label [[EXIT:%.*]]
85 ; CHECK:       bb1:
86 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[B]], [[C]]
87 ; CHECK-NEXT:    call void @foo()
88 ; CHECK-NEXT:    br label [[EXIT]]
89 ; CHECK:       bb2:
90 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[B]], [[C]]
91 ; CHECK-NEXT:    call void @foo()
92 ; CHECK-NEXT:    br label [[EXIT]]
93 ; CHECK:       exit:
94 ; CHECK-NEXT:    [[RESULT:%.*]] = phi i1 [ [[TMP0]], [[BB0]] ], [ [[TMP1]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
95 ; CHECK-NEXT:    ret i1 [[RESULT]]
97 start:
98   switch i64 %a, label %unreachable [
99   i64 0, label %bb0
100   i64 1, label %bb1
101   i64 2, label %bb2
102   ]
104 unreachable:
105   call void @no_return()
106   unreachable
108 bb0:                                              ; preds = %start
109   %0 = icmp eq i64 %b, %c
110   call void @foo()
111   br label %exit
113 bb1:                                              ; preds = %start
114   %1 = icmp eq i64 %b, %c
115   call void @foo()
116   br label %exit
118 bb2:                                              ; preds = %start
119   %2 = icmp eq i64 %b, %c
120   call void @foo()
121   br label %exit
123 exit:                                             ; preds = %bb2, %bb1, %bb0
124   %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
125   ret i1 %result
128 ; If we can hoist a musttail call,
129 ; we can and have to hoist subsequent bitcast and ret instructions.
130 define ptr @switch_musttail_call(ptr %arg) {
131 ; CHECK-LABEL: @switch_musttail_call(
132 ; CHECK-NEXT:  bb:
133 ; CHECK-NEXT:    [[P0:%.*]] = musttail call ptr @musttail_call(ptr [[ARG:%.*]])
134 ; CHECK-NEXT:    ret ptr [[P0]]
137   %load = load i16, ptr %arg, align 2
138   switch i16 %load, label %unreachable [
139   i16 0, label %bb0
140   i16 1, label %bb1
141   i16 2, label %bb2
142   ]
144 unreachable:
145   unreachable
147 bb0:
148   %p0 = musttail call ptr @musttail_call(ptr %arg)
149   ret ptr %p0
151 bb1:
152   %p1 = musttail call ptr @musttail_call(ptr %arg)
153   ret ptr %p1
155 bb2:
156   %p2 = musttail call ptr @musttail_call(ptr %arg)
157   ret ptr %p2
160 declare void @no_return()
161 declare void @foo()
162 declare ptr @musttail_call(ptr)