xref: /llvm-project/llvm/test/CodeGen/AArch64/frem-power2.ll (revision a284bdb31146160352da905a888da738f2661b50)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2; RUN: llc -mtriple=aarch64 -mattr=+fullfp16 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
3; RUN: llc -mtriple=aarch64 -mattr=+fullfp16 -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
4
5define float @frem2(float %x) {
6; CHECK-SD-LABEL: frem2:
7; CHECK-SD:       // %bb.0: // %entry
8; CHECK-SD-NEXT:    fmov s1, #0.50000000
9; CHECK-SD-NEXT:    // kill: def $s0 killed $s0 def $q0
10; CHECK-SD-NEXT:    fmov s2, #-2.00000000
11; CHECK-SD-NEXT:    fmul s1, s0, s1
12; CHECK-SD-NEXT:    frintz s1, s1
13; CHECK-SD-NEXT:    fmadd s1, s1, s2, s0
14; CHECK-SD-NEXT:    mvni v2.4s, #128, lsl #24
15; CHECK-SD-NEXT:    bit v0.16b, v1.16b, v2.16b
16; CHECK-SD-NEXT:    // kill: def $s0 killed $s0 killed $q0
17; CHECK-SD-NEXT:    ret
18;
19; CHECK-GI-LABEL: frem2:
20; CHECK-GI:       // %bb.0: // %entry
21; CHECK-GI-NEXT:    fmov s1, #2.00000000
22; CHECK-GI-NEXT:    b fmodf
23entry:
24  %fmod = frem float %x, 2.0
25  ret float %fmod
26}
27
28define float @frem2_nsz(float %x) {
29; CHECK-SD-LABEL: frem2_nsz:
30; CHECK-SD:       // %bb.0: // %entry
31; CHECK-SD-NEXT:    fmov s1, #0.50000000
32; CHECK-SD-NEXT:    fmov s2, #-2.00000000
33; CHECK-SD-NEXT:    fmul s1, s0, s1
34; CHECK-SD-NEXT:    frintz s1, s1
35; CHECK-SD-NEXT:    fmadd s0, s1, s2, s0
36; CHECK-SD-NEXT:    ret
37;
38; CHECK-GI-LABEL: frem2_nsz:
39; CHECK-GI:       // %bb.0: // %entry
40; CHECK-GI-NEXT:    fmov s1, #2.00000000
41; CHECK-GI-NEXT:    b fmodf
42entry:
43  %fmod = frem nsz float %x, 2.0
44  ret float %fmod
45}
46
47define float @frem2_fast(float %x) {
48; CHECK-SD-LABEL: frem2_fast:
49; CHECK-SD:       // %bb.0: // %entry
50; CHECK-SD-NEXT:    fmov s1, #0.50000000
51; CHECK-SD-NEXT:    fmov s2, #-2.00000000
52; CHECK-SD-NEXT:    fmul s1, s0, s1
53; CHECK-SD-NEXT:    frintz s1, s1
54; CHECK-SD-NEXT:    fmadd s0, s1, s2, s0
55; CHECK-SD-NEXT:    ret
56;
57; CHECK-GI-LABEL: frem2_fast:
58; CHECK-GI:       // %bb.0: // %entry
59; CHECK-GI-NEXT:    fmov s1, #2.00000000
60; CHECK-GI-NEXT:    b fmodf
61entry:
62  %fmod = frem fast float %x, 2.0
63  ret float %fmod
64}
65
66define float @frem2_abs(float %x) {
67; CHECK-SD-LABEL: frem2_abs:
68; CHECK-SD:       // %bb.0: // %entry
69; CHECK-SD-NEXT:    fabs s0, s0
70; CHECK-SD-NEXT:    fmov s1, #0.50000000
71; CHECK-SD-NEXT:    fmov s2, #-2.00000000
72; CHECK-SD-NEXT:    fmul s1, s0, s1
73; CHECK-SD-NEXT:    frintz s1, s1
74; CHECK-SD-NEXT:    fmadd s0, s1, s2, s0
75; CHECK-SD-NEXT:    ret
76;
77; CHECK-GI-LABEL: frem2_abs:
78; CHECK-GI:       // %bb.0: // %entry
79; CHECK-GI-NEXT:    fabs s0, s0
80; CHECK-GI-NEXT:    fmov s1, #2.00000000
81; CHECK-GI-NEXT:    b fmodf
82entry:
83  %a = tail call float @llvm.fabs.f32(float %x)
84  %fmod = frem float %a, 2.0
85  ret float %fmod
86}
87
88define half @hrem2_nsz(half %x) {
89; CHECK-SD-LABEL: hrem2_nsz:
90; CHECK-SD:       // %bb.0: // %entry
91; CHECK-SD-NEXT:    fmov h1, #0.50000000
92; CHECK-SD-NEXT:    fmov h2, #-2.00000000
93; CHECK-SD-NEXT:    fmul h1, h0, h1
94; CHECK-SD-NEXT:    frintz h1, h1
95; CHECK-SD-NEXT:    fmadd h0, h1, h2, h0
96; CHECK-SD-NEXT:    ret
97;
98; CHECK-GI-LABEL: hrem2_nsz:
99; CHECK-GI:       // %bb.0: // %entry
100; CHECK-GI-NEXT:    str x30, [sp, #-16]! // 8-byte Folded Spill
101; CHECK-GI-NEXT:    .cfi_def_cfa_offset 16
102; CHECK-GI-NEXT:    .cfi_offset w30, -16
103; CHECK-GI-NEXT:    fmov h1, #2.00000000
104; CHECK-GI-NEXT:    fcvt s0, h0
105; CHECK-GI-NEXT:    fcvt s1, h1
106; CHECK-GI-NEXT:    bl fmodf
107; CHECK-GI-NEXT:    fcvt h0, s0
108; CHECK-GI-NEXT:    ldr x30, [sp], #16 // 8-byte Folded Reload
109; CHECK-GI-NEXT:    ret
110entry:
111  %fmod = frem nsz half %x, 2.0
112  ret half %fmod
113}
114
115define double @drem2_nsz(double %x) {
116; CHECK-SD-LABEL: drem2_nsz:
117; CHECK-SD:       // %bb.0: // %entry
118; CHECK-SD-NEXT:    fmov d1, #0.50000000
119; CHECK-SD-NEXT:    fmov d2, #-2.00000000
120; CHECK-SD-NEXT:    fmul d1, d0, d1
121; CHECK-SD-NEXT:    frintz d1, d1
122; CHECK-SD-NEXT:    fmadd d0, d1, d2, d0
123; CHECK-SD-NEXT:    ret
124;
125; CHECK-GI-LABEL: drem2_nsz:
126; CHECK-GI:       // %bb.0: // %entry
127; CHECK-GI-NEXT:    fmov d1, #2.00000000
128; CHECK-GI-NEXT:    b fmod
129entry:
130  %fmod = frem nsz double %x, 2.0
131  ret double %fmod
132}
133
134define float @frem3_nsz(float %x) {
135; CHECK-LABEL: frem3_nsz:
136; CHECK:       // %bb.0: // %entry
137; CHECK-NEXT:    fmov s1, #3.00000000
138; CHECK-NEXT:    b fmodf
139entry:
140  %fmod = frem nsz float %x, 3.0
141  ret float %fmod
142}
143
144define float @frem05_nsz(float %x) {
145; CHECK-LABEL: frem05_nsz:
146; CHECK:       // %bb.0: // %entry
147; CHECK-NEXT:    fmov s1, #0.50000000
148; CHECK-NEXT:    b fmodf
149entry:
150  %fmod = frem nsz float %x, 0.5
151  ret float %fmod
152}
153
154define float @frem1_nsz(float %x) {
155; CHECK-SD-LABEL: frem1_nsz:
156; CHECK-SD:       // %bb.0: // %entry
157; CHECK-SD-NEXT:    frintz s1, s0
158; CHECK-SD-NEXT:    fsub s0, s0, s1
159; CHECK-SD-NEXT:    ret
160;
161; CHECK-GI-LABEL: frem1_nsz:
162; CHECK-GI:       // %bb.0: // %entry
163; CHECK-GI-NEXT:    fmov s1, #1.00000000
164; CHECK-GI-NEXT:    b fmodf
165entry:
166  %fmod = frem nsz float %x, 1.0
167  ret float %fmod
168}
169
170define float @frem0_nsz(float %x) {
171; CHECK-LABEL: frem0_nsz:
172; CHECK:       // %bb.0: // %entry
173; CHECK-NEXT:    movi d1, #0000000000000000
174; CHECK-NEXT:    b fmodf
175entry:
176  %fmod = frem nsz float %x, 0.0
177  ret float %fmod
178}
179
180define float @fremm2_nsz(float %x) {
181; CHECK-SD-LABEL: fremm2_nsz:
182; CHECK-SD:       // %bb.0: // %entry
183; CHECK-SD-NEXT:    fmov s1, #-0.50000000
184; CHECK-SD-NEXT:    fmov s2, #2.00000000
185; CHECK-SD-NEXT:    fmul s1, s0, s1
186; CHECK-SD-NEXT:    frintz s1, s1
187; CHECK-SD-NEXT:    fmadd s0, s1, s2, s0
188; CHECK-SD-NEXT:    ret
189;
190; CHECK-GI-LABEL: fremm2_nsz:
191; CHECK-GI:       // %bb.0: // %entry
192; CHECK-GI-NEXT:    fmov s1, #-2.00000000
193; CHECK-GI-NEXT:    b fmodf
194entry:
195  %fmod = frem nsz float %x, -2.0
196  ret float %fmod
197}
198
199define float @frem4_abs(float %x) {
200; CHECK-SD-LABEL: frem4_abs:
201; CHECK-SD:       // %bb.0: // %entry
202; CHECK-SD-NEXT:    fabs s0, s0
203; CHECK-SD-NEXT:    fmov s1, #0.25000000
204; CHECK-SD-NEXT:    fmov s2, #-4.00000000
205; CHECK-SD-NEXT:    fmul s1, s0, s1
206; CHECK-SD-NEXT:    frintz s1, s1
207; CHECK-SD-NEXT:    fmadd s0, s1, s2, s0
208; CHECK-SD-NEXT:    ret
209;
210; CHECK-GI-LABEL: frem4_abs:
211; CHECK-GI:       // %bb.0: // %entry
212; CHECK-GI-NEXT:    fabs s0, s0
213; CHECK-GI-NEXT:    fmov s1, #4.00000000
214; CHECK-GI-NEXT:    b fmodf
215entry:
216  %a = tail call float @llvm.fabs.f32(float %x)
217  %fmod = frem float %a, 4.0
218  ret float %fmod
219}
220
221define float @frem16_abs(float %x) {
222; CHECK-SD-LABEL: frem16_abs:
223; CHECK-SD:       // %bb.0: // %entry
224; CHECK-SD-NEXT:    fabs s0, s0
225; CHECK-SD-NEXT:    mov w8, #1031798784 // =0x3d800000
226; CHECK-SD-NEXT:    fmov s2, #-16.00000000
227; CHECK-SD-NEXT:    fmov s1, w8
228; CHECK-SD-NEXT:    fmul s1, s0, s1
229; CHECK-SD-NEXT:    frintz s1, s1
230; CHECK-SD-NEXT:    fmadd s0, s1, s2, s0
231; CHECK-SD-NEXT:    ret
232;
233; CHECK-GI-LABEL: frem16_abs:
234; CHECK-GI:       // %bb.0: // %entry
235; CHECK-GI-NEXT:    fabs s0, s0
236; CHECK-GI-NEXT:    fmov s1, #16.00000000
237; CHECK-GI-NEXT:    b fmodf
238entry:
239  %a = tail call float @llvm.fabs.f32(float %x)
240  %fmod = frem float %a, 16.0
241  ret float %fmod
242}
243
244define float @frem4294967296_abs(float %x) {
245; CHECK-SD-LABEL: frem4294967296_abs:
246; CHECK-SD:       // %bb.0: // %entry
247; CHECK-SD-NEXT:    fabs s0, s0
248; CHECK-SD-NEXT:    mov w8, #796917760 // =0x2f800000
249; CHECK-SD-NEXT:    fmov s1, w8
250; CHECK-SD-NEXT:    mov w8, #-813694976 // =0xcf800000
251; CHECK-SD-NEXT:    fmov s2, w8
252; CHECK-SD-NEXT:    fmul s1, s0, s1
253; CHECK-SD-NEXT:    frintz s1, s1
254; CHECK-SD-NEXT:    fmadd s0, s1, s2, s0
255; CHECK-SD-NEXT:    ret
256;
257; CHECK-GI-LABEL: frem4294967296_abs:
258; CHECK-GI:       // %bb.0: // %entry
259; CHECK-GI-NEXT:    fabs s0, s0
260; CHECK-GI-NEXT:    mov w8, #1333788672 // =0x4f800000
261; CHECK-GI-NEXT:    fmov s1, w8
262; CHECK-GI-NEXT:    b fmodf
263entry:
264  %a = tail call float @llvm.fabs.f32(float %x)
265  %fmod = frem float %a, 4294967296.0
266  ret float %fmod
267}
268
269define float @frem1152921504606846976_abs(float %x) {
270; CHECK-SD-LABEL: frem1152921504606846976_abs:
271; CHECK-SD:       // %bb.0: // %entry
272; CHECK-SD-NEXT:    fabs s0, s0
273; CHECK-SD-NEXT:    mov w8, #562036736 // =0x21800000
274; CHECK-SD-NEXT:    fmov s1, w8
275; CHECK-SD-NEXT:    mov w8, #-578813952 // =0xdd800000
276; CHECK-SD-NEXT:    fmov s2, w8
277; CHECK-SD-NEXT:    fmul s1, s0, s1
278; CHECK-SD-NEXT:    frintz s1, s1
279; CHECK-SD-NEXT:    fmadd s0, s1, s2, s0
280; CHECK-SD-NEXT:    ret
281;
282; CHECK-GI-LABEL: frem1152921504606846976_abs:
283; CHECK-GI:       // %bb.0: // %entry
284; CHECK-GI-NEXT:    fabs s0, s0
285; CHECK-GI-NEXT:    mov w8, #1568669696 // =0x5d800000
286; CHECK-GI-NEXT:    fmov s1, w8
287; CHECK-GI-NEXT:    b fmodf
288entry:
289  %a = tail call float @llvm.fabs.f32(float %x)
290  %fmod = frem float %a, 1152921504606846976.0
291  ret float %fmod
292}
293
294define float @frem4611686018427387904_abs(float %x) {
295; CHECK-SD-LABEL: frem4611686018427387904_abs:
296; CHECK-SD:       // %bb.0: // %entry
297; CHECK-SD-NEXT:    fabs s0, s0
298; CHECK-SD-NEXT:    mov w8, #545259520 // =0x20800000
299; CHECK-SD-NEXT:    fmov s1, w8
300; CHECK-SD-NEXT:    mov w8, #-562036736 // =0xde800000
301; CHECK-SD-NEXT:    fmov s2, w8
302; CHECK-SD-NEXT:    fmul s1, s0, s1
303; CHECK-SD-NEXT:    frintz s1, s1
304; CHECK-SD-NEXT:    fmadd s0, s1, s2, s0
305; CHECK-SD-NEXT:    ret
306;
307; CHECK-GI-LABEL: frem4611686018427387904_abs:
308; CHECK-GI:       // %bb.0: // %entry
309; CHECK-GI-NEXT:    fabs s0, s0
310; CHECK-GI-NEXT:    mov w8, #1585446912 // =0x5e800000
311; CHECK-GI-NEXT:    fmov s1, w8
312; CHECK-GI-NEXT:    b fmodf
313entry:
314  %a = tail call float @llvm.fabs.f32(float %x)
315  %fmod = frem float %a, 4611686018427387904.0
316  ret float %fmod
317}
318
319define float @frem9223372036854775808_abs(float %x) {
320; CHECK-SD-LABEL: frem9223372036854775808_abs:
321; CHECK-SD:       // %bb.0: // %entry
322; CHECK-SD-NEXT:    movi v1.2s, #32, lsl #24
323; CHECK-SD-NEXT:    fabs s0, s0
324; CHECK-SD-NEXT:    movi v2.2s, #223, lsl #24
325; CHECK-SD-NEXT:    fmul s1, s0, s1
326; CHECK-SD-NEXT:    frintz s1, s1
327; CHECK-SD-NEXT:    fmadd s0, s1, s2, s0
328; CHECK-SD-NEXT:    ret
329;
330; CHECK-GI-LABEL: frem9223372036854775808_abs:
331; CHECK-GI:       // %bb.0: // %entry
332; CHECK-GI-NEXT:    fabs s0, s0
333; CHECK-GI-NEXT:    movi v1.2s, #95, lsl #24
334; CHECK-GI-NEXT:    b fmodf
335entry:
336  %a = tail call float @llvm.fabs.f32(float %x)
337  %fmod = frem float %a, 9223372036854775808.0
338  ret float %fmod
339}
340
341define <4 x float> @frem2_vec(<4 x float> %x) {
342; CHECK-SD-LABEL: frem2_vec:
343; CHECK-SD:       // %bb.0: // %entry
344; CHECK-SD-NEXT:    movi v1.4s, #63, lsl #24
345; CHECK-SD-NEXT:    movi v2.4s, #64, lsl #24
346; CHECK-SD-NEXT:    mov v3.16b, v0.16b
347; CHECK-SD-NEXT:    fmul v1.4s, v0.4s, v1.4s
348; CHECK-SD-NEXT:    frintz v1.4s, v1.4s
349; CHECK-SD-NEXT:    fmls v3.4s, v2.4s, v1.4s
350; CHECK-SD-NEXT:    mvni v1.4s, #128, lsl #24
351; CHECK-SD-NEXT:    bit v0.16b, v3.16b, v1.16b
352; CHECK-SD-NEXT:    ret
353;
354; CHECK-GI-LABEL: frem2_vec:
355; CHECK-GI:       // %bb.0: // %entry
356; CHECK-GI-NEXT:    sub sp, sp, #80
357; CHECK-GI-NEXT:    str d10, [sp, #48] // 8-byte Folded Spill
358; CHECK-GI-NEXT:    stp d9, d8, [sp, #56] // 16-byte Folded Spill
359; CHECK-GI-NEXT:    str x30, [sp, #72] // 8-byte Folded Spill
360; CHECK-GI-NEXT:    .cfi_def_cfa_offset 80
361; CHECK-GI-NEXT:    .cfi_offset w30, -8
362; CHECK-GI-NEXT:    .cfi_offset b8, -16
363; CHECK-GI-NEXT:    .cfi_offset b9, -24
364; CHECK-GI-NEXT:    .cfi_offset b10, -32
365; CHECK-GI-NEXT:    fmov s1, #2.00000000
366; CHECK-GI-NEXT:    mov s8, v0.s[1]
367; CHECK-GI-NEXT:    mov s9, v0.s[2]
368; CHECK-GI-NEXT:    mov s10, v0.s[3]
369; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 killed $q0
370; CHECK-GI-NEXT:    bl fmodf
371; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
372; CHECK-GI-NEXT:    str q0, [sp, #32] // 16-byte Folded Spill
373; CHECK-GI-NEXT:    fmov s1, #2.00000000
374; CHECK-GI-NEXT:    fmov s0, s8
375; CHECK-GI-NEXT:    bl fmodf
376; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
377; CHECK-GI-NEXT:    str q0, [sp, #16] // 16-byte Folded Spill
378; CHECK-GI-NEXT:    fmov s1, #2.00000000
379; CHECK-GI-NEXT:    fmov s0, s9
380; CHECK-GI-NEXT:    bl fmodf
381; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
382; CHECK-GI-NEXT:    str q0, [sp] // 16-byte Folded Spill
383; CHECK-GI-NEXT:    fmov s1, #2.00000000
384; CHECK-GI-NEXT:    fmov s0, s10
385; CHECK-GI-NEXT:    bl fmodf
386; CHECK-GI-NEXT:    ldp q2, q1, [sp, #16] // 32-byte Folded Reload
387; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
388; CHECK-GI-NEXT:    ldr x30, [sp, #72] // 8-byte Folded Reload
389; CHECK-GI-NEXT:    ldp d9, d8, [sp, #56] // 16-byte Folded Reload
390; CHECK-GI-NEXT:    ldr d10, [sp, #48] // 8-byte Folded Reload
391; CHECK-GI-NEXT:    mov v1.s[1], v2.s[0]
392; CHECK-GI-NEXT:    ldr q2, [sp] // 16-byte Folded Reload
393; CHECK-GI-NEXT:    mov v1.s[2], v2.s[0]
394; CHECK-GI-NEXT:    mov v1.s[3], v0.s[0]
395; CHECK-GI-NEXT:    mov v0.16b, v1.16b
396; CHECK-GI-NEXT:    add sp, sp, #80
397; CHECK-GI-NEXT:    ret
398entry:
399  %fmod = frem <4 x float> %x, <float 2.0, float 2.0, float 2.0, float 2.0>
400  ret <4 x float> %fmod
401}
402
403define <4 x float> @frem2_nsz_vec(<4 x float> %x) {
404; CHECK-SD-LABEL: frem2_nsz_vec:
405; CHECK-SD:       // %bb.0: // %entry
406; CHECK-SD-NEXT:    movi v1.4s, #63, lsl #24
407; CHECK-SD-NEXT:    movi v2.4s, #64, lsl #24
408; CHECK-SD-NEXT:    fmul v1.4s, v0.4s, v1.4s
409; CHECK-SD-NEXT:    frintz v1.4s, v1.4s
410; CHECK-SD-NEXT:    fmls v0.4s, v2.4s, v1.4s
411; CHECK-SD-NEXT:    ret
412;
413; CHECK-GI-LABEL: frem2_nsz_vec:
414; CHECK-GI:       // %bb.0: // %entry
415; CHECK-GI-NEXT:    sub sp, sp, #80
416; CHECK-GI-NEXT:    str d10, [sp, #48] // 8-byte Folded Spill
417; CHECK-GI-NEXT:    stp d9, d8, [sp, #56] // 16-byte Folded Spill
418; CHECK-GI-NEXT:    str x30, [sp, #72] // 8-byte Folded Spill
419; CHECK-GI-NEXT:    .cfi_def_cfa_offset 80
420; CHECK-GI-NEXT:    .cfi_offset w30, -8
421; CHECK-GI-NEXT:    .cfi_offset b8, -16
422; CHECK-GI-NEXT:    .cfi_offset b9, -24
423; CHECK-GI-NEXT:    .cfi_offset b10, -32
424; CHECK-GI-NEXT:    fmov s1, #2.00000000
425; CHECK-GI-NEXT:    mov s8, v0.s[1]
426; CHECK-GI-NEXT:    mov s9, v0.s[2]
427; CHECK-GI-NEXT:    mov s10, v0.s[3]
428; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 killed $q0
429; CHECK-GI-NEXT:    bl fmodf
430; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
431; CHECK-GI-NEXT:    str q0, [sp, #32] // 16-byte Folded Spill
432; CHECK-GI-NEXT:    fmov s1, #2.00000000
433; CHECK-GI-NEXT:    fmov s0, s8
434; CHECK-GI-NEXT:    bl fmodf
435; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
436; CHECK-GI-NEXT:    str q0, [sp, #16] // 16-byte Folded Spill
437; CHECK-GI-NEXT:    fmov s1, #2.00000000
438; CHECK-GI-NEXT:    fmov s0, s9
439; CHECK-GI-NEXT:    bl fmodf
440; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
441; CHECK-GI-NEXT:    str q0, [sp] // 16-byte Folded Spill
442; CHECK-GI-NEXT:    fmov s1, #2.00000000
443; CHECK-GI-NEXT:    fmov s0, s10
444; CHECK-GI-NEXT:    bl fmodf
445; CHECK-GI-NEXT:    ldp q2, q1, [sp, #16] // 32-byte Folded Reload
446; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
447; CHECK-GI-NEXT:    ldr x30, [sp, #72] // 8-byte Folded Reload
448; CHECK-GI-NEXT:    ldp d9, d8, [sp, #56] // 16-byte Folded Reload
449; CHECK-GI-NEXT:    ldr d10, [sp, #48] // 8-byte Folded Reload
450; CHECK-GI-NEXT:    mov v1.s[1], v2.s[0]
451; CHECK-GI-NEXT:    ldr q2, [sp] // 16-byte Folded Reload
452; CHECK-GI-NEXT:    mov v1.s[2], v2.s[0]
453; CHECK-GI-NEXT:    mov v1.s[3], v0.s[0]
454; CHECK-GI-NEXT:    mov v0.16b, v1.16b
455; CHECK-GI-NEXT:    add sp, sp, #80
456; CHECK-GI-NEXT:    ret
457entry:
458  %fmod = frem nsz <4 x float> %x, <float 2.0, float 2.0, float 2.0, float 2.0>
459  ret <4 x float> %fmod
460}
461
462define <4 x float> @frem1152921504606846976_absv(<4 x float> %x) {
463; CHECK-SD-LABEL: frem1152921504606846976_absv:
464; CHECK-SD:       // %bb.0: // %entry
465; CHECK-SD-NEXT:    mov w8, #562036736 // =0x21800000
466; CHECK-SD-NEXT:    fabs v0.4s, v0.4s
467; CHECK-SD-NEXT:    dup v1.4s, w8
468; CHECK-SD-NEXT:    mov w8, #1568669696 // =0x5d800000
469; CHECK-SD-NEXT:    dup v2.4s, w8
470; CHECK-SD-NEXT:    fmul v1.4s, v0.4s, v1.4s
471; CHECK-SD-NEXT:    frintz v1.4s, v1.4s
472; CHECK-SD-NEXT:    fmls v0.4s, v2.4s, v1.4s
473; CHECK-SD-NEXT:    ret
474;
475; CHECK-GI-LABEL: frem1152921504606846976_absv:
476; CHECK-GI:       // %bb.0: // %entry
477; CHECK-GI-NEXT:    sub sp, sp, #96
478; CHECK-GI-NEXT:    stp d11, d10, [sp, #48] // 16-byte Folded Spill
479; CHECK-GI-NEXT:    stp d9, d8, [sp, #64] // 16-byte Folded Spill
480; CHECK-GI-NEXT:    str x30, [sp, #80] // 8-byte Folded Spill
481; CHECK-GI-NEXT:    .cfi_def_cfa_offset 96
482; CHECK-GI-NEXT:    .cfi_offset w30, -16
483; CHECK-GI-NEXT:    .cfi_offset b8, -24
484; CHECK-GI-NEXT:    .cfi_offset b9, -32
485; CHECK-GI-NEXT:    .cfi_offset b10, -40
486; CHECK-GI-NEXT:    .cfi_offset b11, -48
487; CHECK-GI-NEXT:    mov w8, #1568669696 // =0x5d800000
488; CHECK-GI-NEXT:    fabs v0.4s, v0.4s
489; CHECK-GI-NEXT:    fmov s11, w8
490; CHECK-GI-NEXT:    fmov s1, s11
491; CHECK-GI-NEXT:    mov s8, v0.s[1]
492; CHECK-GI-NEXT:    mov s9, v0.s[2]
493; CHECK-GI-NEXT:    mov s10, v0.s[3]
494; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 killed $q0
495; CHECK-GI-NEXT:    bl fmodf
496; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
497; CHECK-GI-NEXT:    str q0, [sp, #32] // 16-byte Folded Spill
498; CHECK-GI-NEXT:    fmov s1, s11
499; CHECK-GI-NEXT:    fmov s0, s8
500; CHECK-GI-NEXT:    bl fmodf
501; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
502; CHECK-GI-NEXT:    str q0, [sp, #16] // 16-byte Folded Spill
503; CHECK-GI-NEXT:    fmov s1, s11
504; CHECK-GI-NEXT:    fmov s0, s9
505; CHECK-GI-NEXT:    bl fmodf
506; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
507; CHECK-GI-NEXT:    str q0, [sp] // 16-byte Folded Spill
508; CHECK-GI-NEXT:    fmov s1, s11
509; CHECK-GI-NEXT:    fmov s0, s10
510; CHECK-GI-NEXT:    bl fmodf
511; CHECK-GI-NEXT:    ldp q2, q1, [sp, #16] // 32-byte Folded Reload
512; CHECK-GI-NEXT:    // kill: def $s0 killed $s0 def $q0
513; CHECK-GI-NEXT:    ldr x30, [sp, #80] // 8-byte Folded Reload
514; CHECK-GI-NEXT:    ldp d9, d8, [sp, #64] // 16-byte Folded Reload
515; CHECK-GI-NEXT:    ldp d11, d10, [sp, #48] // 16-byte Folded Reload
516; CHECK-GI-NEXT:    mov v1.s[1], v2.s[0]
517; CHECK-GI-NEXT:    ldr q2, [sp] // 16-byte Folded Reload
518; CHECK-GI-NEXT:    mov v1.s[2], v2.s[0]
519; CHECK-GI-NEXT:    mov v1.s[3], v0.s[0]
520; CHECK-GI-NEXT:    mov v0.16b, v1.16b
521; CHECK-GI-NEXT:    add sp, sp, #96
522; CHECK-GI-NEXT:    ret
523entry:
524  %a = tail call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
525  %fmod = frem <4 x float> %a, <float 1152921504606846976.0, float 1152921504606846976.0, float 1152921504606846976.0, float 1152921504606846976.0>
526  ret <4 x float> %fmod
527}
528
529define float @frem2_nsz_sitofp(float %x, i32 %sa) {
530; CHECK-SD-LABEL: frem2_nsz_sitofp:
531; CHECK-SD:       // %bb.0: // %entry
532; CHECK-SD-NEXT:    mov w8, #1 // =0x1
533; CHECK-SD-NEXT:    lsl w8, w8, w0
534; CHECK-SD-NEXT:    scvtf s1, w8
535; CHECK-SD-NEXT:    fdiv s2, s0, s1
536; CHECK-SD-NEXT:    frintz s2, s2
537; CHECK-SD-NEXT:    fmsub s0, s2, s1, s0
538; CHECK-SD-NEXT:    ret
539;
540; CHECK-GI-LABEL: frem2_nsz_sitofp:
541; CHECK-GI:       // %bb.0: // %entry
542; CHECK-GI-NEXT:    mov w8, #1 // =0x1
543; CHECK-GI-NEXT:    lsl w8, w8, w0
544; CHECK-GI-NEXT:    scvtf s1, w8
545; CHECK-GI-NEXT:    b fmodf
546entry:
547  %s = shl i32 1, %sa
548  %y = sitofp i32 %s to float
549  %fmod = frem nsz float %x, %y
550  ret float %fmod
551}
552
553define float @frem2_nsz_uitofp(float %x, i32 %sa) {
554; CHECK-SD-LABEL: frem2_nsz_uitofp:
555; CHECK-SD:       // %bb.0: // %entry
556; CHECK-SD-NEXT:    mov w8, #1 // =0x1
557; CHECK-SD-NEXT:    lsl w8, w8, w0
558; CHECK-SD-NEXT:    ucvtf s1, w8
559; CHECK-SD-NEXT:    fdiv s2, s0, s1
560; CHECK-SD-NEXT:    frintz s2, s2
561; CHECK-SD-NEXT:    fmsub s0, s2, s1, s0
562; CHECK-SD-NEXT:    ret
563;
564; CHECK-GI-LABEL: frem2_nsz_uitofp:
565; CHECK-GI:       // %bb.0: // %entry
566; CHECK-GI-NEXT:    mov w8, #1 // =0x1
567; CHECK-GI-NEXT:    lsl w8, w8, w0
568; CHECK-GI-NEXT:    ucvtf s1, w8
569; CHECK-GI-NEXT:    b fmodf
570entry:
571  %s = shl i32 1, %sa
572  %y = uitofp i32 %s to float
573  %fmod = frem nsz float %x, %y
574  ret float %fmod
575}
576
577define float @frem2_const_sitofp(float %x, i32 %sa) {
578; CHECK-SD-LABEL: frem2_const_sitofp:
579; CHECK-SD:       // %bb.0: // %entry
580; CHECK-SD-NEXT:    mov w8, #1 // =0x1
581; CHECK-SD-NEXT:    fmov s1, #12.50000000
582; CHECK-SD-NEXT:    lsl w8, w8, w0
583; CHECK-SD-NEXT:    scvtf s0, w8
584; CHECK-SD-NEXT:    fdiv s2, s1, s0
585; CHECK-SD-NEXT:    frintz s2, s2
586; CHECK-SD-NEXT:    fmsub s0, s2, s0, s1
587; CHECK-SD-NEXT:    ret
588;
589; CHECK-GI-LABEL: frem2_const_sitofp:
590; CHECK-GI:       // %bb.0: // %entry
591; CHECK-GI-NEXT:    mov w8, #1 // =0x1
592; CHECK-GI-NEXT:    and w9, w0, #0x1f
593; CHECK-GI-NEXT:    fmov s0, #12.50000000
594; CHECK-GI-NEXT:    lsl w8, w8, w9
595; CHECK-GI-NEXT:    scvtf s1, w8
596; CHECK-GI-NEXT:    b fmodf
597entry:
598  %sa2 = and i32 %sa, 31
599  %s = shl i32 1, %sa2
600  %y = sitofp i32 %s to float
601  %fmod = frem float 12.50, %y
602  ret float %fmod
603}
604
605define float @frem2_constneg_sitofp(float %x, i32 %sa) {
606; CHECK-SD-LABEL: frem2_constneg_sitofp:
607; CHECK-SD:       // %bb.0: // %entry
608; CHECK-SD-NEXT:    mov w8, #1 // =0x1
609; CHECK-SD-NEXT:    fmov s1, #-12.50000000
610; CHECK-SD-NEXT:    lsl w8, w8, w0
611; CHECK-SD-NEXT:    scvtf s0, w8
612; CHECK-SD-NEXT:    fdiv s2, s1, s0
613; CHECK-SD-NEXT:    frintz s2, s2
614; CHECK-SD-NEXT:    fmsub s0, s2, s0, s1
615; CHECK-SD-NEXT:    fabs s0, s0
616; CHECK-SD-NEXT:    fneg s0, s0
617; CHECK-SD-NEXT:    ret
618;
619; CHECK-GI-LABEL: frem2_constneg_sitofp:
620; CHECK-GI:       // %bb.0: // %entry
621; CHECK-GI-NEXT:    mov w8, #1 // =0x1
622; CHECK-GI-NEXT:    and w9, w0, #0x1f
623; CHECK-GI-NEXT:    fmov s0, #-12.50000000
624; CHECK-GI-NEXT:    lsl w8, w8, w9
625; CHECK-GI-NEXT:    scvtf s1, w8
626; CHECK-GI-NEXT:    b fmodf
627entry:
628  %sa2 = and i32 %sa, 31
629  %s = shl i32 1, %sa2
630  %y = sitofp i32 %s to float
631  %fmod = frem float -12.50, %y
632  ret float %fmod
633}
634