| ; 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: .cfi_def_cfa r30, 8 |
| ; CHECK-NEXT: .cfi_offset r31, -4 |
| ; CHECK-NEXT: .cfi_offset r30, -8 |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: call __hexagon_fast2_sqrtf |
| ; CHECK-NEXT: allocframe(r29,#0):raw |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: r31:30 = dealloc_return(r30):raw |
| ; 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: .cfi_def_cfa r30, 8 |
| ; CHECK-NEXT: .cfi_offset r31, -4 |
| ; CHECK-NEXT: .cfi_offset r30, -8 |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: call __hexagon_fast2_sqrtdf2 |
| ; CHECK-NEXT: allocframe(r29,#0):raw |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: r31:30 = dealloc_return(r30):raw |
| ; 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: .cfi_def_cfa r30, 8 |
| ; CHECK-NEXT: .cfi_offset r31, -4 |
| ; CHECK-NEXT: .cfi_offset r30, -8 |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: call __hexagon_fast_adddf3 |
| ; CHECK-NEXT: allocframe(r29,#0):raw |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: r31:30 = dealloc_return(r30):raw |
| ; 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: .cfi_def_cfa r30, 8 |
| ; CHECK-NEXT: .cfi_offset r31, -4 |
| ; CHECK-NEXT: .cfi_offset r30, -8 |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: call __hexagon_fast_subdf3 |
| ; CHECK-NEXT: allocframe(r29,#0):raw |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: r31:30 = dealloc_return(r30):raw |
| ; 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: .cfi_def_cfa r30, 8 |
| ; CHECK-NEXT: .cfi_offset r31, -4 |
| ; CHECK-NEXT: .cfi_offset r30, -8 |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: call __hexagon_fast_muldf3 |
| ; CHECK-NEXT: allocframe(r29,#0):raw |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: r31:30 = dealloc_return(r30):raw |
| ; 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: .cfi_def_cfa r30, 8 |
| ; CHECK-NEXT: .cfi_offset r31, -4 |
| ; CHECK-NEXT: .cfi_offset r30, -8 |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: call __hexagon_fast_divdf3 |
| ; CHECK-NEXT: allocframe(r29,#0):raw |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: r31:30 = dealloc_return(r30):raw |
| ; 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: .cfi_def_cfa r30, 8 |
| ; CHECK-NEXT: .cfi_offset r31, -4 |
| ; CHECK-NEXT: .cfi_offset r30, -8 |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: call __hexagon_sqrtf |
| ; CHECK-NEXT: allocframe(r29,#0):raw |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: r31:30 = dealloc_return(r30):raw |
| ; 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: .cfi_def_cfa r30, 8 |
| ; CHECK-NEXT: .cfi_offset r31, -4 |
| ; CHECK-NEXT: .cfi_offset r30, -8 |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: call __hexagon_sqrtf |
| ; CHECK-NEXT: allocframe(r29,#0):raw |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: r31:30 = dealloc_return(r30):raw |
| ; 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: .cfi_def_cfa r30, 8 |
| ; CHECK-NEXT: .cfi_offset r31, -4 |
| ; CHECK-NEXT: .cfi_offset r30, -8 |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: call __hexagon_sqrtf |
| ; CHECK-NEXT: allocframe(r29,#0):raw |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: r31:30 = dealloc_return(r30):raw |
| ; 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: .cfi_def_cfa r30, 8 |
| ; CHECK-NEXT: .cfi_offset r31, -4 |
| ; CHECK-NEXT: .cfi_offset r30, -8 |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: call __hexagon_sqrtf |
| ; CHECK-NEXT: allocframe(r29,#0):raw |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: r31:30 = dealloc_return(r30):raw |
| ; 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: .cfi_def_cfa r30, 8 |
| ; CHECK-NEXT: .cfi_offset r31, -4 |
| ; CHECK-NEXT: .cfi_offset r30, -8 |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: call __hexagon_sqrtf |
| ; CHECK-NEXT: allocframe(r29,#0):raw |
| ; CHECK-NEXT: } |
| ; CHECK-NEXT: { |
| ; CHECK-NEXT: r31:30 = dealloc_return(r30):raw |
| ; 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 |
| } |