; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=hexagon -mcpu=hexagonv5 < %s | FileCheck %s

;---------------------------------------------------------------------
; fast sqrt
;---------------------------------------------------------------------

define float @fast_sqrt_f32(float %x) {
; CHECK-LABEL: fast_sqrt_f32:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     jump __hexagon_fast2_sqrtf
; CHECK-NEXT:    }
  %result = call nnan ninf nsz afn float @llvm.sqrt.f32(float %x)
  ret float %result
}

define double @fast_sqrt_f64(double %x) {
; CHECK-LABEL: fast_sqrt_f64:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     jump __hexagon_fast2_sqrtdf2
; CHECK-NEXT:    }
  %result = call nnan ninf nsz afn double @llvm.sqrt.f64(double %x)
  ret double %result
}

;---------------------------------------------------------------------
; fast fadd
;---------------------------------------------------------------------

define float @fast_add_f32(float %x, float %y) {
; CHECK-LABEL: fast_add_f32:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     r0 = sfadd(r0,r1)
; CHECK-NEXT:     jumpr r31
; CHECK-NEXT:    }
  %result = fadd nnan ninf nsz afn float %x, %y
  ret float %result
}

define double @fast_add_f64(double %x, double %y) {
; CHECK-LABEL: fast_add_f64:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     jump __hexagon_fast_adddf3
; CHECK-NEXT:    }
  %result = fadd nnan ninf nsz afn double %x, %y
  ret double %result
}

;---------------------------------------------------------------------
; fast fsub
;---------------------------------------------------------------------

define float @fast_sub_f32(float %x, float %y) {
; CHECK-LABEL: fast_sub_f32:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     r0 = sfsub(r0,r1)
; CHECK-NEXT:     jumpr r31
; CHECK-NEXT:    }
  %result = fsub nnan ninf nsz afn float %x, %y
  ret float %result
}

define double @fast_sub_f64(double %x, double %y) {
; CHECK-LABEL: fast_sub_f64:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     jump __hexagon_fast_subdf3
; CHECK-NEXT:    }
  %result = fsub nnan ninf nsz afn double %x, %y
  ret double %result
}

;---------------------------------------------------------------------
; fast fmul
;---------------------------------------------------------------------

define float @fast_mul_f32(float %x, float %y) {
; CHECK-LABEL: fast_mul_f32:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     r0 = sfmpy(r0,r1)
; CHECK-NEXT:     jumpr r31
; CHECK-NEXT:    }
  %result = fmul nnan ninf nsz afn float %x, %y
  ret float %result
}

define double @fast_mul_f64(double %x, double %y) {
; CHECK-LABEL: fast_mul_f64:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     jump __hexagon_fast_muldf3
; CHECK-NEXT:    }
  %result = fmul nnan ninf nsz afn double %x, %y
  ret double %result
}

;---------------------------------------------------------------------
; fast fdiv
;---------------------------------------------------------------------

define float @fast_div_f32(float %x, float %y) {
; CHECK-LABEL: fast_div_f32:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     r2 = sffixupn(r0,r1)
; CHECK-NEXT:     r4,p0 = sfrecipa(r0,r1)
; CHECK-NEXT:     r5 = ##1065353216
; CHECK-NEXT:    }
; CHECK-NEXT:    {
; CHECK-NEXT:     r1 = sffixupd(r0,r1)
; CHECK-NEXT:     r6 = ##1065353216
; CHECK-NEXT:    }
; CHECK-NEXT:    {
; CHECK-NEXT:     r5 -= sfmpy(r1,r4):lib
; CHECK-NEXT:     r0 = and(r2,##-2147483648)
; CHECK-NEXT:     r3 = r2
; CHECK-NEXT:    }
; CHECK-NEXT:    {
; CHECK-NEXT:     r4 += sfmpy(r5,r4):lib
; CHECK-NEXT:    }
; CHECK-NEXT:    {
; CHECK-NEXT:     r0 += sfmpy(r2,r4):lib
; CHECK-NEXT:     r6 -= sfmpy(r1,r4):lib
; CHECK-NEXT:    }
; CHECK-NEXT:    {
; CHECK-NEXT:     r3 -= sfmpy(r1,r0):lib
; CHECK-NEXT:     r4 += sfmpy(r6,r4):lib
; CHECK-NEXT:    }
; CHECK-NEXT:    {
; CHECK-NEXT:     r0 += sfmpy(r3,r4):lib
; CHECK-NEXT:    }
; CHECK-NEXT:    {
; CHECK-NEXT:     r2 -= sfmpy(r0,r1):lib
; CHECK-NEXT:    }
; CHECK-NEXT:    {
; CHECK-NEXT:     r0 += sfmpy(r2,r4,p0):scale
; CHECK-NEXT:     jumpr r31
; CHECK-NEXT:    }
  %result = fdiv nnan ninf nsz afn float %x, %y
  ret float %result
}

