1; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s --check-prefixes=ALL,LA32
2; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s --check-prefixes=ALL,LA64
3
4define void @foo() noreturn nounwind {
5; ALL-LABEL: foo:
6; ALL:       # %bb.0: # %entry
7; ALL-NEXT:  .LBB0_1: # %loop
8; ALL-NEXT:    # =>This Inner Loop Header: Depth=1
9; ALL-NEXT:    b .LBB0_1
10entry:
11  br label %loop
12loop:
13  br label %loop
14}
15
16define void @foo_br_eq(i32 %a, ptr %b) nounwind {
17; LA32-LABEL: foo_br_eq:
18; LA32:       # %bb.0:
19; LA32-NEXT:    ld.w $a2, $a1, 0
20; LA32-NEXT:    beq $a2, $a0, .LBB1_2
21; LA32-NEXT:    b .LBB1_1
22; LA32-NEXT:  .LBB1_1: # %test
23; LA32-NEXT:    ld.w $a0, $a1, 0
24; LA32-NEXT:  .LBB1_2: # %end
25; LA32-NEXT:    jirl $zero, $ra, 0
26;
27; LA64-LABEL: foo_br_eq:
28; LA64:       # %bb.0:
29; LA64-NEXT:    ld.wu $a2, $a1, 0
30; LA64-NEXT:    bstrpick.d $a0, $a0, 31, 0
31; LA64-NEXT:    beq $a2, $a0, .LBB1_2
32; LA64-NEXT:    b .LBB1_1
33; LA64-NEXT:  .LBB1_1: # %test
34; LA64-NEXT:    ld.w $a0, $a1, 0
35; LA64-NEXT:  .LBB1_2: # %end
36; LA64-NEXT:    jirl $zero, $ra, 0
37  %val = load volatile i32, ptr %b
38  %cc = icmp eq i32 %val, %a
39  br i1 %cc, label %end, label %test
40test:
41  %tmp = load volatile i32, ptr %b
42  br label %end
43
44end:
45  ret void
46}
47
48define void @foo_br_ne(i32 %a, ptr %b) nounwind {
49; LA32-LABEL: foo_br_ne:
50; LA32:       # %bb.0:
51; LA32-NEXT:    ld.w $a2, $a1, 0
52; LA32-NEXT:    bne $a2, $a0, .LBB2_2
53; LA32-NEXT:    b .LBB2_1
54; LA32-NEXT:  .LBB2_1: # %test
55; LA32-NEXT:    ld.w $a0, $a1, 0
56; LA32-NEXT:  .LBB2_2: # %end
57; LA32-NEXT:    jirl $zero, $ra, 0
58;
59; LA64-LABEL: foo_br_ne:
60; LA64:       # %bb.0:
61; LA64-NEXT:    ld.wu $a2, $a1, 0
62; LA64-NEXT:    bstrpick.d $a0, $a0, 31, 0
63; LA64-NEXT:    bne $a2, $a0, .LBB2_2
64; LA64-NEXT:    b .LBB2_1
65; LA64-NEXT:  .LBB2_1: # %test
66; LA64-NEXT:    ld.w $a0, $a1, 0
67; LA64-NEXT:  .LBB2_2: # %end
68; LA64-NEXT:    jirl $zero, $ra, 0
69  %val = load volatile i32, ptr %b
70  %cc = icmp ne i32 %val, %a
71  br i1 %cc, label %end, label %test
72test:
73  %tmp = load volatile i32, ptr %b
74  br label %end
75
76end:
77  ret void
78}
79
80define void @foo_br_slt(i32 %a, ptr %b) nounwind {
81; LA32-LABEL: foo_br_slt:
82; LA32:       # %bb.0:
83; LA32-NEXT:    ld.w $a2, $a1, 0
84; LA32-NEXT:    blt $a2, $a0, .LBB3_2
85; LA32-NEXT:    b .LBB3_1
86; LA32-NEXT:  .LBB3_1: # %test
87; LA32-NEXT:    ld.w $a0, $a1, 0
88; LA32-NEXT:  .LBB3_2: # %end
89; LA32-NEXT:    jirl $zero, $ra, 0
90;
91; LA64-LABEL: foo_br_slt:
92; LA64:       # %bb.0:
93; LA64-NEXT:    ld.w $a2, $a1, 0
94; LA64-NEXT:    addi.w $a0, $a0, 0
95; LA64-NEXT:    blt $a2, $a0, .LBB3_2
96; LA64-NEXT:    b .LBB3_1
97; LA64-NEXT:  .LBB3_1: # %test
98; LA64-NEXT:    ld.w $a0, $a1, 0
99; LA64-NEXT:  .LBB3_2: # %end
100; LA64-NEXT:    jirl $zero, $ra, 0
101  %val = load volatile i32, ptr %b
102  %cc = icmp slt i32 %val, %a
103  br i1 %cc, label %end, label %test
104test:
105  %tmp = load volatile i32, ptr %b
106  br label %end
107
108end:
109  ret void
110}
111
112define void @foo_br_sge(i32 %a, ptr %b) nounwind {
113; LA32-LABEL: foo_br_sge:
114; LA32:       # %bb.0:
115; LA32-NEXT:    ld.w $a2, $a1, 0
116; LA32-NEXT:    bge $a2, $a0, .LBB4_2
117; LA32-NEXT:    b .LBB4_1
118; LA32-NEXT:  .LBB4_1: # %test
119; LA32-NEXT:    ld.w $a0, $a1, 0
120; LA32-NEXT:  .LBB4_2: # %end
121; LA32-NEXT:    jirl $zero, $ra, 0
122;
123; LA64-LABEL: foo_br_sge:
124; LA64:       # %bb.0:
125; LA64-NEXT:    ld.w $a2, $a1, 0
126; LA64-NEXT:    addi.w $a0, $a0, 0
127; LA64-NEXT:    bge $a2, $a0, .LBB4_2
128; LA64-NEXT:    b .LBB4_1
129; LA64-NEXT:  .LBB4_1: # %test
130; LA64-NEXT:    ld.w $a0, $a1, 0
131; LA64-NEXT:  .LBB4_2: # %end
132; LA64-NEXT:    jirl $zero, $ra, 0
133  %val = load volatile i32, ptr %b
134  %cc = icmp sge i32 %val, %a
135  br i1 %cc, label %end, label %test
136test:
137  %tmp = load volatile i32, ptr %b
138  br label %end
139
140end:
141  ret void
142}
143
144define void @foo_br_ult(i32 %a, ptr %b) nounwind {
145; LA32-LABEL: foo_br_ult:
146; LA32:       # %bb.0:
147; LA32-NEXT:    ld.w $a2, $a1, 0
148; LA32-NEXT:    bltu $a2, $a0, .LBB5_2
149; LA32-NEXT:    b .LBB5_1
150; LA32-NEXT:  .LBB5_1: # %test
151; LA32-NEXT:    ld.w $a0, $a1, 0
152; LA32-NEXT:  .LBB5_2: # %end
153; LA32-NEXT:    jirl $zero, $ra, 0
154;
155; LA64-LABEL: foo_br_ult:
156; LA64:       # %bb.0:
157; LA64-NEXT:    ld.wu $a2, $a1, 0
158; LA64-NEXT:    bstrpick.d $a0, $a0, 31, 0
159; LA64-NEXT:    bltu $a2, $a0, .LBB5_2
160; LA64-NEXT:    b .LBB5_1
161; LA64-NEXT:  .LBB5_1: # %test
162; LA64-NEXT:    ld.w $a0, $a1, 0
163; LA64-NEXT:  .LBB5_2: # %end
164; LA64-NEXT:    jirl $zero, $ra, 0
165  %val = load volatile i32, ptr %b
166  %cc = icmp ult i32 %val, %a
167  br i1 %cc, label %end, label %test
168test:
169  %tmp = load volatile i32, ptr %b
170  br label %end
171
172end:
173  ret void
174}
175
176define void @foo_br_uge(i32 %a, ptr %b) nounwind {
177; LA32-LABEL: foo_br_uge:
178; LA32:       # %bb.0:
179; LA32-NEXT:    ld.w $a2, $a1, 0
180; LA32-NEXT:    bgeu $a2, $a0, .LBB6_2
181; LA32-NEXT:    b .LBB6_1
182; LA32-NEXT:  .LBB6_1: # %test
183; LA32-NEXT:    ld.w $a0, $a1, 0
184; LA32-NEXT:  .LBB6_2: # %end
185; LA32-NEXT:    jirl $zero, $ra, 0
186;
187; LA64-LABEL: foo_br_uge:
188; LA64:       # %bb.0:
189; LA64-NEXT:    ld.wu $a2, $a1, 0
190; LA64-NEXT:    bstrpick.d $a0, $a0, 31, 0
191; LA64-NEXT:    bgeu $a2, $a0, .LBB6_2
192; LA64-NEXT:    b .LBB6_1
193; LA64-NEXT:  .LBB6_1: # %test
194; LA64-NEXT:    ld.w $a0, $a1, 0
195; LA64-NEXT:  .LBB6_2: # %end
196; LA64-NEXT:    jirl $zero, $ra, 0
197  %val = load volatile i32, ptr %b
198  %cc = icmp uge i32 %val, %a
199  br i1 %cc, label %end, label %test
200test:
201  %tmp = load volatile i32, ptr %b
202  br label %end
203
204end:
205  ret void
206}
207
208;; Check for condition codes that don't have a matching instruction.
209define void @foo_br_sgt(i32 %a, ptr %b) nounwind {
210; LA32-LABEL: foo_br_sgt:
211; LA32:       # %bb.0:
212; LA32-NEXT:    ld.w $a2, $a1, 0
213; LA32-NEXT:    blt $a0, $a2, .LBB7_2
214; LA32-NEXT:    b .LBB7_1
215; LA32-NEXT:  .LBB7_1: # %test
216; LA32-NEXT:    ld.w $a0, $a1, 0
217; LA32-NEXT:  .LBB7_2: # %end
218; LA32-NEXT:    jirl $zero, $ra, 0
219;
220; LA64-LABEL: foo_br_sgt:
221; LA64:       # %bb.0:
222; LA64-NEXT:    ld.w $a2, $a1, 0
223; LA64-NEXT:    addi.w $a0, $a0, 0
224; LA64-NEXT:    blt $a0, $a2, .LBB7_2
225; LA64-NEXT:    b .LBB7_1
226; LA64-NEXT:  .LBB7_1: # %test
227; LA64-NEXT:    ld.w $a0, $a1, 0
228; LA64-NEXT:  .LBB7_2: # %end
229; LA64-NEXT:    jirl $zero, $ra, 0
230  %val = load volatile i32, ptr %b
231  %cc = icmp sgt i32 %val, %a
232  br i1 %cc, label %end, label %test
233test:
234  %tmp = load volatile i32, ptr %b
235  br label %end
236
237end:
238  ret void
239}
240
241define void @foo_br_sle(i32 %a, ptr %b) nounwind {
242; LA32-LABEL: foo_br_sle:
243; LA32:       # %bb.0:
244; LA32-NEXT:    ld.w $a2, $a1, 0
245; LA32-NEXT:    bge $a0, $a2, .LBB8_2
246; LA32-NEXT:    b .LBB8_1
247; LA32-NEXT:  .LBB8_1: # %test
248; LA32-NEXT:    ld.w $a0, $a1, 0
249; LA32-NEXT:  .LBB8_2: # %end
250; LA32-NEXT:    jirl $zero, $ra, 0
251;
252; LA64-LABEL: foo_br_sle:
253; LA64:       # %bb.0:
254; LA64-NEXT:    ld.w $a2, $a1, 0
255; LA64-NEXT:    addi.w $a0, $a0, 0
256; LA64-NEXT:    bge $a0, $a2, .LBB8_2
257; LA64-NEXT:    b .LBB8_1
258; LA64-NEXT:  .LBB8_1: # %test
259; LA64-NEXT:    ld.w $a0, $a1, 0
260; LA64-NEXT:  .LBB8_2: # %end
261; LA64-NEXT:    jirl $zero, $ra, 0
262  %val = load volatile i32, ptr %b
263  %cc = icmp sle i32 %val, %a
264  br i1 %cc, label %end, label %test
265test:
266  %tmp = load volatile i32, ptr %b
267  br label %end
268
269end:
270  ret void
271}
272
273define void @foo_br_ugt(i32 %a, ptr %b) nounwind {
274; LA32-LABEL: foo_br_ugt:
275; LA32:       # %bb.0:
276; LA32-NEXT:    ld.w $a2, $a1, 0
277; LA32-NEXT:    bltu $a0, $a2, .LBB9_2
278; LA32-NEXT:    b .LBB9_1
279; LA32-NEXT:  .LBB9_1: # %test
280; LA32-NEXT:    ld.w $a0, $a1, 0
281; LA32-NEXT:  .LBB9_2: # %end
282; LA32-NEXT:    jirl $zero, $ra, 0
283;
284; LA64-LABEL: foo_br_ugt:
285; LA64:       # %bb.0:
286; LA64-NEXT:    ld.wu $a2, $a1, 0
287; LA64-NEXT:    bstrpick.d $a0, $a0, 31, 0
288; LA64-NEXT:    bltu $a0, $a2, .LBB9_2
289; LA64-NEXT:    b .LBB9_1
290; LA64-NEXT:  .LBB9_1: # %test
291; LA64-NEXT:    ld.w $a0, $a1, 0
292; LA64-NEXT:  .LBB9_2: # %end
293; LA64-NEXT:    jirl $zero, $ra, 0
294  %val = load volatile i32, ptr %b
295  %cc = icmp ugt i32 %val, %a
296  br i1 %cc, label %end, label %test
297test:
298  %tmp = load volatile i32, ptr %b
299  br label %end
300
301end:
302  ret void
303}
304
305define void @foo_br_ule(i32 %a, ptr %b) nounwind {
306; LA32-LABEL: foo_br_ule:
307; LA32:       # %bb.0:
308; LA32-NEXT:    ld.w $a2, $a1, 0
309; LA32-NEXT:    bgeu $a0, $a2, .LBB10_2
310; LA32-NEXT:    b .LBB10_1
311; LA32-NEXT:  .LBB10_1: # %test
312; LA32-NEXT:    ld.w $a0, $a1, 0
313; LA32-NEXT:  .LBB10_2: # %end
314; LA32-NEXT:    jirl $zero, $ra, 0
315;
316; LA64-LABEL: foo_br_ule:
317; LA64:       # %bb.0:
318; LA64-NEXT:    ld.wu $a2, $a1, 0
319; LA64-NEXT:    bstrpick.d $a0, $a0, 31, 0
320; LA64-NEXT:    bgeu $a0, $a2, .LBB10_2
321; LA64-NEXT:    b .LBB10_1
322; LA64-NEXT:  .LBB10_1: # %test
323; LA64-NEXT:    ld.w $a0, $a1, 0
324; LA64-NEXT:  .LBB10_2: # %end
325; LA64-NEXT:    jirl $zero, $ra, 0
326  %val = load volatile i32, ptr %b
327  %cc = icmp ule i32 %val, %a
328  br i1 %cc, label %end, label %test
329test:
330  %tmp = load volatile i32, ptr %b
331  br label %end
332
333end:
334  ret void
335}
336
337;; Check the case of a branch where the condition was generated in another
338;; function.
339define void @foo_br_cc(ptr %a, i1 %cc) nounwind {
340; ALL-LABEL: foo_br_cc:
341; ALL:       # %bb.0:
342; ALL-NEXT:    ld.w $a2, $a0, 0
343; ALL-NEXT:    andi $a1, $a1, 1
344; ALL-NEXT:    bnez $a1, .LBB11_2
345; ALL-NEXT:    b .LBB11_1
346; ALL-NEXT:  .LBB11_1: # %test
347; ALL-NEXT:    ld.w $a0, $a0, 0
348; ALL-NEXT:  .LBB11_2: # %end
349; ALL-NEXT:    jirl $zero, $ra, 0
350  %val = load volatile i32, ptr %a
351  br i1 %cc, label %end, label %test
352test:
353  %tmp = load volatile i32, ptr %a
354  br label %end
355
356end:
357  ret void
358}
359