
This moves the combine of fdiv by constant to fmul out of an 'if (Options.UnsafeFPMath || Flags.hasAllowReciprocal()' block, so that it triggers if the divide is exact. An extra check for Recip.isDenormal() is added as multiple places make reference to it being unsafe or slow on certain platforms.
81 lines
2.8 KiB
LLVM
81 lines
2.8 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
|
|
; RUN: llc -mtriple=thumbv8m.main-none-eabi %s -o - | FileCheck %s --check-prefix=CHECK-SOFT
|
|
; RUN: llc -mtriple=thumbv8m.main-none-eabi -mattr=+fp-armv8 %s -o - | FileCheck %s --check-prefix=CHECK-FP
|
|
; RUN: llc -mtriple=thumbv8m.main-none-eabi -mattr=+fp-armv8,+slowfpvfmx %s -o - | FileCheck %s --check-prefix=CHECK-M33
|
|
|
|
define float @frem4(float %x) {
|
|
; CHECK-SOFT-LABEL: frem4:
|
|
; CHECK-SOFT: @ %bb.0: @ %entry
|
|
; CHECK-SOFT-NEXT: .save {r7, lr}
|
|
; CHECK-SOFT-NEXT: push {r7, lr}
|
|
; CHECK-SOFT-NEXT: mov.w r1, #1082130432
|
|
; CHECK-SOFT-NEXT: bl fmodf
|
|
; CHECK-SOFT-NEXT: pop {r7, pc}
|
|
;
|
|
; CHECK-FP-LABEL: frem4:
|
|
; CHECK-FP: @ %bb.0: @ %entry
|
|
; CHECK-FP-NEXT: vmov.f32 s0, #2.500000e-01
|
|
; CHECK-FP-NEXT: vmov.f32 s2, #-4.000000e+00
|
|
; CHECK-FP-NEXT: vmov s4, r0
|
|
; CHECK-FP-NEXT: lsrs r0, r0, #31
|
|
; CHECK-FP-NEXT: vmul.f32 s0, s4, s0
|
|
; CHECK-FP-NEXT: vrintz.f32 s0, s0
|
|
; CHECK-FP-NEXT: vfma.f32 s4, s0, s2
|
|
; CHECK-FP-NEXT: vmov r1, s4
|
|
; CHECK-FP-NEXT: bfi r1, r0, #31, #1
|
|
; CHECK-FP-NEXT: mov r0, r1
|
|
; CHECK-FP-NEXT: bx lr
|
|
;
|
|
; CHECK-M33-LABEL: frem4:
|
|
; CHECK-M33: @ %bb.0: @ %entry
|
|
; CHECK-M33-NEXT: vmov.f32 s0, #2.500000e-01
|
|
; CHECK-M33-NEXT: vmov.f32 s2, #-4.000000e+00
|
|
; CHECK-M33-NEXT: vmov s4, r0
|
|
; CHECK-M33-NEXT: lsrs r0, r0, #31
|
|
; CHECK-M33-NEXT: vmul.f32 s0, s4, s0
|
|
; CHECK-M33-NEXT: vrintz.f32 s0, s0
|
|
; CHECK-M33-NEXT: vmla.f32 s4, s0, s2
|
|
; CHECK-M33-NEXT: vmov r1, s4
|
|
; CHECK-M33-NEXT: bfi r1, r0, #31, #1
|
|
; CHECK-M33-NEXT: mov r0, r1
|
|
; CHECK-M33-NEXT: bx lr
|
|
entry:
|
|
%fmod = frem float %x, 4.0
|
|
ret float %fmod
|
|
}
|
|
|
|
define float @frem4_nsz(float %x) {
|
|
; CHECK-SOFT-LABEL: frem4_nsz:
|
|
; CHECK-SOFT: @ %bb.0: @ %entry
|
|
; CHECK-SOFT-NEXT: .save {r7, lr}
|
|
; CHECK-SOFT-NEXT: push {r7, lr}
|
|
; CHECK-SOFT-NEXT: mov.w r1, #1082130432
|
|
; CHECK-SOFT-NEXT: bl fmodf
|
|
; CHECK-SOFT-NEXT: pop {r7, pc}
|
|
;
|
|
; CHECK-FP-LABEL: frem4_nsz:
|
|
; CHECK-FP: @ %bb.0: @ %entry
|
|
; CHECK-FP-NEXT: vmov.f32 s0, #2.500000e-01
|
|
; CHECK-FP-NEXT: vmov.f32 s2, #-4.000000e+00
|
|
; CHECK-FP-NEXT: vmov s4, r0
|
|
; CHECK-FP-NEXT: vmul.f32 s0, s4, s0
|
|
; CHECK-FP-NEXT: vrintz.f32 s0, s0
|
|
; CHECK-FP-NEXT: vfma.f32 s4, s0, s2
|
|
; CHECK-FP-NEXT: vmov r0, s4
|
|
; CHECK-FP-NEXT: bx lr
|
|
;
|
|
; CHECK-M33-LABEL: frem4_nsz:
|
|
; CHECK-M33: @ %bb.0: @ %entry
|
|
; CHECK-M33-NEXT: vmov.f32 s0, #2.500000e-01
|
|
; CHECK-M33-NEXT: vmov.f32 s2, #-4.000000e+00
|
|
; CHECK-M33-NEXT: vmov s4, r0
|
|
; CHECK-M33-NEXT: vmul.f32 s0, s4, s0
|
|
; CHECK-M33-NEXT: vrintz.f32 s0, s0
|
|
; CHECK-M33-NEXT: vmla.f32 s4, s0, s2
|
|
; CHECK-M33-NEXT: vmov r0, s4
|
|
; CHECK-M33-NEXT: bx lr
|
|
entry:
|
|
%fmod = frem nsz float %x, 4.0
|
|
ret float %fmod
|
|
}
|