; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc --mtriple=loongarch32 --mattr=+f,-d --fp-contract=fast < %s \
; RUN: | FileCheck %s --check-prefix=LA32-CONTRACT-FAST
; RUN: llc --mtriple=loongarch32 --mattr=+f,-d --fp-contract=on < %s \
; RUN: | FileCheck %s --check-prefix=LA32-CONTRACT-ON
; RUN: llc --mtriple=loongarch32 --mattr=+f,-d --fp-contract=off < %s \
; RUN: | FileCheck %s --check-prefix=LA32-CONTRACT-OFF
; RUN: llc --mtriple=loongarch64 --mattr=+f,-d --fp-contract=fast < %s \
; RUN: | FileCheck %s --check-prefix=LA64-CONTRACT-FAST
; RUN: llc --mtriple=loongarch64 --mattr=+f,-d --fp-contract=on < %s \
; RUN: | FileCheck %s --check-prefix=LA64-CONTRACT-ON
; RUN: llc --mtriple=loongarch64 --mattr=+f,-d --fp-contract=off < %s \
; RUN: | FileCheck %s --check-prefix=LA64-CONTRACT-OFF
define float @fmadd_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fmadd_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fmadd_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-ON-NEXT: fadd.s $fa0, $fa0, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fmadd_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-OFF-NEXT: fadd.s $fa0, $fa0, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fmadd_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fmadd_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-ON-NEXT: fadd.s $fa0, $fa0, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fmadd_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-OFF-NEXT: fadd.s $fa0, $fa0, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%mul = fmul float %a, %b
%add = fadd float %mul, %c
ret float %add
}
define float @fmsub_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fmsub_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fmsub_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fmsub_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fmsub_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fmsub_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fmsub_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%mul = fmul float %a, %b
%sub = fsub float %mul, %c
ret float %sub
}
define float @fnmadd_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fnmadd_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fnmadd_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-ON-NEXT: fadd.s $fa0, $fa0, $fa2
; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fnmadd_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-OFF-NEXT: fadd.s $fa0, $fa0, $fa2
; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fnmadd_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fnmadd_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-ON-NEXT: fadd.s $fa0, $fa0, $fa2
; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fnmadd_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-OFF-NEXT: fadd.s $fa0, $fa0, $fa2
; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-OFF-NEXT: ret
%mul = fmul float %a, %b
%add = fadd float %mul, %c
%negadd = fneg float %add
ret float %negadd
}
define float @fnmadd_s_nsz(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fnmadd_s_nsz:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fnmadd_s_nsz:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fnmadd_s_nsz:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fnmadd_s_nsz:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fnmadd_s_nsz:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fnmadd_s_nsz:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg nsz float %a
%negc = fneg nsz float %c
%mul = fmul nsz float %nega, %b
%add = fadd nsz float %mul, %negc
ret float %add
}
;; Check that fnmadd.s is not emitted.
define float @not_fnmadd_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: not_fnmadd_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: not_fnmadd_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: not_fnmadd_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: not_fnmadd_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: not_fnmadd_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: not_fnmadd_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg float %a
%negc = fneg float %c
%mul = fmul float %nega, %b
%add = fadd float %mul, %negc
ret float %add
}
define float @fnmsub_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fnmsub_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fnmsub_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2
; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fnmsub_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2
; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fnmsub_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fnmsub_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa0, $fa2
; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fnmsub_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa0, $fa2
; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-OFF-NEXT: ret
%negc = fneg float %c
%mul = fmul float %a, %b
%add = fadd float %mul, %negc
%neg = fneg float %add
ret float %neg
}
define float @fnmsub_s_nsz(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fnmsub_s_nsz:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fnmsub_s_nsz:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa2, $fa0
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fnmsub_s_nsz:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa2, $fa0
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fnmsub_s_nsz:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fnmsub_s_nsz:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa2, $fa0
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fnmsub_s_nsz:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa2, $fa0
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg nsz float %a
%mul = fmul nsz float %nega, %b
%add = fadd nsz float %mul, %c
ret float %add
}
;; Check that fnmsub.s is not emitted.
define float @not_fnmsub_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: not_fnmsub_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: not_fnmsub_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-ON-NEXT: fsub.s $fa0, $fa2, $fa0
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: not_fnmsub_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA32-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa2, $fa0
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: not_fnmsub_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: not_fnmsub_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-ON-NEXT: fsub.s $fa0, $fa2, $fa0
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: not_fnmsub_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmul.s $fa0, $fa0, $fa1
; LA64-CONTRACT-OFF-NEXT: fsub.s $fa0, $fa2, $fa0
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg float %a
%mul = fmul float %nega, %b
%add = fadd float %mul, %c
ret float %add
}
define float @contract_fmadd_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: contract_fmadd_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: contract_fmadd_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: contract_fmadd_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: contract_fmadd_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: contract_fmadd_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: contract_fmadd_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%mul = fmul contract float %a, %b
%add = fadd contract float %mul, %c
ret float %add
}
define float @contract_fmsub_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: contract_fmsub_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: contract_fmsub_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: contract_fmsub_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: contract_fmsub_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: contract_fmsub_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: contract_fmsub_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%mul = fmul contract float %a, %b
%sub = fsub contract float %mul, %c
ret float %sub
}
define float @contract_fnmadd_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: contract_fnmadd_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: contract_fnmadd_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: contract_fnmadd_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: contract_fnmadd_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: contract_fnmadd_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: contract_fnmadd_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%mul = fmul contract float %a, %b
%add = fadd contract float %mul, %c
%negadd = fneg contract float %add
ret float %negadd
}
define float @contract_fnmadd_s_nsz(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: contract_fnmadd_s_nsz:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: contract_fnmadd_s_nsz:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: contract_fnmadd_s_nsz:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: contract_fnmadd_s_nsz:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: contract_fnmadd_s_nsz:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: contract_fnmadd_s_nsz:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg contract nsz float %a
%negc = fneg contract nsz float %c
%mul = fmul contract nsz float %nega, %b
%add = fadd contract nsz float %mul, %negc
ret float %add
}
;; Check that fnmadd.s is not emitted.
define float @not_contract_fnmadd_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: not_contract_fnmadd_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: not_contract_fnmadd_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: not_contract_fnmadd_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: not_contract_fnmadd_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: not_contract_fnmadd_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: not_contract_fnmadd_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg contract float %a
%negc = fneg contract float %c
%mul = fmul contract float %nega, %b
%add = fadd contract float %mul, %negc
ret float %add
}
define float @contract_fnmsub_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: contract_fnmsub_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: contract_fnmsub_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: contract_fnmsub_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: contract_fnmsub_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: contract_fnmsub_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: contract_fnmsub_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%negc = fneg contract float %c
%mul = fmul contract float %a, %b
%add = fadd contract float %mul, %negc
%neg = fneg contract float %add
ret float %neg
}
define float @contract_fnmsub_s_nsz(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: contract_fnmsub_s_nsz:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: contract_fnmsub_s_nsz:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: contract_fnmsub_s_nsz:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: contract_fnmsub_s_nsz:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: contract_fnmsub_s_nsz:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: contract_fnmsub_s_nsz:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg contract nsz float %a
%mul = fmul contract nsz float %nega, %b
%add = fadd contract nsz float %mul, %c
ret float %add
}
;; Check that fnmsub.s is not emitted.
define float @not_contract_fnmsub_s(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: not_contract_fnmsub_s:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: not_contract_fnmsub_s:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: not_contract_fnmsub_s:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: not_contract_fnmsub_s:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: not_contract_fnmsub_s:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: not_contract_fnmsub_s:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg contract float %a
%mul = fmul contract float %nega, %b
%add = fadd contract float %mul, %c
ret float %add
}
declare float @llvm.fma.f64(float, float, float)
define float @fmadd_s_intrinsics(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fmadd_s_intrinsics:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fmadd_s_intrinsics:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fmadd_s_intrinsics:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fmadd_s_intrinsics:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fmadd_s_intrinsics:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fmadd_s_intrinsics:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%fma = call float @llvm.fma.f64(float %a, float %b, float %c)
ret float %fma
}
define float @fmsub_s_intrinsics(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fmsub_s_intrinsics:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fmsub_s_intrinsics:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fmsub_s_intrinsics:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fmsub_s_intrinsics:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fmsub_s_intrinsics:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fmsub_s_intrinsics:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%negc = fneg float %c
%fma = call float @llvm.fma.f64(float %a, float %b, float %negc)
ret float %fma
}
define float @fnmadd_s_intrinsics(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fnmadd_s_intrinsics:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fnmadd_s_intrinsics:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fnmadd_s_intrinsics:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fnmadd_s_intrinsics:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fnmadd_s_intrinsics:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fnmadd_s_intrinsics:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%fma = call float @llvm.fma.f64(float %a, float %b, float %c)
%negfma = fneg float %fma
ret float %negfma
}
define float @fnmadd_s_nsz_intrinsics(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fnmadd_s_nsz_intrinsics:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fnmadd_s_nsz_intrinsics:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fnmadd_s_nsz_intrinsics:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fnmadd_s_nsz_intrinsics:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fnmadd_s_nsz_intrinsics:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fnmadd_s_nsz_intrinsics:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg float %a
%negc = fneg float %c
%fma = call nsz float @llvm.fma.f64(float %nega, float %b, float %negc)
ret float %fma
}
;; Check that fnmadd.s is not emitted.
define float @not_fnmadd_s_intrinsics(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: not_fnmadd_s_intrinsics:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: not_fnmadd_s_intrinsics:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: not_fnmadd_s_intrinsics:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: not_fnmadd_s_intrinsics:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: not_fnmadd_s_intrinsics:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: not_fnmadd_s_intrinsics:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg float %a
%negc = fneg float %c
%fma = call float @llvm.fma.f64(float %nega, float %b, float %negc)
ret float %fma
}
define float @fnmsub_s_intrinsics(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fnmsub_s_intrinsics:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fnmsub_s_intrinsics:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fnmsub_s_intrinsics:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fnmsub_s_intrinsics:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fnmsub_s_intrinsics:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fnmsub_s_intrinsics:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%negc = fneg float %c
%fma = call float @llvm.fma.f64(float %a, float %b, float %negc)
%negfma = fneg float %fma
ret float %negfma
}
define float @fnmsub_s_nsz_intrinsics(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fnmsub_s_nsz_intrinsics:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fnmsub_s_nsz_intrinsics:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fnmsub_s_nsz_intrinsics:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fnmsub_s_nsz_intrinsics:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fnmsub_s_nsz_intrinsics:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fnmsub_s_nsz_intrinsics:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg float %a
%fma = call nsz float @llvm.fma.f64(float %nega, float %b, float %c)
ret float %fma
}
;; Check that fnmsub.s is not emitted.
define float @not_fnmsub_s_intrinsics(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: not_fnmsub_s_intrinsics:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: not_fnmsub_s_intrinsics:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: not_fnmsub_s_intrinsics:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA32-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: not_fnmsub_s_intrinsics:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: not_fnmsub_s_intrinsics:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: not_fnmsub_s_intrinsics:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fneg.s $fa0, $fa0
; LA64-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%nega = fneg float %a
%fma = call float @llvm.fma.f64(float %nega, float %b, float %c)
ret float %fma
}
define float @fmadd_s_contract(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fmadd_s_contract:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fmadd_s_contract:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fmadd_s_contract:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fmadd_s_contract:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fmadd_s_contract:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fmadd_s_contract:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%mul = fmul contract float %a, %b
%add = fadd contract float %mul, %c
ret float %add
}
define float @fmsub_s_contract(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fmsub_s_contract:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fmsub_s_contract:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fmsub_s_contract:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fmsub_s_contract:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fmsub_s_contract:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fmsub_s_contract:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%mul = fmul contract float %a, %b
%sub = fsub contract float %mul, %c
ret float %sub
}
define float @fnmadd_s_contract(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fnmadd_s_contract:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fnmadd_s_contract:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fnmadd_s_contract:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fnmadd_s_contract:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fnmadd_s_contract:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fnmadd_s_contract:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fnmadd.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%mul = fmul contract float %a, %b
%add = fadd contract float %mul, %c
%negadd = fneg contract float %add
ret float %negadd
}
define float @fnmsub_s_contract(float %a, float %b, float %c) nounwind {
; LA32-CONTRACT-FAST-LABEL: fnmsub_s_contract:
; LA32-CONTRACT-FAST: # %bb.0:
; LA32-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-FAST-NEXT: ret
;
; LA32-CONTRACT-ON-LABEL: fnmsub_s_contract:
; LA32-CONTRACT-ON: # %bb.0:
; LA32-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-ON-NEXT: ret
;
; LA32-CONTRACT-OFF-LABEL: fnmsub_s_contract:
; LA32-CONTRACT-OFF: # %bb.0:
; LA32-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA32-CONTRACT-OFF-NEXT: ret
;
; LA64-CONTRACT-FAST-LABEL: fnmsub_s_contract:
; LA64-CONTRACT-FAST: # %bb.0:
; LA64-CONTRACT-FAST-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-FAST-NEXT: ret
;
; LA64-CONTRACT-ON-LABEL: fnmsub_s_contract:
; LA64-CONTRACT-ON: # %bb.0:
; LA64-CONTRACT-ON-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-ON-NEXT: ret
;
; LA64-CONTRACT-OFF-LABEL: fnmsub_s_contract:
; LA64-CONTRACT-OFF: # %bb.0:
; LA64-CONTRACT-OFF-NEXT: fnmsub.s $fa0, $fa0, $fa1, $fa2
; LA64-CONTRACT-OFF-NEXT: ret
%mul = fmul contract float %a, %b
%negc = fneg contract float %c
%add = fadd contract float %negc, %mul
%negadd = fneg contract float %add
ret float %negadd
}