llvm-project/llvm/test/CodeGen/Hexagon/fast-math-libcalls.ll
Matt Arsenault 7299250c03
DAG: Use fast variants of fast math libcalls (#147481)
Hexagon currently has an untested global flag to control fast
math variants of libcalls. Add fast variants as explicit libcall
options so this can be a flag based lowering decision, and implement
it. I have no idea what fast math flags the hexagon case requires,
so I picked the maximally potentially relevant set of flags although
this probably is refinable per call. Looking in compiler-rt, I'm not
sure if the fast variants are anything more than aliases.
2025-07-13 10:41:45 +09:00

370 lines
11 KiB
LLVM

; 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
}