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