xref: /llvm-project/llvm/test/CodeGen/RISCV/machine-combiner.ll (revision 9122c5235ec85ce0c0ad337e862b006e7b349d84)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv64 -mattr=+d,+zbb,+zfh -verify-machineinstrs -mcpu=sifive-u74 \
3; RUN: -O1 -riscv-enable-machine-combiner=true -riscv-force-machine-combiner-strategy=local < %s | \
4; RUN: FileCheck %s --check-prefixes=CHECK,CHECK_LOCAL
5
6; RUN: llc -mtriple=riscv64 -mattr=+d,+zbb,+zfh -verify-machineinstrs -mcpu=sifive-u74 \
7; RUN: -O1 -riscv-enable-machine-combiner=true -riscv-force-machine-combiner-strategy=min-instr < %s | \
8; RUN: FileCheck %s --check-prefixes=CHECK,CHECK_GLOBAL
9
10define double @test_reassoc_fadd1(double %a0, double %a1, double %a2, double %a3) {
11; CHECK-LABEL: test_reassoc_fadd1:
12; CHECK:       # %bb.0:
13; CHECK-NEXT:    fadd.d fa5, fa2, fa3
14; CHECK-NEXT:    fadd.d fa4, fa0, fa1
15; CHECK-NEXT:    fadd.d fa0, fa4, fa5
16; CHECK-NEXT:    ret
17  %t0 = fadd nsz reassoc double %a0, %a1
18  %t1 = fadd nsz reassoc double %t0, %a2
19  %t2 = fadd nsz reassoc double %t1, %a3
20  ret double %t2
21}
22
23define double @test_reassoc_fadd2(double %a0, double %a1, double %a2, double %a3) {
24; CHECK-LABEL: test_reassoc_fadd2:
25; CHECK:       # %bb.0:
26; CHECK-NEXT:    fadd.d fa5, fa2, fa3
27; CHECK-NEXT:    fadd.d fa4, fa0, fa1
28; CHECK-NEXT:    fadd.d fa0, fa5, fa4
29; CHECK-NEXT:    ret
30  %t0 = fadd nsz reassoc double %a0, %a1
31  %t1 = fadd nsz reassoc double %a2, %t0
32  %t2 = fadd nsz reassoc double %t1, %a3
33  ret double %t2
34}
35
36define double @test_reassoc_fadd3(double %a0, double %a1, double %a2, double %a3) {
37; CHECK-LABEL: test_reassoc_fadd3:
38; CHECK:       # %bb.0:
39; CHECK-NEXT:    fadd.d fa5, fa3, fa2
40; CHECK-NEXT:    fadd.d fa4, fa0, fa1
41; CHECK-NEXT:    fadd.d fa0, fa5, fa4
42; CHECK-NEXT:    ret
43  %t0 = fadd nsz reassoc double %a0, %a1
44  %t1 = fadd nsz reassoc double %t0, %a2
45  %t2 = fadd nsz reassoc double %a3, %t1
46  ret double %t2
47}
48
49define double @test_reassoc_fadd4(double %a0, double %a1, double %a2, double %a3) {
50; CHECK-LABEL: test_reassoc_fadd4:
51; CHECK:       # %bb.0:
52; CHECK-NEXT:    fadd.d fa5, fa3, fa2
53; CHECK-NEXT:    fadd.d fa4, fa0, fa1
54; CHECK-NEXT:    fadd.d fa0, fa5, fa4
55; CHECK-NEXT:    ret
56  %t0 = fadd nsz reassoc double %a0, %a1
57  %t1 = fadd nsz reassoc double %a2, %t0
58  %t2 = fadd nsz reassoc double %a3, %t1
59  ret double %t2
60}
61
62define double @test_reassoc_fmul1(double %a0, double %a1, double %a2, double %a3) {
63; CHECK-LABEL: test_reassoc_fmul1:
64; CHECK:       # %bb.0:
65; CHECK-NEXT:    fmul.d fa5, fa2, fa3
66; CHECK-NEXT:    fmul.d fa4, fa0, fa1
67; CHECK-NEXT:    fmul.d fa0, fa4, fa5
68; CHECK-NEXT:    ret
69  %t0 = fmul nsz reassoc double %a0, %a1
70  %t1 = fmul nsz reassoc double %t0, %a2
71  %t2 = fmul nsz reassoc double %t1, %a3
72  ret double %t2
73}
74
75define double @test_reassoc_fmul2(double %a0, double %a1, double %a2, double %a3) {
76; CHECK-LABEL: test_reassoc_fmul2:
77; CHECK:       # %bb.0:
78; CHECK-NEXT:    fmul.d fa5, fa2, fa3
79; CHECK-NEXT:    fmul.d fa4, fa0, fa1
80; CHECK-NEXT:    fmul.d fa0, fa5, fa4
81; CHECK-NEXT:    ret
82  %t0 = fmul nsz reassoc double %a0, %a1
83  %t1 = fmul nsz reassoc double %a2, %t0
84  %t2 = fmul nsz reassoc double %t1, %a3
85  ret double %t2
86}
87
88define double @test_reassoc_fmul3(double %a0, double %a1, double %a2, double %a3) {
89; CHECK-LABEL: test_reassoc_fmul3:
90; CHECK:       # %bb.0:
91; CHECK-NEXT:    fmul.d fa5, fa3, fa2
92; CHECK-NEXT:    fmul.d fa4, fa0, fa1
93; CHECK-NEXT:    fmul.d fa0, fa5, fa4
94; CHECK-NEXT:    ret
95  %t0 = fmul nsz reassoc double %a0, %a1
96  %t1 = fmul nsz reassoc double %t0, %a2
97  %t2 = fmul nsz reassoc double %a3, %t1
98  ret double %t2
99}
100
101define double @test_reassoc_fmul4(double %a0, double %a1, double %a2, double %a3) {
102; CHECK-LABEL: test_reassoc_fmul4:
103; CHECK:       # %bb.0:
104; CHECK-NEXT:    fmul.d fa5, fa3, fa2
105; CHECK-NEXT:    fmul.d fa4, fa0, fa1
106; CHECK-NEXT:    fmul.d fa0, fa5, fa4
107; CHECK-NEXT:    ret
108  %t0 = fmul nsz reassoc double %a0, %a1
109  %t1 = fmul nsz reassoc double %a2, %t0
110  %t2 = fmul nsz reassoc double %a3, %t1
111  ret double %t2
112}
113
114define double @test_reassoc_big1(double %a0, double %a1, double %a2, double %a3, double %a4, double %a5, double %a6) {
115; CHECK-LABEL: test_reassoc_big1:
116; CHECK:       # %bb.0:
117; CHECK-NEXT:    fadd.d fa5, fa4, fa5
118; CHECK-NEXT:    fadd.d fa4, fa2, fa3
119; CHECK-NEXT:    fadd.d fa3, fa0, fa1
120; CHECK-NEXT:    fadd.d fa5, fa5, fa6
121; CHECK-NEXT:    fadd.d fa4, fa3, fa4
122; CHECK-NEXT:    fadd.d fa0, fa4, fa5
123; CHECK-NEXT:    ret
124  %t0 = fadd nsz reassoc double %a0, %a1
125  %t1 = fadd nsz reassoc double %t0, %a2
126  %t2 = fadd nsz reassoc double %t1, %a3
127  %t3 = fadd nsz reassoc double %t2, %a4
128  %t4 = fadd nsz reassoc double %t3, %a5
129  %t5 = fadd nsz reassoc double %t4, %a6
130  ret double %t5
131}
132
133define double @test_reassoc_big2(double %a0, double %a1, i32 %a2, double %a3, i32 %a4, double %a5) {
134; CHECK-LABEL: test_reassoc_big2:
135; CHECK:       # %bb.0:
136; CHECK-NEXT:    fsub.d fa4, fa3, fa2
137; CHECK-NEXT:    fadd.d fa3, fa0, fa1
138; CHECK-NEXT:    fadd.d ft0, fa2, fa1
139; CHECK-NEXT:    fcvt.d.w fa5, a1
140; CHECK-NEXT:    fcvt.d.w ft1, a0
141; CHECK-NEXT:    fmul.d fa5, fa5, fa1
142; CHECK-NEXT:    fmul.d fa2, fa2, ft1
143; CHECK-NEXT:    fsub.d fa4, fa4, fa3
144; CHECK-NEXT:    fmul.d fa3, fa0, ft0
145; CHECK-NEXT:    fmul.d fa5, fa5, fa2
146; CHECK-NEXT:    fmul.d fa4, fa4, fa3
147; CHECK-NEXT:    fmul.d fa0, fa4, fa5
148; CHECK-NEXT:    ret
149  %cvt1 = sitofp i32 %a2 to double
150  %cvt2 = sitofp i32 %a4 to double
151  %t5 = fmul nsz reassoc double %a3, %cvt1
152  %t9 = fmul nsz reassoc double %cvt2, %t5
153  %t4 = fmul nsz reassoc double %t9, %a1
154  %t0 = fadd nsz reassoc double %a0, %a1
155  %t1 = fadd nsz reassoc double %a3, %t0
156  %t3 = fadd nsz reassoc double %a3, %a1
157  %t6 = fmul nsz reassoc double %t4, %a0
158  %t2 = fsub nsz reassoc double %a5, %t1
159  %t7 = fmul nsz reassoc double %t6, %t3
160  %t8 = fmul nsz reassoc double %t2, %t7
161  ret double %t8
162}
163
164; Negative test
165define double @test_reassoc_fadd_flags_1(double %a0, double %a1, double %a2, double %a3) {
166; CHECK-LABEL: test_reassoc_fadd_flags_1:
167; CHECK:       # %bb.0:
168; CHECK-NEXT:    fadd.d fa5, fa0, fa1
169; CHECK-NEXT:    fadd.d fa5, fa5, fa2
170; CHECK-NEXT:    fadd.d fa0, fa5, fa3
171; CHECK-NEXT:    ret
172  %t0 = fadd nsz reassoc double %a0, %a1
173  %t1 = fadd double %t0, %a2
174  %t2 = fadd nsz reassoc double %t1, %a3
175  ret double %t2
176}
177
178; Negative test
179define double @test_reassoc_fadd_flags_2(double %a0, double %a1, double %a2, double %a3) {
180; CHECK-LABEL: test_reassoc_fadd_flags_2:
181; CHECK:       # %bb.0:
182; CHECK-NEXT:    fadd.d fa5, fa0, fa1
183; CHECK-NEXT:    fadd.d fa5, fa5, fa2
184; CHECK-NEXT:    fadd.d fa0, fa5, fa3
185; CHECK-NEXT:    ret
186  %t0 = fadd nsz reassoc double %a0, %a1
187  %t1 = fadd nsz reassoc double %t0, %a2
188  %t2 = fadd double %t1, %a3
189  ret double %t2
190}
191
192define double @test_fmadd1(double %a0, double %a1, double %a2, double %a3) {
193; CHECK-LABEL: test_fmadd1:
194; CHECK:       # %bb.0:
195; CHECK-NEXT:    fmadd.d fa5, fa0, fa1, fa2
196; CHECK-NEXT:    fmadd.d fa4, fa0, fa1, fa3
197; CHECK-NEXT:    fadd.d fa0, fa5, fa4
198; CHECK-NEXT:    ret
199  %t0 = fmul contract double %a0, %a1
200  %t1 = fadd contract double %t0, %a2
201  %t2 = fadd contract double %a3, %t0
202  %t3 = fadd double %t1, %t2
203  ret double %t3
204}
205
206define double @test_fmadd2(double %a0, double %a1, double %a2) {
207; CHECK-LABEL: test_fmadd2:
208; CHECK:       # %bb.0:
209; CHECK-NEXT:    fmul.d fa5, fa0, fa1
210; CHECK-NEXT:    fmadd.d fa4, fa0, fa1, fa2
211; CHECK-NEXT:    fdiv.d fa0, fa4, fa5
212; CHECK-NEXT:    ret
213  %t0 = fmul contract double %a0, %a1
214  %t1 = fadd contract double %t0, %a2
215  %t2 = fdiv double %t1, %t0
216  ret double %t2
217}
218
219define double @test_fmsub(double %a0, double %a1, double %a2) {
220; CHECK-LABEL: test_fmsub:
221; CHECK:       # %bb.0:
222; CHECK-NEXT:    fmul.d fa5, fa0, fa1
223; CHECK-NEXT:    fmsub.d fa4, fa0, fa1, fa2
224; CHECK-NEXT:    fdiv.d fa0, fa4, fa5
225; CHECK-NEXT:    ret
226  %t0 = fmul contract double %a0, %a1
227  %t1 = fsub contract double %t0, %a2
228  %t2 = fdiv double %t1, %t0
229  ret double %t2
230}
231
232define double @test_fnmsub(double %a0, double %a1, double %a2) {
233; CHECK-LABEL: test_fnmsub:
234; CHECK:       # %bb.0:
235; CHECK-NEXT:    fmul.d fa5, fa0, fa1
236; CHECK-NEXT:    fnmsub.d fa4, fa0, fa1, fa2
237; CHECK-NEXT:    fdiv.d fa0, fa4, fa5
238; CHECK-NEXT:    ret
239  %t0 = fmul contract double %a0, %a1
240  %t1 = fsub contract double %a2, %t0
241  %t2 = fdiv double %t1, %t0
242  ret double %t2
243}
244
245define double @test_reassoc_fsub1(double %a0, double %a1, double %a2, double %a3) {
246; CHECK-LABEL: test_reassoc_fsub1:
247; CHECK:       # %bb.0:
248; CHECK-NEXT:    fsub.d fa5, fa2, fa3
249; CHECK-NEXT:    fadd.d fa4, fa0, fa1
250; CHECK-NEXT:    fadd.d fa0, fa4, fa5
251; CHECK-NEXT:    ret
252  %t0 = fadd nsz reassoc double %a0, %a1
253  %t1 = fadd nsz reassoc double %t0, %a2
254  %t2 = fsub nsz reassoc double %t1, %a3
255  ret double %t2
256}
257
258define double @test_reassoc_fsub2(double %a0, double %a1, double %a2, double %a3) {
259; CHECK-LABEL: test_reassoc_fsub2:
260; CHECK:       # %bb.0:
261; CHECK-NEXT:    fsub.d fa5, fa2, fa3
262; CHECK-NEXT:    fadd.d fa4, fa0, fa1
263; CHECK-NEXT:    fsub.d fa0, fa4, fa5
264; CHECK-NEXT:    ret
265  %t0 = fadd nsz reassoc double %a0, %a1
266  %t1 = fsub nsz reassoc double %t0, %a2
267  %t2 = fadd nsz reassoc double %t1, %a3
268  ret double %t2
269}
270
271define double @test_reassoc_fsub3(double %a0, double %a1, double %a2, double %a3) {
272; CHECK-LABEL: test_reassoc_fsub3:
273; CHECK:       # %bb.0:
274; CHECK-NEXT:    fadd.d fa5, fa2, fa3
275; CHECK-NEXT:    fadd.d fa4, fa0, fa1
276; CHECK-NEXT:    fsub.d fa0, fa4, fa5
277; CHECK-NEXT:    ret
278  %t0 = fadd nsz reassoc double %a0, %a1
279  %t1 = fsub nsz reassoc double %t0, %a2
280  %t2 = fsub nsz reassoc double %t1, %a3
281  ret double %t2
282}
283
284define double @test_reassoc_fsub4(double %a0, double %a1, double %a2, double %a3) {
285; CHECK-LABEL: test_reassoc_fsub4:
286; CHECK:       # %bb.0:
287; CHECK-NEXT:    fsub.d fa5, fa2, fa3
288; CHECK-NEXT:    fadd.d fa4, fa0, fa1
289; CHECK-NEXT:    fadd.d fa0, fa5, fa4
290; CHECK-NEXT:    ret
291  %t0 = fadd nsz reassoc double %a0, %a1
292  %t1 = fadd nsz reassoc double %a2, %t0
293  %t2 = fsub nsz reassoc double %t1, %a3
294  ret double %t2
295}
296
297define double @test_reassoc_fsub5(double %a0, double %a1, double %a2, double %a3) {
298; CHECK-LABEL: test_reassoc_fsub5:
299; CHECK:       # %bb.0:
300; CHECK-NEXT:    fadd.d fa5, fa2, fa3
301; CHECK-NEXT:    fadd.d fa4, fa0, fa1
302; CHECK-NEXT:    fsub.d fa0, fa5, fa4
303; CHECK-NEXT:    ret
304  %t0 = fadd nsz reassoc double %a0, %a1
305  %t1 = fsub nsz reassoc double %a2, %t0
306  %t2 = fadd nsz reassoc double %t1, %a3
307  ret double %t2
308}
309
310define double @test_reassoc_fsub6(double %a0, double %a1, double %a2, double %a3) {
311; CHECK-LABEL: test_reassoc_fsub6:
312; CHECK:       # %bb.0:
313; CHECK-NEXT:    fsub.d fa5, fa2, fa3
314; CHECK-NEXT:    fadd.d fa4, fa0, fa1
315; CHECK-NEXT:    fsub.d fa0, fa5, fa4
316; CHECK-NEXT:    ret
317  %t0 = fadd nsz reassoc double %a0, %a1
318  %t1 = fsub nsz reassoc double %a2, %t0
319  %t2 = fsub nsz reassoc double %t1, %a3
320  ret double %t2
321}
322
323define double @test_reassoc_fsub7(double %a0, double %a1, double %a2, double %a3) {
324; CHECK-LABEL: test_reassoc_fsub7:
325; CHECK:       # %bb.0:
326; CHECK-NEXT:    fsub.d fa5, fa3, fa2
327; CHECK-NEXT:    fadd.d fa4, fa0, fa1
328; CHECK-NEXT:    fsub.d fa0, fa5, fa4
329; CHECK-NEXT:    ret
330  %t0 = fadd nsz reassoc double %a0, %a1
331  %t1 = fadd nsz reassoc double %t0, %a2
332  %t2 = fsub nsz reassoc double %a3, %t1
333  ret double %t2
334}
335
336define double @test_reassoc_fsub8(double %a0, double %a1, double %a2, double %a3) {
337; CHECK-LABEL: test_reassoc_fsub8:
338; CHECK:       # %bb.0:
339; CHECK-NEXT:    fsub.d fa5, fa3, fa2
340; CHECK-NEXT:    fadd.d fa4, fa0, fa1
341; CHECK-NEXT:    fadd.d fa0, fa5, fa4
342; CHECK-NEXT:    ret
343  %t0 = fadd nsz reassoc double %a0, %a1
344  %t1 = fsub nsz reassoc double %t0, %a2
345  %t2 = fadd nsz reassoc double %a3, %t1
346  ret double %t2
347}
348
349define double @test_reassoc_fsub9(double %a0, double %a1, double %a2, double %a3) {
350; CHECK-LABEL: test_reassoc_fsub9:
351; CHECK:       # %bb.0:
352; CHECK-NEXT:    fadd.d fa5, fa3, fa2
353; CHECK-NEXT:    fadd.d fa4, fa0, fa1
354; CHECK-NEXT:    fsub.d fa0, fa5, fa4
355; CHECK-NEXT:    ret
356  %t0 = fadd nsz reassoc double %a0, %a1
357  %t1 = fsub nsz reassoc double %t0, %a2
358  %t2 = fsub nsz reassoc double %a3, %t1
359  ret double %t2
360}
361
362define double @test_reassoc_fsub10(double %a0, double %a1, double %a2, double %a3) {
363; CHECK-LABEL: test_reassoc_fsub10:
364; CHECK:       # %bb.0:
365; CHECK-NEXT:    fsub.d fa5, fa3, fa2
366; CHECK-NEXT:    fadd.d fa4, fa0, fa1
367; CHECK-NEXT:    fsub.d fa0, fa5, fa4
368; CHECK-NEXT:    ret
369  %t0 = fadd nsz reassoc double %a0, %a1
370  %t1 = fadd nsz reassoc double %a2, %t0
371  %t2 = fsub nsz reassoc double %a3, %t1
372  ret double %t2
373}
374
375define double @test_reassoc_fsub11(double %a0, double %a1, double %a2, double %a3) {
376; CHECK-LABEL: test_reassoc_fsub11:
377; CHECK:       # %bb.0:
378; CHECK-NEXT:    fadd.d fa5, fa3, fa2
379; CHECK-NEXT:    fadd.d fa4, fa0, fa1
380; CHECK-NEXT:    fsub.d fa0, fa5, fa4
381; CHECK-NEXT:    ret
382  %t0 = fadd nsz reassoc double %a0, %a1
383  %t1 = fsub nsz reassoc double %a2, %t0
384  %t2 = fadd nsz reassoc double %a3, %t1
385  ret double %t2
386}
387
388define double @test_reassoc_fsub12(double %a0, double %a1, double %a2, double %a3) {
389; CHECK-LABEL: test_reassoc_fsub12:
390; CHECK:       # %bb.0:
391; CHECK-NEXT:    fsub.d fa5, fa3, fa2
392; CHECK-NEXT:    fadd.d fa4, fa0, fa1
393; CHECK-NEXT:    fadd.d fa0, fa5, fa4
394; CHECK-NEXT:    ret
395  %t0 = fadd nsz reassoc double %a0, %a1
396  %t1 = fsub nsz reassoc double %a2, %t0
397  %t2 = fsub nsz reassoc double %a3, %t1
398  ret double %t2
399}
400
401define i8 @test_reassoc_add_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
402; CHECK-LABEL: test_reassoc_add_i8:
403; CHECK:       # %bb.0:
404; CHECK-NEXT:    add a0, a0, a1
405; CHECK-NEXT:    add a2, a2, a3
406; CHECK-NEXT:    add a0, a0, a2
407; CHECK-NEXT:    ret
408  %t0 = add i8 %a0, %a1
409  %t1 = add i8 %t0, %a2
410  %t2 = add i8 %t1, %a3
411  ret i8 %t2
412}
413
414define i16 @test_reassoc_add_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
415; CHECK-LABEL: test_reassoc_add_i16:
416; CHECK:       # %bb.0:
417; CHECK-NEXT:    add a0, a0, a1
418; CHECK-NEXT:    add a2, a2, a3
419; CHECK-NEXT:    add a0, a0, a2
420; CHECK-NEXT:    ret
421  %t0 = add i16 %a0, %a1
422  %t1 = add i16 %t0, %a2
423  %t2 = add i16 %t1, %a3
424  ret i16 %t2
425}
426
427define i32 @test_reassoc_add_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
428; CHECK-LABEL: test_reassoc_add_i32:
429; CHECK:       # %bb.0:
430; CHECK-NEXT:    add a0, a0, a1
431; CHECK-NEXT:    add a2, a2, a3
432; CHECK-NEXT:    addw a0, a0, a2
433; CHECK-NEXT:    ret
434  %t0 = add i32 %a0, %a1
435  %t1 = add i32 %t0, %a2
436  %t2 = add i32 %t1, %a3
437  ret i32 %t2
438}
439
440define i64 @test_reassoc_add_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
441; CHECK-LABEL: test_reassoc_add_i64:
442; CHECK:       # %bb.0:
443; CHECK-NEXT:    add a0, a0, a1
444; CHECK-NEXT:    add a2, a2, a3
445; CHECK-NEXT:    add a0, a0, a2
446; CHECK-NEXT:    ret
447  %t0 = add i64 %a0, %a1
448  %t1 = add i64 %t0, %a2
449  %t2 = add i64 %t1, %a3
450  ret i64 %t2
451}
452
453define i32 @test_reassoc_add_sub_i32_1(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
454; CHECK-LABEL: test_reassoc_add_sub_i32_1:
455; CHECK:       # %bb.0:
456; CHECK-NEXT:    add a0, a0, a1
457; CHECK-NEXT:    subw a2, a2, a3
458; CHECK-NEXT:    subw a0, a0, a2
459; CHECK-NEXT:    ret
460  %t0 = add i32 %a0, %a1
461  %t1 = sub i32 %t0, %a2
462  %t2 = add i32 %t1, %a3
463  ret i32 %t2
464}
465
466define i32 @test_reassoc_add_sub_i32_2(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
467; CHECK-LABEL: test_reassoc_add_sub_i32_2:
468; CHECK:       # %bb.0:
469; CHECK-NEXT:    add a0, a0, a1
470; CHECK-NEXT:    subw a2, a2, a3
471; CHECK-NEXT:    addw a0, a0, a2
472; CHECK-NEXT:    ret
473  %t0 = add i32 %a0, %a1
474  %t1 = add i32 %t0, %a2
475  %t2 = sub i32 %t1, %a3
476  ret i32 %t2
477}
478
479define i32 @test_reassoc_add_sub_i32_3(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
480; CHECK-LABEL: test_reassoc_add_sub_i32_3:
481; CHECK:       # %bb.0:
482; CHECK-NEXT:    add a0, a0, a1
483; CHECK-NEXT:    add a2, a2, a3
484; CHECK-NEXT:    subw a0, a0, a2
485; CHECK-NEXT:    ret
486  %t0 = add i32 %a0, %a1
487  %t1 = sub i32 %t0, %a2
488  %t2 = sub i32 %t1, %a3
489  ret i32 %t2
490}
491
492define i64 @test_reassoc_add_sub_i64_1(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
493; CHECK-LABEL: test_reassoc_add_sub_i64_1:
494; CHECK:       # %bb.0:
495; CHECK-NEXT:    add a0, a0, a1
496; CHECK-NEXT:    sub a2, a2, a3
497; CHECK-NEXT:    sub a0, a0, a2
498; CHECK-NEXT:    ret
499  %t0 = add i64 %a0, %a1
500  %t1 = sub i64 %t0, %a2
501  %t2 = add i64 %t1, %a3
502  ret i64 %t2
503}
504
505define i64 @test_reassoc_add_sub_i64_2(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
506; CHECK-LABEL: test_reassoc_add_sub_i64_2:
507; CHECK:       # %bb.0:
508; CHECK-NEXT:    add a0, a0, a1
509; CHECK-NEXT:    sub a2, a2, a3
510; CHECK-NEXT:    add a0, a0, a2
511; CHECK-NEXT:    ret
512  %t0 = add i64 %a0, %a1
513  %t1 = add i64 %t0, %a2
514  %t2 = sub i64 %t1, %a3
515  ret i64 %t2
516}
517
518define i64 @test_reassoc_add_sub_i64_3(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
519; CHECK-LABEL: test_reassoc_add_sub_i64_3:
520; CHECK:       # %bb.0:
521; CHECK-NEXT:    add a0, a0, a1
522; CHECK-NEXT:    add a2, a2, a3
523; CHECK-NEXT:    sub a0, a0, a2
524; CHECK-NEXT:    ret
525  %t0 = add i64 %a0, %a1
526  %t1 = sub i64 %t0, %a2
527  %t2 = sub i64 %t1, %a3
528  ret i64 %t2
529}
530
531define i8 @test_reassoc_and_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
532; CHECK-LABEL: test_reassoc_and_i8:
533; CHECK:       # %bb.0:
534; CHECK-NEXT:    and a0, a0, a1
535; CHECK-NEXT:    and a2, a2, a3
536; CHECK-NEXT:    and a0, a0, a2
537; CHECK-NEXT:    ret
538  %t0 = and i8 %a0, %a1
539  %t1 = and i8 %t0, %a2
540  %t2 = and i8 %t1, %a3
541  ret i8 %t2
542}
543
544define i16 @test_reassoc_and_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
545; CHECK-LABEL: test_reassoc_and_i16:
546; CHECK:       # %bb.0:
547; CHECK-NEXT:    and a0, a0, a1
548; CHECK-NEXT:    and a2, a2, a3
549; CHECK-NEXT:    and a0, a0, a2
550; CHECK-NEXT:    ret
551  %t0 = and i16 %a0, %a1
552  %t1 = and i16 %t0, %a2
553  %t2 = and i16 %t1, %a3
554  ret i16 %t2
555}
556
557define i32 @test_reassoc_and_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
558; CHECK-LABEL: test_reassoc_and_i32:
559; CHECK:       # %bb.0:
560; CHECK-NEXT:    and a0, a0, a1
561; CHECK-NEXT:    and a2, a2, a3
562; CHECK-NEXT:    and a0, a0, a2
563; CHECK-NEXT:    ret
564  %t0 = and i32 %a0, %a1
565  %t1 = and i32 %t0, %a2
566  %t2 = and i32 %t1, %a3
567  ret i32 %t2
568}
569
570define i64 @test_reassoc_and_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
571; CHECK-LABEL: test_reassoc_and_i64:
572; CHECK:       # %bb.0:
573; CHECK-NEXT:    and a0, a0, a1
574; CHECK-NEXT:    and a2, a2, a3
575; CHECK-NEXT:    and a0, a0, a2
576; CHECK-NEXT:    ret
577  %t0 = and i64 %a0, %a1
578  %t1 = and i64 %t0, %a2
579  %t2 = and i64 %t1, %a3
580  ret i64 %t2
581}
582
583define i8 @test_reassoc_or_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
584; CHECK-LABEL: test_reassoc_or_i8:
585; CHECK:       # %bb.0:
586; CHECK-NEXT:    or a0, a0, a1
587; CHECK-NEXT:    or a2, a2, a3
588; CHECK-NEXT:    or a0, a0, a2
589; CHECK-NEXT:    ret
590  %t0 = or i8 %a0, %a1
591  %t1 = or i8 %t0, %a2
592  %t2 = or i8 %t1, %a3
593  ret i8 %t2
594}
595
596define i16 @test_reassoc_or_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
597; CHECK-LABEL: test_reassoc_or_i16:
598; CHECK:       # %bb.0:
599; CHECK-NEXT:    or a0, a0, a1
600; CHECK-NEXT:    or a2, a2, a3
601; CHECK-NEXT:    or a0, a0, a2
602; CHECK-NEXT:    ret
603  %t0 = or i16 %a0, %a1
604  %t1 = or i16 %t0, %a2
605  %t2 = or i16 %t1, %a3
606  ret i16 %t2
607}
608
609define i32 @test_reassoc_or_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
610; CHECK-LABEL: test_reassoc_or_i32:
611; CHECK:       # %bb.0:
612; CHECK-NEXT:    or a0, a0, a1
613; CHECK-NEXT:    or a2, a2, a3
614; CHECK-NEXT:    or a0, a0, a2
615; CHECK-NEXT:    ret
616  %t0 = or i32 %a0, %a1
617  %t1 = or i32 %t0, %a2
618  %t2 = or i32 %t1, %a3
619  ret i32 %t2
620}
621
622define i64 @test_reassoc_or_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
623; CHECK-LABEL: test_reassoc_or_i64:
624; CHECK:       # %bb.0:
625; CHECK-NEXT:    or a0, a0, a1
626; CHECK-NEXT:    or a2, a2, a3
627; CHECK-NEXT:    or a0, a0, a2
628; CHECK-NEXT:    ret
629  %t0 = or i64 %a0, %a1
630  %t1 = or i64 %t0, %a2
631  %t2 = or i64 %t1, %a3
632  ret i64 %t2
633}
634
635define i8 @test_reassoc_xor_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
636; CHECK-LABEL: test_reassoc_xor_i8:
637; CHECK:       # %bb.0:
638; CHECK-NEXT:    xor a0, a0, a1
639; CHECK-NEXT:    xor a2, a2, a3
640; CHECK-NEXT:    xor a0, a0, a2
641; CHECK-NEXT:    ret
642  %t0 = xor i8 %a0, %a1
643  %t1 = xor i8 %t0, %a2
644  %t2 = xor i8 %t1, %a3
645  ret i8 %t2
646}
647
648define i16 @test_reassoc_xor_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
649; CHECK-LABEL: test_reassoc_xor_i16:
650; CHECK:       # %bb.0:
651; CHECK-NEXT:    xor a0, a0, a1
652; CHECK-NEXT:    xor a2, a2, a3
653; CHECK-NEXT:    xor a0, a0, a2
654; CHECK-NEXT:    ret
655  %t0 = xor i16 %a0, %a1
656  %t1 = xor i16 %t0, %a2
657  %t2 = xor i16 %t1, %a3
658  ret i16 %t2
659}
660
661define i32 @test_reassoc_xor_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
662; CHECK-LABEL: test_reassoc_xor_i32:
663; CHECK:       # %bb.0:
664; CHECK-NEXT:    xor a0, a0, a1
665; CHECK-NEXT:    xor a2, a2, a3
666; CHECK-NEXT:    xor a0, a0, a2
667; CHECK-NEXT:    ret
668  %t0 = xor i32 %a0, %a1
669  %t1 = xor i32 %t0, %a2
670  %t2 = xor i32 %t1, %a3
671  ret i32 %t2
672}
673
674define i64 @test_reassoc_xor_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
675; CHECK-LABEL: test_reassoc_xor_i64:
676; CHECK:       # %bb.0:
677; CHECK-NEXT:    xor a0, a0, a1
678; CHECK-NEXT:    xor a2, a2, a3
679; CHECK-NEXT:    xor a0, a0, a2
680; CHECK-NEXT:    ret
681  %t0 = xor i64 %a0, %a1
682  %t1 = xor i64 %t0, %a2
683  %t2 = xor i64 %t1, %a3
684  ret i64 %t2
685}
686
687define i8 @test_reassoc_mul_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
688; CHECK-LABEL: test_reassoc_mul_i8:
689; CHECK:       # %bb.0:
690; CHECK-NEXT:    mul a2, a2, a3
691; CHECK-NEXT:    mul a0, a0, a1
692; CHECK-NEXT:    mul a0, a0, a2
693; CHECK-NEXT:    ret
694  %t0 = mul i8 %a0, %a1
695  %t1 = mul i8 %t0, %a2
696  %t2 = mul i8 %t1, %a3
697  ret i8 %t2
698}
699
700define i16 @test_reassoc_mul_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
701; CHECK-LABEL: test_reassoc_mul_i16:
702; CHECK:       # %bb.0:
703; CHECK-NEXT:    mul a2, a2, a3
704; CHECK-NEXT:    mul a0, a0, a1
705; CHECK-NEXT:    mul a0, a0, a2
706; CHECK-NEXT:    ret
707  %t0 = mul i16 %a0, %a1
708  %t1 = mul i16 %t0, %a2
709  %t2 = mul i16 %t1, %a3
710  ret i16 %t2
711}
712
713define i32 @test_reassoc_mul_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
714; CHECK-LABEL: test_reassoc_mul_i32:
715; CHECK:       # %bb.0:
716; CHECK-NEXT:    mul a2, a2, a3
717; CHECK-NEXT:    mul a0, a0, a1
718; CHECK-NEXT:    mulw a0, a0, a2
719; CHECK-NEXT:    ret
720  %t0 = mul i32 %a0, %a1
721  %t1 = mul i32 %t0, %a2
722  %t2 = mul i32 %t1, %a3
723  ret i32 %t2
724}
725
726define i64 @test_reassoc_mul_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
727; CHECK-LABEL: test_reassoc_mul_i64:
728; CHECK:       # %bb.0:
729; CHECK-NEXT:    mul a2, a2, a3
730; CHECK-NEXT:    mul a0, a0, a1
731; CHECK-NEXT:    mul a0, a0, a2
732; CHECK-NEXT:    ret
733  %t0 = mul i64 %a0, %a1
734  %t1 = mul i64 %t0, %a2
735  %t2 = mul i64 %t1, %a3
736  ret i64 %t2
737}
738
739define i8 @test_reassoc_minu_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
740; CHECK-LABEL: test_reassoc_minu_i8:
741; CHECK:       # %bb.0:
742; CHECK-NEXT:    andi a3, a3, 255
743; CHECK-NEXT:    andi a1, a1, 255
744; CHECK-NEXT:    andi a0, a0, 255
745; CHECK-NEXT:    andi a2, a2, 255
746; CHECK-NEXT:    minu a0, a0, a1
747; CHECK-NEXT:    minu a1, a2, a3
748; CHECK-NEXT:    minu a0, a0, a1
749; CHECK-NEXT:    ret
750  %t0 = call i8 @llvm.umin.i8(i8 %a0, i8 %a1)
751  %t1 = call i8 @llvm.umin.i8(i8 %t0, i8 %a2)
752  %t2 = call i8 @llvm.umin.i8(i8 %t1, i8 %a3)
753  ret i8 %t2
754}
755
756define i16 @test_reassoc_minu_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
757; CHECK-LABEL: test_reassoc_minu_i16:
758; CHECK:       # %bb.0:
759; CHECK-NEXT:    zext.h a3, a3
760; CHECK-NEXT:    zext.h a1, a1
761; CHECK-NEXT:    zext.h a0, a0
762; CHECK-NEXT:    zext.h a2, a2
763; CHECK-NEXT:    minu a0, a0, a1
764; CHECK-NEXT:    minu a1, a2, a3
765; CHECK-NEXT:    minu a0, a0, a1
766; CHECK-NEXT:    ret
767  %t0 = call i16 @llvm.umin.i16(i16 %a0, i16 %a1)
768  %t1 = call i16 @llvm.umin.i16(i16 %t0, i16 %a2)
769  %t2 = call i16 @llvm.umin.i16(i16 %t1, i16 %a3)
770  ret i16 %t2
771}
772
773define i32 @test_reassoc_minu_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
774; CHECK-LABEL: test_reassoc_minu_i32:
775; CHECK:       # %bb.0:
776; CHECK-NEXT:    sext.w a3, a3
777; CHECK-NEXT:    sext.w a1, a1
778; CHECK-NEXT:    sext.w a0, a0
779; CHECK-NEXT:    sext.w a2, a2
780; CHECK-NEXT:    minu a0, a0, a1
781; CHECK-NEXT:    minu a1, a2, a3
782; CHECK-NEXT:    minu a0, a0, a1
783; CHECK-NEXT:    ret
784  %t0 = call i32 @llvm.umin.i32(i32 %a0, i32 %a1)
785  %t1 = call i32 @llvm.umin.i32(i32 %t0, i32 %a2)
786  %t2 = call i32 @llvm.umin.i32(i32 %t1, i32 %a3)
787  ret i32 %t2
788}
789
790define i64 @test_reassoc_minu_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
791; CHECK-LABEL: test_reassoc_minu_i64:
792; CHECK:       # %bb.0:
793; CHECK-NEXT:    minu a0, a0, a1
794; CHECK-NEXT:    minu a1, a2, a3
795; CHECK-NEXT:    minu a0, a0, a1
796; CHECK-NEXT:    ret
797  %t0 = call i64 @llvm.umin.i64(i64 %a0, i64 %a1)
798  %t1 = call i64 @llvm.umin.i64(i64 %t0, i64 %a2)
799  %t2 = call i64 @llvm.umin.i64(i64 %t1, i64 %a3)
800  ret i64 %t2
801}
802
803define i8 @test_reassoc_min_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
804; CHECK-LABEL: test_reassoc_min_i8:
805; CHECK:       # %bb.0:
806; CHECK-NEXT:    sext.b a3, a3
807; CHECK-NEXT:    sext.b a1, a1
808; CHECK-NEXT:    sext.b a0, a0
809; CHECK-NEXT:    sext.b a2, a2
810; CHECK-NEXT:    min a0, a0, a1
811; CHECK-NEXT:    min a1, a2, a3
812; CHECK-NEXT:    min a0, a0, a1
813; CHECK-NEXT:    ret
814  %t0 = call i8 @llvm.smin.i8(i8 %a0, i8 %a1)
815  %t1 = call i8 @llvm.smin.i8(i8 %t0, i8 %a2)
816  %t2 = call i8 @llvm.smin.i8(i8 %t1, i8 %a3)
817  ret i8 %t2
818}
819
820define i16 @test_reassoc_min_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
821; CHECK-LABEL: test_reassoc_min_i16:
822; CHECK:       # %bb.0:
823; CHECK-NEXT:    sext.h a3, a3
824; CHECK-NEXT:    sext.h a1, a1
825; CHECK-NEXT:    sext.h a0, a0
826; CHECK-NEXT:    sext.h a2, a2
827; CHECK-NEXT:    min a0, a0, a1
828; CHECK-NEXT:    min a1, a2, a3
829; CHECK-NEXT:    min a0, a0, a1
830; CHECK-NEXT:    ret
831  %t0 = call i16 @llvm.smin.i16(i16 %a0, i16 %a1)
832  %t1 = call i16 @llvm.smin.i16(i16 %t0, i16 %a2)
833  %t2 = call i16 @llvm.smin.i16(i16 %t1, i16 %a3)
834  ret i16 %t2
835}
836
837define i32 @test_reassoc_min_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
838; CHECK-LABEL: test_reassoc_min_i32:
839; CHECK:       # %bb.0:
840; CHECK-NEXT:    sext.w a3, a3
841; CHECK-NEXT:    sext.w a1, a1
842; CHECK-NEXT:    sext.w a0, a0
843; CHECK-NEXT:    sext.w a2, a2
844; CHECK-NEXT:    min a0, a0, a1
845; CHECK-NEXT:    min a1, a2, a3
846; CHECK-NEXT:    min a0, a0, a1
847; CHECK-NEXT:    ret
848  %t0 = call i32 @llvm.smin.i32(i32 %a0, i32 %a1)
849  %t1 = call i32 @llvm.smin.i32(i32 %t0, i32 %a2)
850  %t2 = call i32 @llvm.smin.i32(i32 %t1, i32 %a3)
851  ret i32 %t2
852}
853
854define i64 @test_reassoc_min_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
855; CHECK-LABEL: test_reassoc_min_i64:
856; CHECK:       # %bb.0:
857; CHECK-NEXT:    min a0, a0, a1
858; CHECK-NEXT:    min a1, a2, a3
859; CHECK-NEXT:    min a0, a0, a1
860; CHECK-NEXT:    ret
861  %t0 = call i64 @llvm.smin.i64(i64 %a0, i64 %a1)
862  %t1 = call i64 @llvm.smin.i64(i64 %t0, i64 %a2)
863  %t2 = call i64 @llvm.smin.i64(i64 %t1, i64 %a3)
864  ret i64 %t2
865}
866
867define i8 @test_reassoc_maxu_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
868; CHECK-LABEL: test_reassoc_maxu_i8:
869; CHECK:       # %bb.0:
870; CHECK-NEXT:    andi a3, a3, 255
871; CHECK-NEXT:    andi a1, a1, 255
872; CHECK-NEXT:    andi a0, a0, 255
873; CHECK-NEXT:    andi a2, a2, 255
874; CHECK-NEXT:    maxu a0, a0, a1
875; CHECK-NEXT:    maxu a1, a2, a3
876; CHECK-NEXT:    maxu a0, a0, a1
877; CHECK-NEXT:    ret
878  %t0 = call i8 @llvm.umax.i8(i8 %a0, i8 %a1)
879  %t1 = call i8 @llvm.umax.i8(i8 %t0, i8 %a2)
880  %t2 = call i8 @llvm.umax.i8(i8 %t1, i8 %a3)
881  ret i8 %t2
882}
883
884define i16 @test_reassoc_maxu_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
885; CHECK-LABEL: test_reassoc_maxu_i16:
886; CHECK:       # %bb.0:
887; CHECK-NEXT:    zext.h a3, a3
888; CHECK-NEXT:    zext.h a1, a1
889; CHECK-NEXT:    zext.h a0, a0
890; CHECK-NEXT:    zext.h a2, a2
891; CHECK-NEXT:    maxu a0, a0, a1
892; CHECK-NEXT:    maxu a1, a2, a3
893; CHECK-NEXT:    maxu a0, a0, a1
894; CHECK-NEXT:    ret
895  %t0 = call i16 @llvm.umax.i16(i16 %a0, i16 %a1)
896  %t1 = call i16 @llvm.umax.i16(i16 %t0, i16 %a2)
897  %t2 = call i16 @llvm.umax.i16(i16 %t1, i16 %a3)
898  ret i16 %t2
899}
900
901define i32 @test_reassoc_maxu_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
902; CHECK-LABEL: test_reassoc_maxu_i32:
903; CHECK:       # %bb.0:
904; CHECK-NEXT:    sext.w a3, a3
905; CHECK-NEXT:    sext.w a1, a1
906; CHECK-NEXT:    sext.w a0, a0
907; CHECK-NEXT:    sext.w a2, a2
908; CHECK-NEXT:    maxu a0, a0, a1
909; CHECK-NEXT:    maxu a1, a2, a3
910; CHECK-NEXT:    maxu a0, a0, a1
911; CHECK-NEXT:    ret
912  %t0 = call i32 @llvm.umax.i32(i32 %a0, i32 %a1)
913  %t1 = call i32 @llvm.umax.i32(i32 %t0, i32 %a2)
914  %t2 = call i32 @llvm.umax.i32(i32 %t1, i32 %a3)
915  ret i32 %t2
916}
917
918define i64 @test_reassoc_maxu_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
919; CHECK-LABEL: test_reassoc_maxu_i64:
920; CHECK:       # %bb.0:
921; CHECK-NEXT:    maxu a0, a0, a1
922; CHECK-NEXT:    maxu a1, a2, a3
923; CHECK-NEXT:    maxu a0, a0, a1
924; CHECK-NEXT:    ret
925  %t0 = call i64 @llvm.umax.i64(i64 %a0, i64 %a1)
926  %t1 = call i64 @llvm.umax.i64(i64 %t0, i64 %a2)
927  %t2 = call i64 @llvm.umax.i64(i64 %t1, i64 %a3)
928  ret i64 %t2
929}
930
931define i8 @test_reassoc_max_i8(i8 %a0, i8 %a1, i8 %a2, i8 %a3) {
932; CHECK-LABEL: test_reassoc_max_i8:
933; CHECK:       # %bb.0:
934; CHECK-NEXT:    sext.b a3, a3
935; CHECK-NEXT:    sext.b a1, a1
936; CHECK-NEXT:    sext.b a0, a0
937; CHECK-NEXT:    sext.b a2, a2
938; CHECK-NEXT:    max a0, a0, a1
939; CHECK-NEXT:    max a1, a2, a3
940; CHECK-NEXT:    max a0, a0, a1
941; CHECK-NEXT:    ret
942  %t0 = call i8 @llvm.smax.i8(i8 %a0, i8 %a1)
943  %t1 = call i8 @llvm.smax.i8(i8 %t0, i8 %a2)
944  %t2 = call i8 @llvm.smax.i8(i8 %t1, i8 %a3)
945  ret i8 %t2
946}
947
948define i16 @test_reassoc_max_i16(i16 %a0, i16 %a1, i16 %a2, i16 %a3) {
949; CHECK-LABEL: test_reassoc_max_i16:
950; CHECK:       # %bb.0:
951; CHECK-NEXT:    sext.h a3, a3
952; CHECK-NEXT:    sext.h a1, a1
953; CHECK-NEXT:    sext.h a0, a0
954; CHECK-NEXT:    sext.h a2, a2
955; CHECK-NEXT:    max a0, a0, a1
956; CHECK-NEXT:    max a1, a2, a3
957; CHECK-NEXT:    max a0, a0, a1
958; CHECK-NEXT:    ret
959  %t0 = call i16 @llvm.smax.i16(i16 %a0, i16 %a1)
960  %t1 = call i16 @llvm.smax.i16(i16 %t0, i16 %a2)
961  %t2 = call i16 @llvm.smax.i16(i16 %t1, i16 %a3)
962  ret i16 %t2
963}
964
965define i32 @test_reassoc_max_i32(i32 %a0, i32 %a1, i32 %a2, i32 %a3) {
966; CHECK-LABEL: test_reassoc_max_i32:
967; CHECK:       # %bb.0:
968; CHECK-NEXT:    sext.w a3, a3
969; CHECK-NEXT:    sext.w a1, a1
970; CHECK-NEXT:    sext.w a0, a0
971; CHECK-NEXT:    sext.w a2, a2
972; CHECK-NEXT:    max a0, a0, a1
973; CHECK-NEXT:    max a1, a2, a3
974; CHECK-NEXT:    max a0, a0, a1
975; CHECK-NEXT:    ret
976  %t0 = call i32 @llvm.smax.i32(i32 %a0, i32 %a1)
977  %t1 = call i32 @llvm.smax.i32(i32 %t0, i32 %a2)
978  %t2 = call i32 @llvm.smax.i32(i32 %t1, i32 %a3)
979  ret i32 %t2
980}
981
982define i64 @test_reassoc_max_i64(i64 %a0, i64 %a1, i64 %a2, i64 %a3) {
983; CHECK-LABEL: test_reassoc_max_i64:
984; CHECK:       # %bb.0:
985; CHECK-NEXT:    max a0, a0, a1
986; CHECK-NEXT:    max a1, a2, a3
987; CHECK-NEXT:    max a0, a0, a1
988; CHECK-NEXT:    ret
989  %t0 = call i64 @llvm.smax.i64(i64 %a0, i64 %a1)
990  %t1 = call i64 @llvm.smax.i64(i64 %t0, i64 %a2)
991  %t2 = call i64 @llvm.smax.i64(i64 %t1, i64 %a3)
992  ret i64 %t2
993}
994
995define half @test_fmin_f16(half %a0, half %a1, half %a2, half %a3) {
996; CHECK-LABEL: test_fmin_f16:
997; CHECK:       # %bb.0:
998; CHECK-NEXT:    fmin.h fa5, fa2, fa3
999; CHECK-NEXT:    fmin.h fa4, fa0, fa1
1000; CHECK-NEXT:    fmin.h fa0, fa4, fa5
1001; CHECK-NEXT:    ret
1002  %t0 = call half @llvm.minnum.f16(half %a0, half %a1)
1003  %t1 = call half @llvm.minnum.f16(half %t0, half %a2)
1004  %t2 = call half @llvm.minnum.f16(half %t1, half %a3)
1005  ret half %t2
1006}
1007
1008define float @test_fmin_f32(float %a0, float %a1, float %a2, float %a3) {
1009; CHECK-LABEL: test_fmin_f32:
1010; CHECK:       # %bb.0:
1011; CHECK-NEXT:    fmin.s fa5, fa2, fa3
1012; CHECK-NEXT:    fmin.s fa4, fa0, fa1
1013; CHECK-NEXT:    fmin.s fa0, fa4, fa5
1014; CHECK-NEXT:    ret
1015  %t0 = call float @llvm.minnum.f32(float %a0, float %a1)
1016  %t1 = call float @llvm.minnum.f32(float %t0, float %a2)
1017  %t2 = call float @llvm.minnum.f32(float %t1, float %a3)
1018  ret float %t2
1019}
1020
1021define double @test_fmin_f64(double %a0, double %a1, double %a2, double %a3) {
1022; CHECK-LABEL: test_fmin_f64:
1023; CHECK:       # %bb.0:
1024; CHECK-NEXT:    fmin.d fa5, fa2, fa3
1025; CHECK-NEXT:    fmin.d fa4, fa0, fa1
1026; CHECK-NEXT:    fmin.d fa0, fa4, fa5
1027; CHECK-NEXT:    ret
1028  %t0 = call double @llvm.minnum.f64(double %a0, double %a1)
1029  %t1 = call double @llvm.minnum.f64(double %t0, double %a2)
1030  %t2 = call double @llvm.minnum.f64(double %t1, double %a3)
1031  ret double %t2
1032}
1033
1034define half @test_fmax_f16(half %a0, half %a1, half %a2, half %a3) {
1035; CHECK-LABEL: test_fmax_f16:
1036; CHECK:       # %bb.0:
1037; CHECK-NEXT:    fmax.h fa5, fa2, fa3
1038; CHECK-NEXT:    fmax.h fa4, fa0, fa1
1039; CHECK-NEXT:    fmax.h fa0, fa4, fa5
1040; CHECK-NEXT:    ret
1041  %t0 = call half @llvm.maxnum.f16(half %a0, half %a1)
1042  %t1 = call half @llvm.maxnum.f16(half %t0, half %a2)
1043  %t2 = call half @llvm.maxnum.f16(half %t1, half %a3)
1044  ret half %t2
1045}
1046
1047define float @test_fmax_f32(float %a0, float %a1, float %a2, float %a3) {
1048; CHECK-LABEL: test_fmax_f32:
1049; CHECK:       # %bb.0:
1050; CHECK-NEXT:    fmax.s fa5, fa2, fa3
1051; CHECK-NEXT:    fmax.s fa4, fa0, fa1
1052; CHECK-NEXT:    fmax.s fa0, fa4, fa5
1053; CHECK-NEXT:    ret
1054  %t0 = call float @llvm.maxnum.f32(float %a0, float %a1)
1055  %t1 = call float @llvm.maxnum.f32(float %t0, float %a2)
1056  %t2 = call float @llvm.maxnum.f32(float %t1, float %a3)
1057  ret float %t2
1058}
1059
1060define double @test_fmax_f64(double %a0, double %a1, double %a2, double %a3) {
1061; CHECK-LABEL: test_fmax_f64:
1062; CHECK:       # %bb.0:
1063; CHECK-NEXT:    fmax.d fa5, fa2, fa3
1064; CHECK-NEXT:    fmax.d fa4, fa0, fa1
1065; CHECK-NEXT:    fmax.d fa0, fa4, fa5
1066; CHECK-NEXT:    ret
1067  %t0 = call double @llvm.maxnum.f64(double %a0, double %a1)
1068  %t1 = call double @llvm.maxnum.f64(double %t0, double %a2)
1069  %t2 = call double @llvm.maxnum.f64(double %t1, double %a3)
1070  ret double %t2
1071}
1072
1073declare i8 @llvm.umin.i8(i8 %a, i8 %b)
1074declare i16 @llvm.umin.i16(i16 %a, i16 %b)
1075declare i32 @llvm.umin.i32(i32 %a, i32 %b)
1076declare i64 @llvm.umin.i64(i64 %a, i64 %b)
1077declare i8 @llvm.smin.i8(i8 %a, i8 %b)
1078declare i16 @llvm.smin.i16(i16 %a, i16 %b)
1079declare i32 @llvm.smin.i32(i32 %a, i32 %b)
1080declare i64 @llvm.smin.i64(i64 %a, i64 %b)
1081declare i8 @llvm.umax.i8(i8 %a, i8 %b)
1082declare i16 @llvm.umax.i16(i16 %a, i16 %b)
1083declare i32 @llvm.umax.i32(i32 %a, i32 %b)
1084declare i64 @llvm.umax.i64(i64 %a, i64 %b)
1085declare i8 @llvm.smax.i8(i8 %a, i8 %b)
1086declare i16 @llvm.smax.i16(i16 %a, i16 %b)
1087declare i32 @llvm.smax.i32(i32 %a, i32 %b)
1088declare i64 @llvm.smax.i64(i64 %a, i64 %b)
1089declare half @llvm.minnum.f16(half, half)
1090declare float @llvm.minnum.f32(float, float)
1091declare double @llvm.minnum.f64(double, double)
1092declare half @llvm.maxnum.f16(half, half)
1093declare float @llvm.maxnum.f32(float, float)
1094declare double @llvm.maxnum.f64(double, double)
1095
1096define double @test_fmadd_strategy(double %a0, double %a1, double %a2, double %a3, i64 %flag) {
1097; CHECK_LOCAL-LABEL: test_fmadd_strategy:
1098; CHECK_LOCAL:       # %bb.0: # %entry
1099; CHECK_LOCAL-NEXT:    fsub.d fa4, fa0, fa1
1100; CHECK_LOCAL-NEXT:    andi a0, a0, 1
1101; CHECK_LOCAL-NEXT:    fmv.d fa5, fa0
1102; CHECK_LOCAL-NEXT:    fmul.d fa0, fa4, fa2
1103; CHECK_LOCAL-NEXT:    beqz a0, .LBB76_2
1104; CHECK_LOCAL-NEXT:  # %bb.1: # %entry
1105; CHECK_LOCAL-NEXT:    fmul.d fa4, fa5, fa1
1106; CHECK_LOCAL-NEXT:    fmadd.d fa5, fa5, fa1, fa0
1107; CHECK_LOCAL-NEXT:    fsub.d fa0, fa5, fa4
1108; CHECK_LOCAL-NEXT:  .LBB76_2: # %entry
1109; CHECK_LOCAL-NEXT:    ret
1110;
1111; CHECK_GLOBAL-LABEL: test_fmadd_strategy:
1112; CHECK_GLOBAL:       # %bb.0: # %entry
1113; CHECK_GLOBAL-NEXT:    fsub.d fa4, fa0, fa1
1114; CHECK_GLOBAL-NEXT:    andi a0, a0, 1
1115; CHECK_GLOBAL-NEXT:    fmv.d fa5, fa0
1116; CHECK_GLOBAL-NEXT:    fmul.d fa0, fa4, fa2
1117; CHECK_GLOBAL-NEXT:    beqz a0, .LBB76_2
1118; CHECK_GLOBAL-NEXT:  # %bb.1: # %entry
1119; CHECK_GLOBAL-NEXT:    fmul.d fa5, fa5, fa1
1120; CHECK_GLOBAL-NEXT:    fadd.d fa4, fa5, fa0
1121; CHECK_GLOBAL-NEXT:    fsub.d fa0, fa4, fa5
1122; CHECK_GLOBAL-NEXT:  .LBB76_2: # %entry
1123; CHECK_GLOBAL-NEXT:    ret
1124entry:
1125  %sub = fsub contract double %a0, %a1
1126  %mul = fmul contract double %sub, %a2
1127  %and = and i64 %flag, 1
1128  %tobool.not = icmp eq i64 %and, 0
1129  %mul2 = fmul contract double %a0, %a1
1130  %add = fadd contract double %mul2, %mul
1131  %sub3 = fsub contract double %add, %mul2
1132  %retval.0 = select i1 %tobool.not, double %mul, double %sub3
1133  ret double %retval.0
1134}
1135