; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -verify-machineinstrs -o - %s -mtriple=arm64-apple-ios7.0 | FileCheck %s

declare float @fabsf(float) readonly
declare double @fabs(double) readonly

declare float @llvm.sqrt.f32(float %Val)
declare double @llvm.sqrt.f64(double %Val)

declare float @ceilf(float) readonly
declare double @ceil(double) readonly

declare float @floorf(float) readonly
declare double @floor(double) readonly

declare float @truncf(float) readonly
declare double @trunc(double) readonly

declare float @rintf(float) readonly
declare double @rint(double) readonly

declare float @nearbyintf(float) readonly
declare double @nearbyint(double) readonly

define float @fabs_f(float %v) {
; CHECK-LABEL: fabs_f:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fabs s0, s0
; CHECK-NEXT:    ret
  %r = call float @fabsf(float %v)
  ret float %r
}

define float @fsub_f(float %v) {
; CHECK-LABEL: fsub_f:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fneg s0, s0
; CHECK-NEXT:    ret
  %r = fsub float -0.0, %v
  ret float %r
}

define float @sqrt_f(float %v) {
; CHECK-LABEL: sqrt_f:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fsqrt s0, s0
; CHECK-NEXT:    ret
  %r = call float @llvm.sqrt.f32(float %v)
  ret float %r
}

define float @ceil_f(float %v) {
; CHECK-LABEL: ceil_f:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    frintp s0, s0
; CHECK-NEXT:    ret
  %r = call float @ceilf(float %v)
  ret float %r
}

define float @floor_f(float %v) {
; CHECK-LABEL: floor_f:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    frintm s0, s0
; CHECK-NEXT:    ret
  %r = call float @floorf(float %v)
  ret float %r
}

define float @trunc_f(float %v) {
; CHECK-LABEL: trunc_f:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    frintz s0, s0
; CHECK-NEXT:    ret
  %r = call float @truncf(float %v)
  ret float %r
}

define float @rint_f(float %v) {
; CHECK-LABEL: rint_f:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    frintx s0, s0
; CHECK-NEXT:    ret
  %r = call float @rintf(float %v)
  ret float %r
}

define float @nearbyint_f(float %v) {
; CHECK-LABEL: nearbyint_f:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    frinti s0, s0
; CHECK-NEXT:    ret
  %r = call float @nearbyintf(float %v)
  ret float %r
}

define double @fabs_d(double %v) {
; CHECK-LABEL: fabs_d:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fabs d0, d0
; CHECK-NEXT:    ret
  %r = call double @fabs(double %v)
  ret double %r
}

define double @fsub_d(double %v) {
; CHECK-LABEL: fsub_d:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fneg d0, d0
; CHECK-NEXT:    ret
  %r = fsub double -0.0, %v
  ret double %r
}

define double @sqrt_d(double %v) {
; CHECK-LABEL: sqrt_d:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fsqrt d0, d0
; CHECK-NEXT:    ret
  %r = call double @llvm.sqrt.f64(double %v)
  ret double %r
}

define double @ceil_d(double %v) {
; CHECK-LABEL: ceil_d:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    frintp d0, d0
; CHECK-NEXT:    ret
  %r = call double @ceil(double %v)
  ret double %r
}

define double @floor_d(double %v) {
; CHECK-LABEL: floor_d:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    frintm d0, d0
; CHECK-NEXT:    ret
  %r = call double @floor(double %v)
  ret double %r
}

define double @trunc_d(double %v) {
; CHECK-LABEL: trunc_d:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    frintz d0, d0
; CHECK-NEXT:    ret
  %r = call double @trunc(double %v)
  ret double %r
}

define double @rint_d(double %v) {
; CHECK-LABEL: rint_d:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    frintx d0, d0
; CHECK-NEXT:    ret
  %r = call double @rint(double %v)
  ret double %r
}

define double @nearbyint_d(double %v) {
; CHECK-LABEL: nearbyint_d:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    frinti d0, d0
; CHECK-NEXT:    ret
  %r = call double @nearbyint(double %v)
  ret double %r
}

define float @conv_h_f(half %v) {
; CHECK-LABEL: conv_h_f:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fcvt s0, h0
; CHECK-NEXT:    ret
  %r = fpext half %v to float
  ret float %r
}

define double @conv_h_d(half %v) {
; CHECK-LABEL: conv_h_d:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fcvt d0, h0
; CHECK-NEXT:    ret
  %r = fpext half %v to double
  ret double %r
}

define half @conv_f_h(float %v) {
; CHECK-LABEL: conv_f_h:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fcvt h0, s0
; CHECK-NEXT:    ret
  %r = fptrunc float %v to half
  ret half %r
}

define double @conv_f_d(float %v) {
; CHECK-LABEL: conv_f_d:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fcvt d0, s0
; CHECK-NEXT:    ret
  %r = fpext float %v to double
  ret double %r
}

define half @conv_d_h(double %v) {
; CHECK-LABEL: conv_d_h:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fcvt h0, d0
; CHECK-NEXT:    ret
  %r = fptrunc double %v to half
  ret half %r
}

define float @conv_d_f(double %v) {
; CHECK-LABEL: conv_d_f:
; CHECK:       ; %bb.0:
; CHECK-NEXT:    fcvt s0, d0
; CHECK-NEXT:    ret
  %r = fptrunc double %v to float
  ret float %r
}
