[AMDGPU] Mark AGPR tuple implicit in the first instr of AGPR spills. (#115285)
[llvm-project.git] / llvm / test / Transforms / InstCombine / sink_to_unreachable.ll
blob72aa6dc80df34c68cc5f7739dd5cdcc881db0aba
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine -S < %s | FileCheck %s
4 declare void @use(i32 %x)
5 declare i1 @cond()
7 define void @test_01(i32 %x, i32 %y) {
8 ; CHECK-LABEL: @test_01(
9 ; CHECK-NEXT:  entry:
10 ; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
11 ; CHECK-NEXT:    br i1 [[C2]], label [[EXIT:%.*]], label [[UNREACHED:%.*]]
12 ; CHECK:       unreached:
13 ; CHECK-NEXT:    [[COMPARATOR:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[X]], i32 [[Y]])
14 ; CHECK-NEXT:    call void @use(i32 [[COMPARATOR]])
15 ; CHECK-NEXT:    unreachable
16 ; CHECK:       exit:
17 ; CHECK-NEXT:    ret void
19 entry:
20   %c1 = icmp eq i32 %x, %y
21   %c2 = icmp slt i32 %x, %y
22   %signed = select i1 %c2, i32 -1, i32 1
23   %comparator = select i1 %c1, i32 0, i32 %signed
24   br i1 %c2, label %exit, label %unreached
26 unreached:
27   call void @use(i32 %comparator)
28   unreachable
30 exit:
31   ret void
35 define void @test_02(i32 %x, i32 %y) {
36 ; CHECK-LABEL: @test_02(
37 ; CHECK-NEXT:  entry:
38 ; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
39 ; CHECK-NEXT:    br i1 [[C2]], label [[EXIT:%.*]], label [[MEDIUM:%.*]]
40 ; CHECK:       medium:
41 ; CHECK-NEXT:    [[C3:%.*]] = icmp sgt i32 [[X]], [[Y]]
42 ; CHECK-NEXT:    br i1 [[C3]], label [[EXIT]], label [[UNREACHED:%.*]]
43 ; CHECK:       unreached:
44 ; CHECK-NEXT:    [[COMPARATOR:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[X]], i32 [[Y]])
45 ; CHECK-NEXT:    call void @use(i32 [[COMPARATOR]])
46 ; CHECK-NEXT:    unreachable
47 ; CHECK:       exit:
48 ; CHECK-NEXT:    ret void
50 entry:
51   %c1 = icmp eq i32 %x, %y
52   %c2 = icmp slt i32 %x, %y
53   %signed = select i1 %c2, i32 -1, i32 1
54   %comparator = select i1 %c1, i32 0, i32 %signed
55   br i1 %c2, label %exit, label %medium
57 medium:
58   %c3 = icmp sgt i32 %x, %y
59   br i1 %c3, label %exit, label %unreached
61 unreached:
62   call void @use(i32 %comparator)
63   unreachable
65 exit:
66   ret void
69 define i32 @test_03(i32 %x, i32 %y) {
70 ; CHECK-LABEL: @test_03(
71 ; CHECK-NEXT:  entry:
72 ; CHECK-NEXT:    [[C2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]
73 ; CHECK-NEXT:    br i1 [[C2]], label [[EXIT:%.*]], label [[MEDIUM:%.*]]
74 ; CHECK:       medium:
75 ; CHECK-NEXT:    [[C3:%.*]] = icmp sgt i32 [[X]], [[Y]]
76 ; CHECK-NEXT:    br i1 [[C3]], label [[EXIT]], label [[UNREACHED:%.*]]
77 ; CHECK:       unreached:
78 ; CHECK-NEXT:    [[COMPARATOR:%.*]] = call i32 @llvm.scmp.i32.i32(i32 [[X]], i32 [[Y]])
79 ; CHECK-NEXT:    ret i32 [[COMPARATOR]]
80 ; CHECK:       exit:
81 ; CHECK-NEXT:    ret i32 0
83 entry:
84   %c1 = icmp eq i32 %x, %y
85   %c2 = icmp slt i32 %x, %y
86   %signed = select i1 %c2, i32 -1, i32 1
87   %comparator = select i1 %c1, i32 0, i32 %signed
88   br i1 %c2, label %exit, label %medium
90 medium:
91   %c3 = icmp sgt i32 %x, %y
92   br i1 %c3, label %exit, label %unreached
94 unreached:
95   ret i32 %comparator
97 exit:
98   ret i32 0
101 define i32 @test_04(i32 %x, i1 %c) {
102 ; CHECK-LABEL: @test_04(
103 ; CHECK-NEXT:  bb0:
104 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
105 ; CHECK:       bb1:
106 ; CHECK-NEXT:    br label [[BB3:%.*]]
107 ; CHECK:       bb2:
108 ; CHECK-NEXT:    br label [[BB3]]
109 ; CHECK:       bb3:
110 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[BB1]] ], [ 1, [[BB2]] ]
111 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], 1
112 ; CHECK-NEXT:    [[R:%.*]] = add i32 [[P]], [[A]]
113 ; CHECK-NEXT:    ret i32 [[R]]
115 bb0:
116   %a = add i32 %x, 1
117   br i1 %c, label %bb1, label %bb2
118 bb1:
119   br label %bb3
120 bb2:
121   br label %bb3
122 bb3:
123   %p = phi i32 [0, %bb1], [1, %bb2]
124   %r = add i32 %p, %a
125   ret i32 %r
128 ; Do not sink into a potentially hotter block.
129 define i32 @test_05_neg(i32 %x, i1 %cond) {
130 ; CHECK-LABEL: @test_05_neg(
131 ; CHECK-NEXT:  bb0:
132 ; CHECK-NEXT:    [[A:%.*]] = add i32 [[X:%.*]], 1
133 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
134 ; CHECK:       bb1:
135 ; CHECK-NEXT:    br label [[BB3:%.*]]
136 ; CHECK:       bb2:
137 ; CHECK-NEXT:    [[CALL:%.*]] = call i1 @cond()
138 ; CHECK-NEXT:    br i1 [[CALL]], label [[BB2]], label [[BB3]]
139 ; CHECK:       bb3:
140 ; CHECK-NEXT:    [[P:%.*]] = phi i32 [ 0, [[BB1]] ], [ [[A]], [[BB2]] ]
141 ; CHECK-NEXT:    ret i32 [[P]]
143 bb0:
144   %a = add i32 %x, 1
145   br i1 %cond, label %bb1, label %bb2
146 bb1:
147   br label %bb3
148 bb2:
149   %call = call i1 @cond()
150   br i1 %call, label %bb2, label %bb3
151 bb3:
152   %p = phi i32 [0, %bb1], [%a, %bb2]
153   ret i32 %p
156 define i1 @sink_to_unreachable_ret(i16 %X)  {
157 ; CHECK-LABEL: @sink_to_unreachable_ret(
158 ; CHECK-NEXT:  entry:
159 ; CHECK-NEXT:    br label [[LOOP:%.*]]
160 ; CHECK:       loop:
161 ; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[UNREACH:%.*]]
162 ; CHECK:       unreach:
163 ; CHECK-NEXT:    ret i1 poison
165 entry:
166   br label %loop
168 loop:
169   %p = icmp sgt i16 %X, 16
170   br i1 true, label %loop, label %unreach
172 unreach:
173   ret i1 %p
176 define void @sink_to_unreachable_condbr(i16 %X)  {
177 ; CHECK-LABEL: @sink_to_unreachable_condbr(
178 ; CHECK-NEXT:  entry:
179 ; CHECK-NEXT:    br label [[LOOP:%.*]]
180 ; CHECK:       loop:
181 ; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[UNREACH:%.*]]
182 ; CHECK:       unreach:
183 ; CHECK-NEXT:    br i1 poison, label [[DUMMY:%.*]], label [[LOOP]]
184 ; CHECK:       dummy:
185 ; CHECK-NEXT:    unreachable
187 entry:
188   br label %loop
190 loop:
191   %p = icmp sgt i16 %X, 16
192   br i1 true, label %loop, label %unreach
194 unreach:
195   br i1 %p, label %dummy, label %loop
197 dummy:
198   unreachable
201 define void @sink_to_unreachable_switch(i16 %X)  {
202 ; CHECK-LABEL: @sink_to_unreachable_switch(
203 ; CHECK-NEXT:  entry:
204 ; CHECK-NEXT:    br label [[LOOP:%.*]]
205 ; CHECK:       loop:
206 ; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[UNREACH:%.*]]
207 ; CHECK:       unreach:
208 ; CHECK-NEXT:    switch i16 poison, label [[UNREACH_RET:%.*]] [
209 ; CHECK-NEXT:    ]
210 ; CHECK:       unreach.ret:
211 ; CHECK-NEXT:    unreachable
213 entry:
214   br label %loop
216 loop:
217   %quantum = srem i16 %X, 32
218   br i1 true, label %loop, label %unreach
220 unreach:
221   switch i16 %quantum, label %unreach.ret []
223 unreach.ret:
224   unreachable
227 define void @sink_to_unreachable_indirectbr(ptr %Ptr)  {
228 ; CHECK-LABEL: @sink_to_unreachable_indirectbr(
229 ; CHECK-NEXT:  entry:
230 ; CHECK-NEXT:    br label [[LOOP:%.*]]
231 ; CHECK:       loop:
232 ; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[UNREACH:%.*]]
233 ; CHECK:       unreach:
234 ; CHECK-NEXT:    indirectbr ptr poison, [label %loop]
236 entry:
237   br label %loop
239 loop:
240   %gep = getelementptr inbounds ptr, ptr %Ptr, i16 1
241   br i1 true, label %loop, label %unreach
243 unreach:
244   indirectbr ptr %gep, [label %loop]
247 define void @sink_to_unreachable_invoke(ptr %Ptr) personality ptr @__CxxFrameHandler3 {
248 ; CHECK-LABEL: @sink_to_unreachable_invoke(
249 ; CHECK-NEXT:  entry:
250 ; CHECK-NEXT:    br label [[LOOP:%.*]]
251 ; CHECK:       loop:
252 ; CHECK-NEXT:    br i1 true, label [[LOOP]], label [[UNREACH:%.*]]
253 ; CHECK:       unreach:
254 ; CHECK-NEXT:    invoke void poison(i1 false)
255 ; CHECK-NEXT:            to label [[DUMMY:%.*]] unwind label [[ICATCH_DISPATCH:%.*]]
256 ; CHECK:       unreach2:
257 ; CHECK-NEXT:    invoke void @__CxxFrameHandler3(ptr poison)
258 ; CHECK-NEXT:            to label [[DUMMY]] unwind label [[ICATCH_DISPATCH]]
259 ; CHECK:       unreach3:
260 ; CHECK-NEXT:    [[CLEAN:%.*]] = cleanuppad within none []
261 ; CHECK-NEXT:    invoke void @__CxxFrameHandler3(ptr poison) [ "funclet"(token [[CLEAN]]) ]
262 ; CHECK-NEXT:            to label [[DUMMY]] unwind label [[ICATCH_DISPATCH]]
263 ; CHECK:       icatch.dispatch:
264 ; CHECK-NEXT:    [[TMP1:%.*]] = catchswitch within none [label %icatch] unwind to caller
265 ; CHECK:       icatch:
266 ; CHECK-NEXT:    [[TMP2:%.*]] = catchpad within [[TMP1]] [ptr null, i32 64, ptr null]
267 ; CHECK-NEXT:    catchret from [[TMP2]] to label [[DUMMY2:%.*]]
268 ; CHECK:       dummy:
269 ; CHECK-NEXT:    ret void
270 ; CHECK:       dummy2:
271 ; CHECK-NEXT:    ret void
273 entry:
274   br label %loop
276 loop:
277   %gep = getelementptr inbounds ptr, ptr %Ptr, i16 1
278   br i1 true, label %loop, label %unreach
280 unreach:
281   invoke void %gep(i1 false)
282   to label %dummy unwind label %icatch.dispatch
284 unreach2:
285   invoke void @__CxxFrameHandler3(ptr %gep)
286   to label %dummy unwind label %icatch.dispatch
288 unreach3:
289   %clean = cleanuppad within none []
290   invoke void @__CxxFrameHandler3(ptr %gep) [ "funclet"(token %clean) ]
291   to label %dummy unwind label %icatch.dispatch
293 icatch.dispatch:
294   %tmp1 = catchswitch within none [label %icatch] unwind to caller
296 icatch:
297   %tmp2 = catchpad within %tmp1 [ptr null, i32 64, ptr null]
298   catchret from %tmp2 to label %dummy2
300 dummy:
301   ret void
303 dummy2:
304   ret void
307 declare void @may_throw()
308 declare i32 @__CxxFrameHandler3(...)