; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 ; RUN: llc -mtriple=aarch64 -mattr=+fullfp16 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD ; RUN: llc -mtriple=aarch64 -mattr=+fullfp16 -global-isel -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI define float @frem2(float %x) { ; CHECK-SD-LABEL: frem2: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fmov s1, #0.50000000 ; CHECK-SD-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-SD-NEXT: fmov s2, #-2.00000000 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s1, s1, s2, s0 ; CHECK-SD-NEXT: mvni v2.4s, #128, lsl #24 ; CHECK-SD-NEXT: bit v0.16b, v1.16b, v2.16b ; CHECK-SD-NEXT: // kill: def $s0 killed $s0 killed $q0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: b fmodf entry: %fmod = frem float %x, 2.0 ret float %fmod } define float @frem2_nsz(float %x) { ; CHECK-SD-LABEL: frem2_nsz: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fmov s1, #0.50000000 ; CHECK-SD-NEXT: fmov s2, #-2.00000000 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_nsz: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: b fmodf entry: %fmod = frem nsz float %x, 2.0 ret float %fmod } define float @frem2_fast(float %x) { ; CHECK-SD-LABEL: frem2_fast: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fmov s1, #0.50000000 ; CHECK-SD-NEXT: fmov s2, #-2.00000000 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_fast: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: b fmodf entry: %fmod = frem fast float %x, 2.0 ret float %fmod } define float @frem2_abs(float %x) { ; CHECK-SD-LABEL: frem2_abs: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fabs s0, s0 ; CHECK-SD-NEXT: fmov s1, #0.50000000 ; CHECK-SD-NEXT: fmov s2, #-2.00000000 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_abs: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fabs s0, s0 ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: b fmodf entry: %a = tail call float @llvm.fabs.f32(float %x) %fmod = frem float %a, 2.0 ret float %fmod } define float @frem2_exp(float %x) #0 { ; CHECK-SD-LABEL: frem2_exp: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill ; CHECK-SD-NEXT: bl expf ; CHECK-SD-NEXT: fmov s1, #0.50000000 ; CHECK-SD-NEXT: fmov s2, #-2.00000000 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_exp: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill ; CHECK-GI-NEXT: bl expf ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-GI-NEXT: b fmodf entry: %a = tail call float @llvm.exp.f32(float %x) %fmod = frem float %a, 2.0 ret float %fmod } define float @frem2_exp2(float %x) #0 { ; CHECK-SD-LABEL: frem2_exp2: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill ; CHECK-SD-NEXT: bl exp2f ; CHECK-SD-NEXT: fmov s1, #0.50000000 ; CHECK-SD-NEXT: fmov s2, #-2.00000000 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_exp2: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill ; CHECK-GI-NEXT: bl exp2f ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-GI-NEXT: b fmodf entry: %a = tail call float @llvm.exp2.f32(float %x) %fmod = frem float %a, 2.0 ret float %fmod } define float @frem2_exp10(float %x) #0 { ; CHECK-SD-LABEL: frem2_exp10: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill ; CHECK-SD-NEXT: bl exp10f ; CHECK-SD-NEXT: fmov s1, #0.50000000 ; CHECK-SD-NEXT: fmov s2, #-2.00000000 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_exp10: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill ; CHECK-GI-NEXT: bl exp10f ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-GI-NEXT: b fmodf entry: %a = tail call float @llvm.exp10.f32(float %x) %fmod = frem float %a, 2.0 ret float %fmod } define half @hrem2_nsz(half %x) { ; CHECK-SD-LABEL: hrem2_nsz: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fmov h1, #0.50000000 ; CHECK-SD-NEXT: fmov h2, #-2.00000000 ; CHECK-SD-NEXT: fmul h1, h0, h1 ; CHECK-SD-NEXT: frintz h1, h1 ; CHECK-SD-NEXT: fmadd h0, h1, h2, h0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: hrem2_nsz: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill ; CHECK-GI-NEXT: .cfi_def_cfa_offset 16 ; CHECK-GI-NEXT: .cfi_offset w30, -16 ; CHECK-GI-NEXT: fcvt s0, h0 ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: fcvt h0, s0 ; CHECK-GI-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload ; CHECK-GI-NEXT: ret entry: %fmod = frem nsz half %x, 2.0 ret half %fmod } define double @drem2_nsz(double %x) { ; CHECK-SD-LABEL: drem2_nsz: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fmov d1, #0.50000000 ; CHECK-SD-NEXT: fmov d2, #-2.00000000 ; CHECK-SD-NEXT: fmul d1, d0, d1 ; CHECK-SD-NEXT: frintz d1, d1 ; CHECK-SD-NEXT: fmadd d0, d1, d2, d0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: drem2_nsz: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fmov d1, #2.00000000 ; CHECK-GI-NEXT: b fmod entry: %fmod = frem nsz double %x, 2.0 ret double %fmod } define float @frem3_nsz(float %x) { ; CHECK-LABEL: frem3_nsz: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: fmov s1, #3.00000000 ; CHECK-NEXT: b fmodf entry: %fmod = frem nsz float %x, 3.0 ret float %fmod } define float @frem05_nsz(float %x) { ; CHECK-LABEL: frem05_nsz: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: fmov s1, #0.50000000 ; CHECK-NEXT: b fmodf entry: %fmod = frem nsz float %x, 0.5 ret float %fmod } define float @frem1_nsz(float %x) { ; CHECK-SD-LABEL: frem1_nsz: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: frintz s1, s0 ; CHECK-SD-NEXT: fsub s0, s0, s1 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem1_nsz: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fmov s1, #1.00000000 ; CHECK-GI-NEXT: b fmodf entry: %fmod = frem nsz float %x, 1.0 ret float %fmod } define float @frem0_nsz(float %x) { ; CHECK-LABEL: frem0_nsz: ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: movi d1, #0000000000000000 ; CHECK-NEXT: b fmodf entry: %fmod = frem nsz float %x, 0.0 ret float %fmod } define float @fremm2_nsz(float %x) { ; CHECK-SD-LABEL: fremm2_nsz: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fmov s1, #-0.50000000 ; CHECK-SD-NEXT: fmov s2, #2.00000000 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: fremm2_nsz: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fmov s1, #-2.00000000 ; CHECK-GI-NEXT: b fmodf entry: %fmod = frem nsz float %x, -2.0 ret float %fmod } define float @frem4_abs(float %x) { ; CHECK-SD-LABEL: frem4_abs: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fabs s0, s0 ; CHECK-SD-NEXT: fmov s1, #0.25000000 ; CHECK-SD-NEXT: fmov s2, #-4.00000000 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem4_abs: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fabs s0, s0 ; CHECK-GI-NEXT: fmov s1, #4.00000000 ; CHECK-GI-NEXT: b fmodf entry: %a = tail call float @llvm.fabs.f32(float %x) %fmod = frem float %a, 4.0 ret float %fmod } define float @frem16_abs(float %x) { ; CHECK-SD-LABEL: frem16_abs: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fabs s0, s0 ; CHECK-SD-NEXT: mov w8, #1031798784 // =0x3d800000 ; CHECK-SD-NEXT: fmov s2, #-16.00000000 ; CHECK-SD-NEXT: fmov s1, w8 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem16_abs: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fabs s0, s0 ; CHECK-GI-NEXT: fmov s1, #16.00000000 ; CHECK-GI-NEXT: b fmodf entry: %a = tail call float @llvm.fabs.f32(float %x) %fmod = frem float %a, 16.0 ret float %fmod } define float @frem4294967296_abs(float %x) { ; CHECK-SD-LABEL: frem4294967296_abs: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fabs s0, s0 ; CHECK-SD-NEXT: mov w8, #796917760 // =0x2f800000 ; CHECK-SD-NEXT: fmov s1, w8 ; CHECK-SD-NEXT: mov w8, #-813694976 // =0xcf800000 ; CHECK-SD-NEXT: fmov s2, w8 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem4294967296_abs: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fabs s0, s0 ; CHECK-GI-NEXT: mov w8, #1333788672 // =0x4f800000 ; CHECK-GI-NEXT: fmov s1, w8 ; CHECK-GI-NEXT: b fmodf entry: %a = tail call float @llvm.fabs.f32(float %x) %fmod = frem float %a, 4294967296.0 ret float %fmod } define float @frem1152921504606846976_abs(float %x) { ; CHECK-SD-LABEL: frem1152921504606846976_abs: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fabs s0, s0 ; CHECK-SD-NEXT: mov w8, #562036736 // =0x21800000 ; CHECK-SD-NEXT: fmov s1, w8 ; CHECK-SD-NEXT: mov w8, #-578813952 // =0xdd800000 ; CHECK-SD-NEXT: fmov s2, w8 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem1152921504606846976_abs: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fabs s0, s0 ; CHECK-GI-NEXT: mov w8, #1568669696 // =0x5d800000 ; CHECK-GI-NEXT: fmov s1, w8 ; CHECK-GI-NEXT: b fmodf entry: %a = tail call float @llvm.fabs.f32(float %x) %fmod = frem float %a, 1152921504606846976.0 ret float %fmod } define float @frem4611686018427387904_abs(float %x) { ; CHECK-SD-LABEL: frem4611686018427387904_abs: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: fabs s0, s0 ; CHECK-SD-NEXT: mov w8, #545259520 // =0x20800000 ; CHECK-SD-NEXT: fmov s1, w8 ; CHECK-SD-NEXT: mov w8, #-562036736 // =0xde800000 ; CHECK-SD-NEXT: fmov s2, w8 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem4611686018427387904_abs: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fabs s0, s0 ; CHECK-GI-NEXT: mov w8, #1585446912 // =0x5e800000 ; CHECK-GI-NEXT: fmov s1, w8 ; CHECK-GI-NEXT: b fmodf entry: %a = tail call float @llvm.fabs.f32(float %x) %fmod = frem float %a, 4611686018427387904.0 ret float %fmod } define float @frem9223372036854775808_abs(float %x) { ; CHECK-SD-LABEL: frem9223372036854775808_abs: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: movi v1.2s, #32, lsl #24 ; CHECK-SD-NEXT: fabs s0, s0 ; CHECK-SD-NEXT: movi v2.2s, #223, lsl #24 ; CHECK-SD-NEXT: fmul s1, s0, s1 ; CHECK-SD-NEXT: frintz s1, s1 ; CHECK-SD-NEXT: fmadd s0, s1, s2, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem9223372036854775808_abs: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: fabs s0, s0 ; CHECK-GI-NEXT: movi v1.2s, #95, lsl #24 ; CHECK-GI-NEXT: b fmodf entry: %a = tail call float @llvm.fabs.f32(float %x) %fmod = frem float %a, 9223372036854775808.0 ret float %fmod } define <4 x float> @frem2_vec(<4 x float> %x) { ; CHECK-SD-LABEL: frem2_vec: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: movi v1.4s, #63, lsl #24 ; CHECK-SD-NEXT: movi v2.4s, #64, lsl #24 ; CHECK-SD-NEXT: mov v3.16b, v0.16b ; CHECK-SD-NEXT: fmul v1.4s, v0.4s, v1.4s ; CHECK-SD-NEXT: frintz v1.4s, v1.4s ; CHECK-SD-NEXT: fmls v3.4s, v2.4s, v1.4s ; CHECK-SD-NEXT: mvni v1.4s, #128, lsl #24 ; CHECK-SD-NEXT: bit v0.16b, v3.16b, v1.16b ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_vec: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: sub sp, sp, #80 ; CHECK-GI-NEXT: str d10, [sp, #48] // 8-byte Spill ; CHECK-GI-NEXT: stp d9, d8, [sp, #56] // 16-byte Folded Spill ; CHECK-GI-NEXT: str x30, [sp, #72] // 8-byte Spill ; CHECK-GI-NEXT: .cfi_def_cfa_offset 80 ; CHECK-GI-NEXT: .cfi_offset w30, -8 ; CHECK-GI-NEXT: .cfi_offset b8, -16 ; CHECK-GI-NEXT: .cfi_offset b9, -24 ; CHECK-GI-NEXT: .cfi_offset b10, -32 ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: mov s8, v0.s[1] ; CHECK-GI-NEXT: mov s9, v0.s[2] ; CHECK-GI-NEXT: mov s10, v0.s[3] ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 killed $q0 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: str q0, [sp, #32] // 16-byte Spill ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: fmov s0, s8 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: str q0, [sp, #16] // 16-byte Spill ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: fmov s0, s9 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: str q0, [sp] // 16-byte Spill ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: fmov s0, s10 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: ldp q2, q1, [sp, #16] // 32-byte Folded Reload ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: ldr x30, [sp, #72] // 8-byte Reload ; CHECK-GI-NEXT: ldp d9, d8, [sp, #56] // 16-byte Folded Reload ; CHECK-GI-NEXT: ldr d10, [sp, #48] // 8-byte Reload ; CHECK-GI-NEXT: mov v1.s[1], v2.s[0] ; CHECK-GI-NEXT: ldr q2, [sp] // 16-byte Reload ; CHECK-GI-NEXT: mov v1.s[2], v2.s[0] ; CHECK-GI-NEXT: mov v1.s[3], v0.s[0] ; CHECK-GI-NEXT: mov v0.16b, v1.16b ; CHECK-GI-NEXT: add sp, sp, #80 ; CHECK-GI-NEXT: ret entry: %fmod = frem <4 x float> %x, ret <4 x float> %fmod } define <4 x float> @frem2_nsz_vec(<4 x float> %x) { ; CHECK-SD-LABEL: frem2_nsz_vec: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: movi v1.4s, #63, lsl #24 ; CHECK-SD-NEXT: movi v2.4s, #64, lsl #24 ; CHECK-SD-NEXT: fmul v1.4s, v0.4s, v1.4s ; CHECK-SD-NEXT: frintz v1.4s, v1.4s ; CHECK-SD-NEXT: fmls v0.4s, v2.4s, v1.4s ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_nsz_vec: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: sub sp, sp, #80 ; CHECK-GI-NEXT: str d10, [sp, #48] // 8-byte Spill ; CHECK-GI-NEXT: stp d9, d8, [sp, #56] // 16-byte Folded Spill ; CHECK-GI-NEXT: str x30, [sp, #72] // 8-byte Spill ; CHECK-GI-NEXT: .cfi_def_cfa_offset 80 ; CHECK-GI-NEXT: .cfi_offset w30, -8 ; CHECK-GI-NEXT: .cfi_offset b8, -16 ; CHECK-GI-NEXT: .cfi_offset b9, -24 ; CHECK-GI-NEXT: .cfi_offset b10, -32 ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: mov s8, v0.s[1] ; CHECK-GI-NEXT: mov s9, v0.s[2] ; CHECK-GI-NEXT: mov s10, v0.s[3] ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 killed $q0 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: str q0, [sp, #32] // 16-byte Spill ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: fmov s0, s8 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: str q0, [sp, #16] // 16-byte Spill ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: fmov s0, s9 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: str q0, [sp] // 16-byte Spill ; CHECK-GI-NEXT: fmov s1, #2.00000000 ; CHECK-GI-NEXT: fmov s0, s10 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: ldp q2, q1, [sp, #16] // 32-byte Folded Reload ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: ldr x30, [sp, #72] // 8-byte Reload ; CHECK-GI-NEXT: ldp d9, d8, [sp, #56] // 16-byte Folded Reload ; CHECK-GI-NEXT: ldr d10, [sp, #48] // 8-byte Reload ; CHECK-GI-NEXT: mov v1.s[1], v2.s[0] ; CHECK-GI-NEXT: ldr q2, [sp] // 16-byte Reload ; CHECK-GI-NEXT: mov v1.s[2], v2.s[0] ; CHECK-GI-NEXT: mov v1.s[3], v0.s[0] ; CHECK-GI-NEXT: mov v0.16b, v1.16b ; CHECK-GI-NEXT: add sp, sp, #80 ; CHECK-GI-NEXT: ret entry: %fmod = frem nsz <4 x float> %x, ret <4 x float> %fmod } define <4 x float> @frem1152921504606846976_absv(<4 x float> %x) { ; CHECK-SD-LABEL: frem1152921504606846976_absv: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: mov w8, #562036736 // =0x21800000 ; CHECK-SD-NEXT: fabs v0.4s, v0.4s ; CHECK-SD-NEXT: dup v1.4s, w8 ; CHECK-SD-NEXT: mov w8, #1568669696 // =0x5d800000 ; CHECK-SD-NEXT: dup v2.4s, w8 ; CHECK-SD-NEXT: fmul v1.4s, v0.4s, v1.4s ; CHECK-SD-NEXT: frintz v1.4s, v1.4s ; CHECK-SD-NEXT: fmls v0.4s, v2.4s, v1.4s ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem1152921504606846976_absv: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: sub sp, sp, #96 ; CHECK-GI-NEXT: str d10, [sp, #48] // 8-byte Spill ; CHECK-GI-NEXT: stp d9, d8, [sp, #64] // 16-byte Folded Spill ; CHECK-GI-NEXT: stp x30, x19, [sp, #80] // 16-byte Folded Spill ; CHECK-GI-NEXT: .cfi_def_cfa_offset 96 ; CHECK-GI-NEXT: .cfi_offset w19, -8 ; CHECK-GI-NEXT: .cfi_offset w30, -16 ; CHECK-GI-NEXT: .cfi_offset b8, -24 ; CHECK-GI-NEXT: .cfi_offset b9, -32 ; CHECK-GI-NEXT: .cfi_offset b10, -48 ; CHECK-GI-NEXT: fabs v0.4s, v0.4s ; CHECK-GI-NEXT: mov w19, #1568669696 // =0x5d800000 ; CHECK-GI-NEXT: fmov s1, w19 ; CHECK-GI-NEXT: mov s8, v0.s[1] ; CHECK-GI-NEXT: mov s9, v0.s[2] ; CHECK-GI-NEXT: mov s10, v0.s[3] ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 killed $q0 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: str q0, [sp, #32] // 16-byte Spill ; CHECK-GI-NEXT: fmov s1, w19 ; CHECK-GI-NEXT: fmov s0, s8 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: str q0, [sp, #16] // 16-byte Spill ; CHECK-GI-NEXT: fmov s1, w19 ; CHECK-GI-NEXT: fmov s0, s9 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: str q0, [sp] // 16-byte Spill ; CHECK-GI-NEXT: fmov s1, w19 ; CHECK-GI-NEXT: fmov s0, s10 ; CHECK-GI-NEXT: bl fmodf ; CHECK-GI-NEXT: ldp q2, q1, [sp, #16] // 32-byte Folded Reload ; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0 ; CHECK-GI-NEXT: ldr d10, [sp, #48] // 8-byte Reload ; CHECK-GI-NEXT: ldp x30, x19, [sp, #80] // 16-byte Folded Reload ; CHECK-GI-NEXT: ldp d9, d8, [sp, #64] // 16-byte Folded Reload ; CHECK-GI-NEXT: mov v1.s[1], v2.s[0] ; CHECK-GI-NEXT: ldr q2, [sp] // 16-byte Reload ; CHECK-GI-NEXT: mov v1.s[2], v2.s[0] ; CHECK-GI-NEXT: mov v1.s[3], v0.s[0] ; CHECK-GI-NEXT: mov v0.16b, v1.16b ; CHECK-GI-NEXT: add sp, sp, #96 ; CHECK-GI-NEXT: ret entry: %a = tail call <4 x float> @llvm.fabs.v4f32(<4 x float> %x) %fmod = frem <4 x float> %a, ret <4 x float> %fmod } define float @frem2_nsz_sitofp(float %x, i32 %sa) { ; CHECK-SD-LABEL: frem2_nsz_sitofp: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: mov w8, #1 // =0x1 ; CHECK-SD-NEXT: lsl w8, w8, w0 ; CHECK-SD-NEXT: scvtf s1, w8 ; CHECK-SD-NEXT: fdiv s2, s0, s1 ; CHECK-SD-NEXT: frintz s2, s2 ; CHECK-SD-NEXT: fmsub s0, s2, s1, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_nsz_sitofp: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: mov w8, #1 // =0x1 ; CHECK-GI-NEXT: lsl w8, w8, w0 ; CHECK-GI-NEXT: scvtf s1, w8 ; CHECK-GI-NEXT: b fmodf entry: %s = shl i32 1, %sa %y = sitofp i32 %s to float %fmod = frem nsz float %x, %y ret float %fmod } define float @frem2_nsz_uitofp(float %x, i32 %sa) { ; CHECK-SD-LABEL: frem2_nsz_uitofp: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: mov w8, #1 // =0x1 ; CHECK-SD-NEXT: lsl w8, w8, w0 ; CHECK-SD-NEXT: ucvtf s1, w8 ; CHECK-SD-NEXT: fdiv s2, s0, s1 ; CHECK-SD-NEXT: frintz s2, s2 ; CHECK-SD-NEXT: fmsub s0, s2, s1, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_nsz_uitofp: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: mov w8, #1 // =0x1 ; CHECK-GI-NEXT: lsl w8, w8, w0 ; CHECK-GI-NEXT: ucvtf s1, w8 ; CHECK-GI-NEXT: b fmodf entry: %s = shl i32 1, %sa %y = uitofp i32 %s to float %fmod = frem nsz float %x, %y ret float %fmod } define float @frem2_const_sitofp(float %x, i32 %sa) { ; CHECK-SD-LABEL: frem2_const_sitofp: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: mov w8, #1 // =0x1 ; CHECK-SD-NEXT: fmov s1, #12.50000000 ; CHECK-SD-NEXT: lsl w8, w8, w0 ; CHECK-SD-NEXT: scvtf s0, w8 ; CHECK-SD-NEXT: fdiv s2, s1, s0 ; CHECK-SD-NEXT: frintz s2, s2 ; CHECK-SD-NEXT: fmsub s0, s2, s0, s1 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_const_sitofp: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: mov w8, #1 // =0x1 ; CHECK-GI-NEXT: and w9, w0, #0x1f ; CHECK-GI-NEXT: fmov s0, #12.50000000 ; CHECK-GI-NEXT: lsl w8, w8, w9 ; CHECK-GI-NEXT: scvtf s1, w8 ; CHECK-GI-NEXT: b fmodf entry: %sa2 = and i32 %sa, 31 %s = shl i32 1, %sa2 %y = sitofp i32 %s to float %fmod = frem float 12.50, %y ret float %fmod } define float @frem2_constneg_sitofp(float %x, i32 %sa) { ; CHECK-SD-LABEL: frem2_constneg_sitofp: ; CHECK-SD: // %bb.0: // %entry ; CHECK-SD-NEXT: mov w8, #1 // =0x1 ; CHECK-SD-NEXT: fmov s1, #-12.50000000 ; CHECK-SD-NEXT: lsl w8, w8, w0 ; CHECK-SD-NEXT: scvtf s0, w8 ; CHECK-SD-NEXT: fdiv s2, s1, s0 ; CHECK-SD-NEXT: frintz s2, s2 ; CHECK-SD-NEXT: fmsub s0, s2, s0, s1 ; CHECK-SD-NEXT: fabs s0, s0 ; CHECK-SD-NEXT: fneg s0, s0 ; CHECK-SD-NEXT: ret ; ; CHECK-GI-LABEL: frem2_constneg_sitofp: ; CHECK-GI: // %bb.0: // %entry ; CHECK-GI-NEXT: mov w8, #1 // =0x1 ; CHECK-GI-NEXT: and w9, w0, #0x1f ; CHECK-GI-NEXT: fmov s0, #-12.50000000 ; CHECK-GI-NEXT: lsl w8, w8, w9 ; CHECK-GI-NEXT: scvtf s1, w8 ; CHECK-GI-NEXT: b fmodf entry: %sa2 = and i32 %sa, 31 %s = shl i32 1, %sa2 %y = sitofp i32 %s to float %fmod = frem float -12.50, %y ret float %fmod } attributes #0 = { nounwind }