1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64-linux-gnu -verify-machineinstrs -o - %s | FileCheck %s
3
4%struct_type = type { [10000 x i32], i32, i32 }
5
6define void @test1(%struct_type** %s, i32 %n) {
7; CHECK-LABEL: test1:
8; CHECK:       // %bb.0: // %entry
9; CHECK-NEXT:    ldr x9, [x0]
10; CHECK-NEXT:    mov w10, #40000
11; CHECK-NEXT:    mov w8, wzr
12; CHECK-NEXT:    add x9, x9, x10
13; CHECK-NEXT:    cmp w8, w1
14; CHECK-NEXT:    b.ge .LBB0_2
15; CHECK-NEXT:  .LBB0_1: // %while_body
16; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
17; CHECK-NEXT:    add w10, w8, #1
18; CHECK-NEXT:    stp w10, w8, [x9]
19; CHECK-NEXT:    mov w8, w10
20; CHECK-NEXT:    cmp w8, w1
21; CHECK-NEXT:    b.lt .LBB0_1
22; CHECK-NEXT:  .LBB0_2: // %while_end
23; CHECK-NEXT:    ret
24entry:
25  %struct = load %struct_type*, %struct_type** %s
26  br label %while_cond
27
28while_cond:
29  %phi = phi i32 [ 0, %entry ], [ %i, %while_body ]
30  %gep0 = getelementptr %struct_type, %struct_type* %struct, i64 0, i32 1
31  %gep1 = getelementptr %struct_type, %struct_type* %struct, i64 0, i32 2
32  %cmp = icmp slt i32 %phi, %n
33  br i1 %cmp, label %while_body, label %while_end
34
35while_body:
36  %i = add i32 %phi, 1
37  store i32 %i, i32* %gep0
38  store i32 %phi, i32* %gep1
39  br label %while_cond
40
41while_end:
42  ret void
43}
44
45define void @test2(%struct_type* %struct, i32 %n) {
46; CHECK-LABEL: test2:
47; CHECK:       // %bb.0: // %entry
48; CHECK-NEXT:    cbz x0, .LBB1_3
49; CHECK-NEXT:  // %bb.1: // %while_cond.preheader
50; CHECK-NEXT:    mov w9, #40000
51; CHECK-NEXT:    mov w8, wzr
52; CHECK-NEXT:    add x9, x0, x9
53; CHECK-NEXT:    cmp w8, w1
54; CHECK-NEXT:    b.ge .LBB1_3
55; CHECK-NEXT:  .LBB1_2: // %while_body
56; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
57; CHECK-NEXT:    add w10, w8, #1
58; CHECK-NEXT:    stp w10, w8, [x9]
59; CHECK-NEXT:    mov w8, w10
60; CHECK-NEXT:    cmp w8, w1
61; CHECK-NEXT:    b.lt .LBB1_2
62; CHECK-NEXT:  .LBB1_3: // %while_end
63; CHECK-NEXT:    ret
64entry:
65  %cmp = icmp eq %struct_type* %struct, null
66  br i1 %cmp, label %while_end, label %while_cond
67
68while_cond:
69  %phi = phi i32 [ 0, %entry ], [ %i, %while_body ]
70  %gep0 = getelementptr %struct_type, %struct_type* %struct, i64 0, i32 1
71  %gep1 = getelementptr %struct_type, %struct_type* %struct, i64 0, i32 2
72  %cmp1 = icmp slt i32 %phi, %n
73  br i1 %cmp1, label %while_body, label %while_end
74
75while_body:
76  %i = add i32 %phi, 1
77  store i32 %i, i32* %gep0
78  store i32 %phi, i32* %gep1
79  br label %while_cond
80
81while_end:
82  ret void
83}
84
85define void @test3(%struct_type* %s1, %struct_type* %s2, i1 %cond, i32 %n) {
86; CHECK-LABEL: test3:
87; CHECK:       // %bb.0: // %entry
88; CHECK-NEXT:    tst w2, #0x1
89; CHECK-NEXT:    csel x9, x1, x0, ne
90; CHECK-NEXT:    cbz x9, .LBB2_3
91; CHECK-NEXT:  // %bb.1: // %while_cond.preheader
92; CHECK-NEXT:    mov w10, #40000
93; CHECK-NEXT:    mov w8, wzr
94; CHECK-NEXT:    add x9, x9, x10
95; CHECK-NEXT:    cmp w8, w3
96; CHECK-NEXT:    b.ge .LBB2_3
97; CHECK-NEXT:  .LBB2_2: // %while_body
98; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
99; CHECK-NEXT:    add w10, w8, #1
100; CHECK-NEXT:    stp w10, w8, [x9]
101; CHECK-NEXT:    mov w8, w10
102; CHECK-NEXT:    cmp w8, w3
103; CHECK-NEXT:    b.lt .LBB2_2
104; CHECK-NEXT:  .LBB2_3: // %while_end
105; CHECK-NEXT:    ret
106entry:
107  br i1 %cond, label %if_true, label %if_end
108
109if_true:
110  br label %if_end
111
112if_end:
113  %struct = phi %struct_type* [ %s1, %entry ], [ %s2, %if_true ]
114  %cmp = icmp eq %struct_type* %struct, null
115  br i1 %cmp, label %while_end, label %while_cond
116
117while_cond:
118  %phi = phi i32 [ 0, %if_end ], [ %i, %while_body ]
119  %gep0 = getelementptr %struct_type, %struct_type* %struct, i64 0, i32 1
120  %gep1 = getelementptr %struct_type, %struct_type* %struct, i64 0, i32 2
121  %cmp1 = icmp slt i32 %phi, %n
122  br i1 %cmp1, label %while_body, label %while_end
123
124while_body:
125  %i = add i32 %phi, 1
126  store i32 %i, i32* %gep0
127  store i32 %phi, i32* %gep1
128  br label %while_cond
129
130while_end:
131  ret void
132}
133
134declare %struct_type* @foo()
135declare void @foo2()
136
137define void @test4(i32 %n) personality i32 (...)* @__FrameHandler {
138; CHECK-LABEL: test4:
139; CHECK:       .Lfunc_begin0:
140; CHECK-NEXT:    .cfi_startproc
141; CHECK-NEXT:    .cfi_personality 0, __FrameHandler
142; CHECK-NEXT:    .cfi_lsda 0, .Lexception0
143; CHECK-NEXT:  // %bb.0: // %entry
144; CHECK-NEXT:    stp x30, x21, [sp, #-32]! // 16-byte Folded Spill
145; CHECK-NEXT:    .cfi_def_cfa_offset 32
146; CHECK-NEXT:    stp x20, x19, [sp, #16] // 16-byte Folded Spill
147; CHECK-NEXT:    .cfi_offset w19, -8
148; CHECK-NEXT:    .cfi_offset w20, -16
149; CHECK-NEXT:    .cfi_offset w21, -24
150; CHECK-NEXT:    .cfi_offset w30, -32
151; CHECK-NEXT:    mov w19, w0
152; CHECK-NEXT:    mov w20, wzr
153; CHECK-NEXT:    mov w21, #40000
154; CHECK-NEXT:  .LBB3_1: // %while_cond
155; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
156; CHECK-NEXT:  .Ltmp0:
157; CHECK-NEXT:    bl foo
158; CHECK-NEXT:  .Ltmp1:
159; CHECK-NEXT:  // %bb.2: // %while_cond_x.split
160; CHECK-NEXT:    // in Loop: Header=BB3_1 Depth=1
161; CHECK-NEXT:    add x8, x0, x21
162; CHECK-NEXT:    cmp w20, w19
163; CHECK-NEXT:    str wzr, [x8]
164; CHECK-NEXT:    b.ge .LBB3_4
165; CHECK-NEXT:  // %bb.3: // %while_body
166; CHECK-NEXT:    // in Loop: Header=BB3_1 Depth=1
167; CHECK-NEXT:    add w9, w20, #1
168; CHECK-NEXT:    stp w9, w20, [x8]
169; CHECK-NEXT:    mov w20, w9
170; CHECK-NEXT:    b .LBB3_1
171; CHECK-NEXT:  .LBB3_4: // %while_end
172; CHECK-NEXT:    ldp x20, x19, [sp, #16] // 16-byte Folded Reload
173; CHECK-NEXT:    ldp x30, x21, [sp], #32 // 16-byte Folded Reload
174; CHECK-NEXT:    ret
175; CHECK-NEXT:  .LBB3_5: // %cleanup
176; CHECK-NEXT:  .Ltmp2:
177; CHECK-NEXT:    mov x19, x0
178; CHECK-NEXT:    bl foo2
179; CHECK-NEXT:    mov x0, x19
180; CHECK-NEXT:    bl _Unwind_Resume
181entry:
182  br label %while_cond
183
184while_cond:
185  %phi = phi i32 [ 0, %entry ], [ %i, %while_body ]
186  %struct = invoke %struct_type* @foo() to label %while_cond_x unwind label %cleanup
187
188while_cond_x:
189  %gep0 = getelementptr %struct_type, %struct_type* %struct, i64 0, i32 1
190  %gep1 = getelementptr %struct_type, %struct_type* %struct, i64 0, i32 2
191  store i32 0, i32* %gep0
192  %cmp = icmp slt i32 %phi, %n
193  br i1 %cmp, label %while_body, label %while_end
194
195while_body:
196  %i = add i32 %phi, 1
197  store i32 %i, i32* %gep0
198  store i32 %phi, i32* %gep1
199  br label %while_cond
200
201while_end:
202  ret void
203
204cleanup:
205  %x10 = landingpad { i8*, i32 }
206          cleanup
207  call void @foo2()
208  resume { i8*, i32 } %x10
209}
210
211declare i32 @__FrameHandler(...)
212
213define void @test5([65536 x i32]** %s, i32 %n) {
214; CHECK-LABEL: test5:
215; CHECK:       // %bb.0: // %entry
216; CHECK-NEXT:    ldr x9, [x0]
217; CHECK-NEXT:    mov w8, wzr
218; CHECK-NEXT:    add x9, x9, #19, lsl #12 // =77824
219; CHECK-NEXT:    add x9, x9, #2176
220; CHECK-NEXT:    cmp w8, w1
221; CHECK-NEXT:    b.ge .LBB4_2
222; CHECK-NEXT:  .LBB4_1: // %while_body
223; CHECK-NEXT:    // =>This Inner Loop Header: Depth=1
224; CHECK-NEXT:    add w10, w8, #1
225; CHECK-NEXT:    stp w10, w8, [x9]
226; CHECK-NEXT:    mov w8, w10
227; CHECK-NEXT:    cmp w8, w1
228; CHECK-NEXT:    b.lt .LBB4_1
229; CHECK-NEXT:  .LBB4_2: // %while_end
230; CHECK-NEXT:    ret
231entry:
232  %struct = load [65536 x i32]*, [65536 x i32]** %s
233  br label %while_cond
234
235while_cond:
236  %phi = phi i32 [ 0, %entry ], [ %i, %while_body ]
237  %gep0 = getelementptr [65536 x i32], [65536 x i32]* %struct, i64 0, i32 20000
238  %gep1 = getelementptr [65536 x i32], [65536 x i32]* %struct, i64 0, i32 20001
239  %cmp = icmp slt i32 %phi, %n
240  br i1 %cmp, label %while_body, label %while_end
241
242while_body:
243  %i = add i32 %phi, 1
244  store i32 %i, i32* %gep0
245  store i32 %phi, i32* %gep1
246  br label %while_cond
247
248while_end:
249  ret void
250}
251
252declare i8* @llvm.strip.invariant.group.p0i8(i8*)
253
254define void @test_invariant_group(i32) {
255; CHECK-LABEL: test_invariant_group:
256; CHECK:       // %bb.0:
257; CHECK-NEXT:    cbz wzr, .LBB5_2
258; CHECK-NEXT:  // %bb.1:
259; CHECK-NEXT:    cbz w0, .LBB5_3
260; CHECK-NEXT:  .LBB5_2:
261; CHECK-NEXT:    ret
262; CHECK-NEXT:  .LBB5_3:
263; CHECK-NEXT:    cbnz wzr, .LBB5_2
264; CHECK-NEXT:  // %bb.4:
265; CHECK-NEXT:    mov w8, #1
266; CHECK-NEXT:    str x8, [x8]
267; CHECK-NEXT:    ret
268  br i1 undef, label %8, label %7
269
270; <label>:2:                                      ; preds = %8, %2
271  br i1 undef, label %2, label %7
272
273; <label>:3:                                      ; preds = %8
274  %4 = getelementptr inbounds i8, i8* %9, i32 40000
275  %5 = bitcast i8* %4 to i64*
276  br i1 undef, label %7, label %6
277
278; <label>:6:                                      ; preds = %3
279  store i64 1, i64* %5, align 8
280  br label %7
281
282; <label>:7:                                      ; preds = %6, %3, %2, %1
283  ret void
284
285; <label>:8:                                      ; preds = %1
286  %9 = call i8* @llvm.strip.invariant.group.p0i8(i8* nonnull undef)
287  %10 = icmp eq i32 %0, 0
288  br i1 %10, label %3, label %2
289}
290
291