1 ; RUN: llc -debugify-and-strip-all-safe < %s -stress-early-ifcvt -aarch64-enable-atomic-cfg-tidy=0 | FileCheck %s
2 target triple = "arm64-apple-macosx"
5 define i32 @mm2(ptr nocapture %p, i32 %n) nounwind uwtable readonly ssp {
10 ; Loop body has no branches before the backedge.
13 %max.0 = phi i32 [ 0, %entry ], [ %max.1, %do.cond ]
14 %min.0 = phi i32 [ 0, %entry ], [ %min.1, %do.cond ]
15 %n.addr.0 = phi i32 [ %n, %entry ], [ %dec, %do.cond ]
16 %p.addr.0 = phi ptr [ %p, %entry ], [ %incdec.ptr, %do.cond ]
17 %incdec.ptr = getelementptr inbounds i32, ptr %p.addr.0, i64 1
18 %0 = load i32, ptr %p.addr.0, align 4
19 %cmp = icmp sgt i32 %0, %max.0
20 br i1 %cmp, label %do.cond, label %if.else
23 %cmp1 = icmp slt i32 %0, %min.0
24 %.min.0 = select i1 %cmp1, i32 %0, i32 %min.0
28 %max.1 = phi i32 [ %0, %do.body ], [ %max.0, %if.else ]
29 %min.1 = phi i32 [ %min.0, %do.body ], [ %.min.0, %if.else ]
31 %dec = add i32 %n.addr.0, -1
32 %tobool = icmp eq i32 %dec, 0
33 br i1 %tobool, label %do.end, label %do.body
36 %sub = sub nsw i32 %max.1, %min.1
40 ; CHECK-LABEL: fold_inc_true_32:
41 ; CHECK: {{subs.*wzr,|cmp}} w2, #1
42 ; CHECK-NEXT: csinc w0, w1, w0, eq
44 define i32 @fold_inc_true_32(i32 %x, i32 %y, i32 %c) nounwind ssp {
46 %tobool = icmp eq i32 %c, 1
47 %inc = add nsw i32 %x, 1
48 br i1 %tobool, label %eq_bb, label %done
54 %cond = phi i32 [ %y, %eq_bb ], [ %inc, %entry ]
58 ; CHECK-LABEL: fold_inc_true_64:
59 ; CHECK: {{subs.*xzr,|cmp}} x2, #1
60 ; CHECK-NEXT: csinc x0, x1, x0, eq
62 define i64 @fold_inc_true_64(i64 %x, i64 %y, i64 %c) nounwind ssp {
64 %tobool = icmp eq i64 %c, 1
65 %inc = add nsw i64 %x, 1
66 br i1 %tobool, label %eq_bb, label %done
72 %cond = phi i64 [ %y, %eq_bb ], [ %inc, %entry ]
76 ; CHECK-LABEL: fold_inc_false_32:
77 ; CHECK: {{subs.*wzr,|cmp}} w2, #1
78 ; CHECK-NEXT: csinc w0, w1, w0, ne
80 define i32 @fold_inc_false_32(i32 %x, i32 %y, i32 %c) nounwind ssp {
82 %tobool = icmp eq i32 %c, 1
83 %inc = add nsw i32 %x, 1
84 br i1 %tobool, label %eq_bb, label %done
90 %cond = phi i32 [ %inc, %eq_bb ], [ %y, %entry ]
94 ; CHECK-LABEL: fold_inc_false_64:
95 ; CHECK: {{subs.*xzr,|cmp}} x2, #1
96 ; CHECK-NEXT: csinc x0, x1, x0, ne
98 define i64 @fold_inc_false_64(i64 %x, i64 %y, i64 %c) nounwind ssp {
100 %tobool = icmp eq i64 %c, 1
101 %inc = add nsw i64 %x, 1
102 br i1 %tobool, label %eq_bb, label %done
108 %cond = phi i64 [ %inc, %eq_bb ], [ %y, %entry ]
112 ; CHECK-LABEL: fold_inv_true_32:
113 ; CHECK: {{subs.*wzr,|cmp}} w2, #1
114 ; CHECK-NEXT: csinv w0, w1, w0, eq
116 define i32 @fold_inv_true_32(i32 %x, i32 %y, i32 %c) nounwind ssp {
118 %tobool = icmp eq i32 %c, 1
119 %inv = xor i32 %x, -1
120 br i1 %tobool, label %eq_bb, label %done
126 %cond = phi i32 [ %y, %eq_bb ], [ %inv, %entry ]
130 ; CHECK-LABEL: fold_inv_true_64:
131 ; CHECK: {{subs.*xzr,|cmp}} x2, #1
132 ; CHECK-NEXT: csinv x0, x1, x0, eq
134 define i64 @fold_inv_true_64(i64 %x, i64 %y, i64 %c) nounwind ssp {
136 %tobool = icmp eq i64 %c, 1
137 %inv = xor i64 %x, -1
138 br i1 %tobool, label %eq_bb, label %done
144 %cond = phi i64 [ %y, %eq_bb ], [ %inv, %entry ]
148 ; CHECK-LABEL: fold_inv_false_32:
149 ; CHECK: {{subs.*wzr,|cmp}} w2, #1
150 ; CHECK-NEXT: csinv w0, w1, w0, ne
152 define i32 @fold_inv_false_32(i32 %x, i32 %y, i32 %c) nounwind ssp {
154 %tobool = icmp eq i32 %c, 1
155 %inv = xor i32 %x, -1
156 br i1 %tobool, label %eq_bb, label %done
162 %cond = phi i32 [ %inv, %eq_bb ], [ %y, %entry ]
166 ; CHECK-LABEL: fold_inv_false_64:
167 ; CHECK: {{subs.*xzr,|cmp}} x2, #1
168 ; CHECK-NEXT: csinv x0, x1, x0, ne
170 define i64 @fold_inv_false_64(i64 %x, i64 %y, i64 %c) nounwind ssp {
172 %tobool = icmp eq i64 %c, 1
173 %inv = xor i64 %x, -1
174 br i1 %tobool, label %eq_bb, label %done
180 %cond = phi i64 [ %inv, %eq_bb ], [ %y, %entry ]
184 ; CHECK-LABEL: fold_neg_true_32:
185 ; CHECK: {{subs.*wzr,|cmp}} w2, #1
186 ; CHECK-NEXT: csneg w0, w1, w0, eq
188 define i32 @fold_neg_true_32(i32 %x, i32 %y, i32 %c) nounwind ssp {
190 %tobool = icmp eq i32 %c, 1
191 %neg = sub nsw i32 0, %x
192 br i1 %tobool, label %eq_bb, label %done
198 %cond = phi i32 [ %y, %eq_bb ], [ %neg, %entry ]
202 ; CHECK-LABEL: fold_neg_true_64:
203 ; CHECK: {{subs.*xzr,|cmp}} x2, #1
204 ; CHECK-NEXT: csneg x0, x1, x0, eq
206 define i64 @fold_neg_true_64(i64 %x, i64 %y, i64 %c) nounwind ssp {
208 %tobool = icmp eq i64 %c, 1
209 %neg = sub nsw i64 0, %x
210 br i1 %tobool, label %eq_bb, label %done
216 %cond = phi i64 [ %y, %eq_bb ], [ %neg, %entry ]
220 ; CHECK-LABEL: fold_neg_false_32:
221 ; CHECK: {{subs.*wzr,|cmp}} w2, #1
222 ; CHECK-NEXT: csneg w0, w1, w0, ne
224 define i32 @fold_neg_false_32(i32 %x, i32 %y, i32 %c) nounwind ssp {
226 %tobool = icmp eq i32 %c, 1
227 %neg = sub nsw i32 0, %x
228 br i1 %tobool, label %eq_bb, label %done
234 %cond = phi i32 [ %neg, %eq_bb ], [ %y, %entry ]
238 ; CHECK-LABEL: fold_neg_false_64:
239 ; CHECK: {{subs.*xzr,|cmp}} x2, #1
240 ; CHECK-NEXT: csneg x0, x1, x0, ne
242 define i64 @fold_neg_false_64(i64 %x, i64 %y, i64 %c) nounwind ssp {
244 %tobool = icmp eq i64 %c, 1
245 %neg = sub nsw i64 0, %x
246 br i1 %tobool, label %eq_bb, label %done
252 %cond = phi i64 [ %neg, %eq_bb ], [ %y, %entry ]
257 ; CHECK: {{subs.*wzr,|cmp}} w2, #0
258 ; CHECK-NEXT: csel w0, w1, w0, ne
260 define i32 @cbnz_32(i32 %x, i32 %y, i32 %c) nounwind ssp {
262 %tobool = icmp eq i32 %c, 0
263 br i1 %tobool, label %eq_bb, label %done
269 %cond = phi i32 [ %x, %eq_bb ], [ %y, %entry ]
274 ; CHECK: {{subs.*xzr,|cmp}} x2, #0
275 ; CHECK-NEXT: csel x0, x1, x0, ne
277 define i64 @cbnz_64(i64 %x, i64 %y, i64 %c) nounwind ssp {
279 %tobool = icmp eq i64 %c, 0
280 br i1 %tobool, label %eq_bb, label %done
286 %cond = phi i64 [ %x, %eq_bb ], [ %y, %entry ]
291 ; CHECK: {{subs.*wzr,|cmp}} w2, #0
292 ; CHECK-NEXT: csel w0, w1, w0, eq
294 define i32 @cbz_32(i32 %x, i32 %y, i32 %c) nounwind ssp {
296 %tobool = icmp ne i32 %c, 0
297 br i1 %tobool, label %ne_bb, label %done
303 %cond = phi i32 [ %x, %ne_bb ], [ %y, %entry ]
308 ; CHECK: {{subs.*xzr,|cmp}} x2, #0
309 ; CHECK-NEXT: csel x0, x1, x0, eq
311 define i64 @cbz_64(i64 %x, i64 %y, i64 %c) nounwind ssp {
313 %tobool = icmp ne i64 %c, 0
314 br i1 %tobool, label %ne_bb, label %done
320 %cond = phi i64 [ %x, %ne_bb ], [ %y, %entry ]
325 ; CHECK: {{ands.*xzr,|tst}} w2, #0x80
326 ; CHECK-NEXT: csel w0, w1, w0, ne
328 define i32 @tbnz_32(i32 %x, i32 %y, i32 %c) nounwind ssp {
330 %mask = and i32 %c, 128
331 %tobool = icmp eq i32 %mask, 0
332 br i1 %tobool, label %eq_bb, label %done
338 %cond = phi i32 [ %x, %eq_bb ], [ %y, %entry ]
343 ; CHECK: {{ands.*xzr,|tst}} x2, #0x8000000000000000
344 ; CHECK-NEXT: csel x0, x1, x0, ne
346 define i64 @tbnz_64(i64 %x, i64 %y, i64 %c) nounwind ssp {
348 %mask = and i64 %c, 9223372036854775808
349 %tobool = icmp eq i64 %mask, 0
350 br i1 %tobool, label %eq_bb, label %done
356 %cond = phi i64 [ %x, %eq_bb ], [ %y, %entry ]
361 ; CHECK: {{ands.*xzr,|tst}} w2, #0x80
362 ; CHECK-NEXT: csel w0, w1, w0, eq
364 define i32 @tbz_32(i32 %x, i32 %y, i32 %c) nounwind ssp {
366 %mask = and i32 %c, 128
367 %tobool = icmp ne i32 %mask, 0
368 br i1 %tobool, label %ne_bb, label %done
374 %cond = phi i32 [ %x, %ne_bb ], [ %y, %entry ]
379 ; CHECK: {{ands.*xzr,|tst}} x2, #0x8000000000000000
380 ; CHECK-NEXT: csel x0, x1, x0, eq
382 define i64 @tbz_64(i64 %x, i64 %y, i64 %c) nounwind ssp {
384 %mask = and i64 %c, 9223372036854775808
385 %tobool = icmp ne i64 %mask, 0
386 br i1 %tobool, label %ne_bb, label %done
392 %cond = phi i64 [ %x, %ne_bb ], [ %y, %entry ]
396 ; This function from 175.vpr folds an ADDWri into a CSINC.
397 ; Remember to clear the kill flag on the ADDWri.
398 define i32 @get_ytrack_to_xtracks() nounwind ssp {
403 %x0 = load i32, ptr undef, align 4
404 br i1 undef, label %if.then.i146, label %is_sbox.exit155
407 %add8.i143 = add nsw i32 0, %x0
408 %rem.i144 = srem i32 %add8.i143, %x0
409 %add9.i145 = add i32 %rem.i144, 1
410 br label %is_sbox.exit155
412 is_sbox.exit155: ; preds = %if.then.i146, %for.body
413 %seg_offset.0.i151 = phi i32 [ %add9.i145, %if.then.i146 ], [ undef, %for.body ]
414 %idxprom15.i152 = sext i32 %seg_offset.0.i151 to i64
415 %arrayidx18.i154 = getelementptr inbounds i32, ptr null, i64 %idxprom15.i152
416 %x1 = load i32, ptr %arrayidx18.i154, align 4
417 br i1 undef, label %for.body51, label %for.body
419 for.body51: ; preds = %is_sbox.exit155
420 call fastcc void @get_switch_type(i32 %x1, i32 undef, i16 signext undef, i16 signext undef, ptr undef)
423 declare fastcc void @get_switch_type(i32, i32, i16 signext, i16 signext, ptr nocapture) nounwind ssp