define double @fast_div_f64(double %x, double %y) {
; CHECK-LABEL: fast_div_f64:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     jump __hexagon_fast_divdf3
; CHECK-NEXT:    }
  %result = fdiv nnan ninf nsz afn double %x, %y
  ret double %result
}

;---------------------------------------------------------------------
; Negative tests sqrt
;---------------------------------------------------------------------

; TODO: What flags do we really need here?
define float @sqrt_f32__afn(float %x) {
; CHECK-LABEL: sqrt_f32__afn:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     jump __hexagon_sqrtf
; CHECK-NEXT:    }
  %result = call afn float @llvm.sqrt.f32(float %x)
  ret float %result
}

define float @sqrt_f32__afn_ninf(float %x) {
; CHECK-LABEL: sqrt_f32__afn_ninf:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     jump __hexagon_sqrtf
; CHECK-NEXT:    }
  %result = call afn ninf float @llvm.sqrt.f32(float %x)
  ret float %result
}

define float @sqrt_f32__afn_nnan(float %x) {
; CHECK-LABEL: sqrt_f32__afn_nnan:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     jump __hexagon_sqrtf
; CHECK-NEXT:    }
  %result = call afn nnan float @llvm.sqrt.f32(float %x)
  ret float %result
}

define float @sqrt_f32__nnan(float %x) {
; CHECK-LABEL: sqrt_f32__nnan:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     jump __hexagon_sqrtf
; CHECK-NEXT:    }
  %result = call nnan float @llvm.sqrt.f32(float %x)
  ret float %result
}

define float @sqrt_f32_nnan_ninf_afn(float %x) {
; CHECK-LABEL: sqrt_f32_nnan_ninf_afn:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     jump __hexagon_sqrtf
; CHECK-NEXT:    }
  %result = call nnan ninf afn float @llvm.sqrt.f32(float %x)
  ret float %result
}

;---------------------------------------------------------------------
; Negative tests fadd
;---------------------------------------------------------------------

; TODO: What flags do we really need here?
define float @fadd_f32_afn(float %x, float %y) {
; CHECK-LABEL: fadd_f32_afn:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     r0 = sfadd(r0,r1)
; CHECK-NEXT:     jumpr r31
; CHECK-NEXT:    }
  %result = fadd afn float %x, %y
  ret float %result
}

define float @fadd_f32__afn_ninf(float %x, float %y) {
; CHECK-LABEL: fadd_f32__afn_ninf:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     r0 = sfadd(r0,r1)
; CHECK-NEXT:     jumpr r31
; CHECK-NEXT:    }
  %result = fadd afn ninf float %x, %y
  ret float %result
}

define float @fadd_f32__afn_nnan(float %x, float %y) {
; CHECK-LABEL: fadd_f32__afn_nnan:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     r0 = sfadd(r0,r1)
; CHECK-NEXT:     jumpr r31
; CHECK-NEXT:    }
  %result = fadd afn nnan float %x, %y
  ret float %result
}

define float @fadd_f32__nnan(float %x, float %y) {
; CHECK-LABEL: fadd_f32__nnan:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     r0 = sfadd(r0,r1)
; CHECK-NEXT:     jumpr r31
; CHECK-NEXT:    }
  %result = fadd nnan float %x, %y
  ret float %result
}

define float @fadd_f32__nnan_ninf_afn(float %x, float %y) {
; CHECK-LABEL: fadd_f32__nnan_ninf_afn:
; CHECK:         .cfi_startproc
; CHECK-NEXT:  // %bb.0:
; CHECK-NEXT:    {
; CHECK-NEXT:     r0 = sfadd(r0,r1)
; CHECK-NEXT:     jumpr r31
; CHECK-NEXT:    }
  %result = fadd nnan ninf afn float %x, %y
  ret float %result
}
