blob: 0d906c351ad601cb4da3ab71c68ab3e43bb4118c [file] [edit]
; RUN: llc -mtriple=aarch64 -global-isel=0 %s -o - | FileCheck %s --check-prefix=CHECK,FP
; RUN: llc -mtriple=aarch64 -O0 -global-isel=1 %s -o - | FileCheck %s --check-prefix=CHECK,FP
; RUN: llc -mtriple=aarch64 -mattr=-fp-armv8 -global-isel=0 %s -o - | FileCheck %s --check-prefix=CHECK,NOFP
; RUN: llc -mtriple=aarch64 -mattr=-fp-armv8 -O0 -global-isel=1 %s -o - | FileCheck %s --check-prefix=CHECK,NOFP
; Test that @llvm.fmuladd, with the semantics "multiply and add can be
; fused or separate at the compiler's option", fuses them in the
; normal case of hardware FP, but doesn't fuse them in AArch64 softfp,
; on the theory that the libc fma function is likely slower than the
; combination.
;
; However, @llvm.fma must fuse them regardless, so that _should_ emit
; a call to fma in softfp modes.
define float @whichever_float(float %0, float %1, float %2) {
%result = call float @llvm.fmuladd.f32(float %0, float %1, float %2)
ret float %result
; CHECK-LABEL: {{^}}whichever_float:
; FP: fmadd s0, s0, s1, s2
; NOFP: bl __mulsf3
; NOFP: bl __addsf3
}
define double @whichever_double(double %0, double %1, double %2) {
%result = call double @llvm.fmuladd.f64(double %0, double %1, double %2)
ret double %result
; CHECK-LABEL: {{^}}whichever_double:
; FP: fmadd d0, d0, d1, d2
; NOFP: bl __muldf3
; NOFP: bl __adddf3
}
define float @force_fma_float(float %0, float %1, float %2) {
%result = call float @llvm.fma.f32(float %0, float %1, float %2)
ret float %result
; CHECK-LABEL: {{^}}force_fma_float:
; FP: fmadd s0, s0, s1, s2
; NOFP: bl fmaf
}
define double @force_fma_double(double %0, double %1, double %2) {
%result = call double @llvm.fma.f64(double %0, double %1, double %2)
ret double %result
; CHECK-LABEL: {{^}}force_fma_double:
; FP: fmadd d0, d0, d1, d2
; NOFP: bl fma
}