blob: 86be3ccea1d80f7a7cdeb855dc48a22d49ec9ac8 [file] [log] [blame]
Simon Pilgrimfc4d4b22016-07-19 13:35:11 +00001; RUN: llc < %s -mtriple=aarch64-linux-gnu | FileCheck %s
Jiangning Liu1a486da2014-09-05 02:55:24 +00002
3; marked as external to prevent possible optimizations
4@a = external global i32
5@b = external global i32
6@c = external global i32
7@d = external global i32
8
9; (a > 10 && b == c) || (a >= 10 && b == d)
10define i32 @combine_gt_ge_10() #0 {
11; CHECK-LABEL: combine_gt_ge_10
12; CHECK: cmp
13; CHECK: b.le
14; CHECK: ret
15; CHECK-NOT: cmp
16; CHECK: b.lt
17entry:
David Blaikiea79ac142015-02-27 21:17:42 +000018 %0 = load i32, i32* @a, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +000019 %cmp = icmp sgt i32 %0, 10
20 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
21
22land.lhs.true: ; preds = %entry
David Blaikiea79ac142015-02-27 21:17:42 +000023 %1 = load i32, i32* @b, align 4
24 %2 = load i32, i32* @c, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +000025 %cmp1 = icmp eq i32 %1, %2
26 br i1 %cmp1, label %return, label %land.lhs.true3
27
28lor.lhs.false: ; preds = %entry
29 %cmp2 = icmp sgt i32 %0, 9
30 br i1 %cmp2, label %land.lhs.true3, label %if.end
31
32land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true
David Blaikiea79ac142015-02-27 21:17:42 +000033 %3 = load i32, i32* @b, align 4
34 %4 = load i32, i32* @d, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +000035 %cmp4 = icmp eq i32 %3, %4
36 br i1 %cmp4, label %return, label %if.end
37
38if.end: ; preds = %land.lhs.true3, %lor.lhs.false
39 br label %return
40
41return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
42 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
43 ret i32 %retval.0
44}
45
46; (a > 5 && b == c) || (a < 5 && b == d)
47define i32 @combine_gt_lt_5() #0 {
48; CHECK-LABEL: combine_gt_lt_5
49; CHECK: cmp
50; CHECK: b.le
51; CHECK: ret
52; CHECK-NOT: cmp
53; CHECK: b.ge
54entry:
David Blaikiea79ac142015-02-27 21:17:42 +000055 %0 = load i32, i32* @a, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +000056 %cmp = icmp sgt i32 %0, 5
57 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
58
59land.lhs.true: ; preds = %entry
David Blaikiea79ac142015-02-27 21:17:42 +000060 %1 = load i32, i32* @b, align 4
61 %2 = load i32, i32* @c, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +000062 %cmp1 = icmp eq i32 %1, %2
63 br i1 %cmp1, label %return, label %if.end
64
65lor.lhs.false: ; preds = %entry
66 %cmp2 = icmp slt i32 %0, 5
67 br i1 %cmp2, label %land.lhs.true3, label %if.end
68
69land.lhs.true3: ; preds = %lor.lhs.false
David Blaikiea79ac142015-02-27 21:17:42 +000070 %3 = load i32, i32* @b, align 4
71 %4 = load i32, i32* @d, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +000072 %cmp4 = icmp eq i32 %3, %4
73 br i1 %cmp4, label %return, label %if.end
74
75if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
76 br label %return
77
78return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
79 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
80 ret i32 %retval.0
81}
82
83; (a < 5 && b == c) || (a <= 5 && b == d)
84define i32 @combine_lt_ge_5() #0 {
85; CHECK-LABEL: combine_lt_ge_5
86; CHECK: cmp
87; CHECK: b.ge
88; CHECK: ret
89; CHECK-NOT: cmp
90; CHECK: b.gt
91entry:
David Blaikiea79ac142015-02-27 21:17:42 +000092 %0 = load i32, i32* @a, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +000093 %cmp = icmp slt i32 %0, 5
94 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
95
96land.lhs.true: ; preds = %entry
David Blaikiea79ac142015-02-27 21:17:42 +000097 %1 = load i32, i32* @b, align 4
98 %2 = load i32, i32* @c, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +000099 %cmp1 = icmp eq i32 %1, %2
100 br i1 %cmp1, label %return, label %land.lhs.true3
101
102lor.lhs.false: ; preds = %entry
103 %cmp2 = icmp slt i32 %0, 6
104 br i1 %cmp2, label %land.lhs.true3, label %if.end
105
106land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true
David Blaikiea79ac142015-02-27 21:17:42 +0000107 %3 = load i32, i32* @b, align 4
108 %4 = load i32, i32* @d, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000109 %cmp4 = icmp eq i32 %3, %4
110 br i1 %cmp4, label %return, label %if.end
111
112if.end: ; preds = %land.lhs.true3, %lor.lhs.false
113 br label %return
114
115return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
116 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
117 ret i32 %retval.0
118}
119
120; (a < 5 && b == c) || (a > 5 && b == d)
121define i32 @combine_lt_gt_5() #0 {
122; CHECK-LABEL: combine_lt_gt_5
123; CHECK: cmp
124; CHECK: b.ge
125; CHECK: ret
126; CHECK-NOT: cmp
127; CHECK: b.le
128entry:
David Blaikiea79ac142015-02-27 21:17:42 +0000129 %0 = load i32, i32* @a, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000130 %cmp = icmp slt i32 %0, 5
131 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
132
133land.lhs.true: ; preds = %entry
David Blaikiea79ac142015-02-27 21:17:42 +0000134 %1 = load i32, i32* @b, align 4
135 %2 = load i32, i32* @c, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000136 %cmp1 = icmp eq i32 %1, %2
137 br i1 %cmp1, label %return, label %if.end
138
139lor.lhs.false: ; preds = %entry
140 %cmp2 = icmp sgt i32 %0, 5
141 br i1 %cmp2, label %land.lhs.true3, label %if.end
142
143land.lhs.true3: ; preds = %lor.lhs.false
David Blaikiea79ac142015-02-27 21:17:42 +0000144 %3 = load i32, i32* @b, align 4
145 %4 = load i32, i32* @d, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000146 %cmp4 = icmp eq i32 %3, %4
147 br i1 %cmp4, label %return, label %if.end
148
149if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
150 br label %return
151
152return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
153 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
154 ret i32 %retval.0
155}
156
157; (a > -5 && b == c) || (a < -5 && b == d)
158define i32 @combine_gt_lt_n5() #0 {
159; CHECK-LABEL: combine_gt_lt_n5
160; CHECK: cmn
161; CHECK: b.le
162; CHECK: ret
163; CHECK-NOT: cmn
164; CHECK: b.ge
165entry:
David Blaikiea79ac142015-02-27 21:17:42 +0000166 %0 = load i32, i32* @a, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000167 %cmp = icmp sgt i32 %0, -5
168 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
169
170land.lhs.true: ; preds = %entry
David Blaikiea79ac142015-02-27 21:17:42 +0000171 %1 = load i32, i32* @b, align 4
172 %2 = load i32, i32* @c, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000173 %cmp1 = icmp eq i32 %1, %2
174 br i1 %cmp1, label %return, label %if.end
175
176lor.lhs.false: ; preds = %entry
177 %cmp2 = icmp slt i32 %0, -5
178 br i1 %cmp2, label %land.lhs.true3, label %if.end
179
180land.lhs.true3: ; preds = %lor.lhs.false
David Blaikiea79ac142015-02-27 21:17:42 +0000181 %3 = load i32, i32* @b, align 4
182 %4 = load i32, i32* @d, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000183 %cmp4 = icmp eq i32 %3, %4
184 br i1 %cmp4, label %return, label %if.end
185
186if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
187 br label %return
188
189return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
190 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
191 ret i32 %retval.0
192}
193
194; (a < -5 && b == c) || (a > -5 && b == d)
195define i32 @combine_lt_gt_n5() #0 {
196; CHECK-LABEL: combine_lt_gt_n5
197; CHECK: cmn
198; CHECK: b.ge
199; CHECK: ret
200; CHECK-NOT: cmn
201; CHECK: b.le
202entry:
David Blaikiea79ac142015-02-27 21:17:42 +0000203 %0 = load i32, i32* @a, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000204 %cmp = icmp slt i32 %0, -5
205 br i1 %cmp, label %land.lhs.true, label %lor.lhs.false
206
207land.lhs.true: ; preds = %entry
David Blaikiea79ac142015-02-27 21:17:42 +0000208 %1 = load i32, i32* @b, align 4
209 %2 = load i32, i32* @c, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000210 %cmp1 = icmp eq i32 %1, %2
211 br i1 %cmp1, label %return, label %if.end
212
213lor.lhs.false: ; preds = %entry
214 %cmp2 = icmp sgt i32 %0, -5
215 br i1 %cmp2, label %land.lhs.true3, label %if.end
216
217land.lhs.true3: ; preds = %lor.lhs.false
David Blaikiea79ac142015-02-27 21:17:42 +0000218 %3 = load i32, i32* @b, align 4
219 %4 = load i32, i32* @d, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000220 %cmp4 = icmp eq i32 %3, %4
221 br i1 %cmp4, label %return, label %if.end
222
223if.end: ; preds = %land.lhs.true3, %lor.lhs.false, %land.lhs.true
224 br label %return
225
226return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
227 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
228 ret i32 %retval.0
229}
230
231%struct.Struct = type { i64, i64 }
232
233@glob = internal unnamed_addr global %struct.Struct* null, align 8
234
235declare %struct.Struct* @Update(%struct.Struct*) #1
236
237; no checks for this case, it just should be processed without errors
238define void @combine_non_adjacent_cmp_br(%struct.Struct* nocapture readonly %hdCall) #0 {
239entry:
David Blaikie79e6c742015-02-27 19:29:02 +0000240 %size = getelementptr inbounds %struct.Struct, %struct.Struct* %hdCall, i64 0, i32 0
David Blaikiea79ac142015-02-27 21:17:42 +0000241 %0 = load i64, i64* %size, align 8
Jiangning Liu1a486da2014-09-05 02:55:24 +0000242 br label %land.rhs
243
244land.rhs:
245 %rp.06 = phi i64 [ %0, %entry ], [ %sub, %while.body ]
David Blaikiea79ac142015-02-27 21:17:42 +0000246 %1 = load i64, i64* inttoptr (i64 24 to i64*), align 8
Jiangning Liu1a486da2014-09-05 02:55:24 +0000247 %cmp2 = icmp sgt i64 %1, 0
248 br i1 %cmp2, label %while.body, label %while.end
249
250while.body:
David Blaikiea79ac142015-02-27 21:17:42 +0000251 %2 = load %struct.Struct*, %struct.Struct** @glob, align 8
Jiangning Liu1a486da2014-09-05 02:55:24 +0000252 %call = tail call %struct.Struct* @Update(%struct.Struct* %2) #2
253 %sub = add nsw i64 %rp.06, -2
254 %cmp = icmp slt i64 %0, %rp.06
255 br i1 %cmp, label %land.rhs, label %while.end
256
257while.end:
258 ret void
259}
260
261; undefined external to prevent possible optimizations
262declare void @do_something() #1
263
264define i32 @do_nothing_if_resultant_opcodes_would_differ() #0 {
265; CHECK-LABEL: do_nothing_if_resultant_opcodes_would_differ
266; CHECK: cmn
267; CHECK: b.gt
268; CHECK: cmp
269; CHECK: b.gt
270entry:
David Blaikiea79ac142015-02-27 21:17:42 +0000271 %0 = load i32, i32* @a, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000272 %cmp4 = icmp slt i32 %0, -1
273 br i1 %cmp4, label %while.body.preheader, label %while.end
274
275while.body.preheader: ; preds = %entry
276 br label %while.body
277
278while.body: ; preds = %while.body, %while.body.preheader
279 %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ]
280 tail call void @do_something() #2
281 %inc = add nsw i32 %i.05, 1
282 %cmp = icmp slt i32 %i.05, 0
283 br i1 %cmp, label %while.body, label %while.cond.while.end_crit_edge
284
285while.cond.while.end_crit_edge: ; preds = %while.body
David Blaikiea79ac142015-02-27 21:17:42 +0000286 %.pre = load i32, i32* @a, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000287 br label %while.end
288
289while.end: ; preds = %while.cond.while.end_crit_edge, %entry
290 %1 = phi i32 [ %.pre, %while.cond.while.end_crit_edge ], [ %0, %entry ]
291 %cmp1 = icmp slt i32 %1, 2
292 br i1 %cmp1, label %land.lhs.true, label %if.end
293
294land.lhs.true: ; preds = %while.end
David Blaikiea79ac142015-02-27 21:17:42 +0000295 %2 = load i32, i32* @b, align 4
296 %3 = load i32, i32* @d, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000297 %cmp2 = icmp eq i32 %2, %3
298 br i1 %cmp2, label %return, label %if.end
299
300if.end: ; preds = %land.lhs.true, %while.end
301 br label %return
302
303return: ; preds = %if.end, %land.lhs.true
304 %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
305 ret i32 %retval.0
306}
307
308define i32 @do_nothing_if_compares_can_not_be_adjusted_to_each_other() #0 {
309; CHECK-LABEL: do_nothing_if_compares_can_not_be_adjusted_to_each_other
310; CHECK: cmp
311; CHECK: b.gt
312; CHECK: cmn
313; CHECK: b.lt
314entry:
David Blaikiea79ac142015-02-27 21:17:42 +0000315 %0 = load i32, i32* @a, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000316 %cmp4 = icmp slt i32 %0, 1
317 br i1 %cmp4, label %while.body.preheader, label %while.end
318
319while.body.preheader: ; preds = %entry
320 br label %while.body
321
322while.body: ; preds = %while.body, %while.body.preheader
323 %i.05 = phi i32 [ %inc, %while.body ], [ %0, %while.body.preheader ]
324 tail call void @do_something() #2
325 %inc = add nsw i32 %i.05, 1
326 %cmp = icmp slt i32 %i.05, 0
327 br i1 %cmp, label %while.body, label %while.end.loopexit
328
329while.end.loopexit: ; preds = %while.body
330 br label %while.end
331
332while.end: ; preds = %while.end.loopexit, %entry
David Blaikiea79ac142015-02-27 21:17:42 +0000333 %1 = load i32, i32* @c, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000334 %cmp1 = icmp sgt i32 %1, -3
335 br i1 %cmp1, label %land.lhs.true, label %if.end
336
337land.lhs.true: ; preds = %while.end
David Blaikiea79ac142015-02-27 21:17:42 +0000338 %2 = load i32, i32* @b, align 4
339 %3 = load i32, i32* @d, align 4
Jiangning Liu1a486da2014-09-05 02:55:24 +0000340 %cmp2 = icmp eq i32 %2, %3
341 br i1 %cmp2, label %return, label %if.end
342
343if.end: ; preds = %land.lhs.true, %while.end
344 br label %return
345
346return: ; preds = %if.end, %land.lhs.true
347 %retval.0 = phi i32 [ 0, %if.end ], [ 123, %land.lhs.true ]
348 ret i32 %retval.0
349}
Chad Rosiera675e552014-10-31 15:17:36 +0000350
351; Test in the following case, we don't hit 'cmp' and trigger a false positive
352; cmp w19, #0
353; cinc w0, w19, gt
354; ...
355; fcmp d8, #0.0
356; b.gt .LBB0_5
357
358define i32 @fcmpri(i32 %argc, i8** nocapture readonly %argv) {
359
360; CHECK-LABEL: fcmpri:
361; CHECK: cmp w0, #2
362; CHECK: b.lt .LBB9_3
363; CHECK-NOT: cmp w0, #1
364; CHECK-NOT: b.le .LBB9_3
365
366; CHECK-LABEL-DAG: .LBB9_3
367; CHECK: cmp w19, #0
368; CHECK: fcmp d8, #0.0
Chad Rosiera675e552014-10-31 15:17:36 +0000369; CHECK-NOT: cmp w19, #1
370; CHECK-NOT: b.ge .LBB9_5
371
372entry:
373 %cmp = icmp sgt i32 %argc, 1
374 br i1 %cmp, label %land.lhs.true, label %if.end
375
376land.lhs.true: ; preds = %entry
David Blaikie79e6c742015-02-27 19:29:02 +0000377 %arrayidx = getelementptr inbounds i8*, i8** %argv, i64 1
David Blaikiea79ac142015-02-27 21:17:42 +0000378 %0 = load i8*, i8** %arrayidx, align 8
Chad Rosiera675e552014-10-31 15:17:36 +0000379 %cmp1 = icmp eq i8* %0, null
380 br i1 %cmp1, label %if.end, label %return
381
382if.end: ; preds = %land.lhs.true, %entry
383 %call = call i32 @zoo(i32 1)
384 %call2 = call double @yoo(i32 -1)
385 %cmp4 = icmp sgt i32 %call, 0
386 %add = zext i1 %cmp4 to i32
387 %cond = add nsw i32 %add, %call
388 %call7 = call i32 @xoo(i32 %cond, i32 2)
389 %cmp9 = fcmp ogt double %call2, 0.000000e+00
390 br i1 %cmp9, label %cond.end14, label %cond.false12
391
392cond.false12: ; preds = %if.end
393 %sub = fadd fast double %call2, -1.000000e+00
394 br label %cond.end14
395
396cond.end14: ; preds = %if.end, %cond.false12
397 %cond15 = phi double [ %sub, %cond.false12 ], [ %call2, %if.end ]
398 %call16 = call i32 @woo(double %cond15, double -2.000000e+00)
399 br label %return
400
401return: ; preds = %land.lhs.true, %cond.end14
402 %retval.0 = phi i32 [ 4, %cond.end14 ], [ 3, %land.lhs.true ]
403 ret i32 %retval.0
404}
405
Tim Northover17ae83a2015-07-28 22:42:32 +0000406define void @cmp_shifted(i32 %in, i32 %lhs, i32 %rhs) {
407; CHECK-LABEL: cmp_shifted:
Tim Northover17ae83a2015-07-28 22:42:32 +0000408; CHECK: cmp w0, #2, lsl #12
Chad Rosier25cfb7d2016-05-05 15:39:18 +0000409; [...]
410; CHECK: cmp w0, #1
Tim Northover17ae83a2015-07-28 22:42:32 +0000411
Chad Rosier25cfb7d2016-05-05 15:39:18 +0000412 %tst_low = icmp sgt i32 %in, 8191
Tim Northover17ae83a2015-07-28 22:42:32 +0000413 br i1 %tst_low, label %true, label %false
414
415true:
416 call i32 @zoo(i32 128)
417 ret void
418
419false:
Chad Rosier25cfb7d2016-05-05 15:39:18 +0000420 %tst = icmp sgt i32 %in, 0
Tim Northover17ae83a2015-07-28 22:42:32 +0000421 br i1 %tst, label %truer, label %falser
422
423truer:
424 call i32 @zoo(i32 42)
425 ret void
426
427falser:
428 call i32 @zoo(i32 1)
429 ret void
430}
431
Weiming Zhao038393b2016-01-15 00:06:58 +0000432define i32 @combine_gt_ge_sel(i64 %v, i64* %p) #0 {
433; CHECK-LABEL: combine_gt_ge_sel
434; CHECK: ldr [[reg1:w[0-9]*]],
435; CHECK: cmp [[reg1]], #0
436; CHECK: csel {{.*}}, gt
437entry:
438 %0 = load i32, i32* @a, align 4
439 %cmp = icmp sgt i32 %0, 0
440 %m = select i1 %cmp, i64 %v, i64 0
441 store i64 %m, i64* %p
442 br i1 %cmp, label %lor.lhs.false, label %land.lhs.true
443
444land.lhs.true: ; preds = %entry
445 %1 = load i32, i32* @b, align 4
446 %2 = load i32, i32* @c, align 4
447 %cmp1 = icmp eq i32 %1, %2
448 br i1 %cmp1, label %return, label %land.lhs.true3
449
450lor.lhs.false: ; preds = %entry
451 %cmp2 = icmp sgt i32 %0, 1
452 br i1 %cmp2, label %land.lhs.true3, label %if.end
453
454land.lhs.true3: ; preds = %lor.lhs.false, %land.lhs.true
455 %3 = load i32, i32* @b, align 4
456 %4 = load i32, i32* @d, align 4
457 %cmp4 = icmp eq i32 %3, %4
458 br i1 %cmp4, label %return, label %if.end
459
460if.end: ; preds = %land.lhs.true3, %lor.lhs.false
461 br label %return
462
463return: ; preds = %if.end, %land.lhs.true3, %land.lhs.true
464 %retval.0 = phi i32 [ 0, %if.end ], [ 1, %land.lhs.true3 ], [ 1, %land.lhs.true ]
465 ret i32 %retval.0
466}
467
Chad Rosiera675e552014-10-31 15:17:36 +0000468declare i32 @zoo(i32)
469
470declare double @yoo(i32)
471
472declare i32 @xoo(i32, i32)
473
474declare i32 @woo(double, double)