Index: lib/Target/Mips/MipsInstrFPU.td =================================================================== --- lib/Target/Mips/MipsInstrFPU.td +++ lib/Target/Mips/MipsInstrFPU.td @@ -842,6 +842,27 @@ def : MipsPat<(f64 (fpextend FGR32Opnd:$src)), (CVT_D64_S FGR32Opnd:$src)>, FGR_64; +//To generate NMADD and NMSUB instructions when fneg node is present +let AdditionalPredicates = [NoNaNsFPMath, HasMadd4] in { + def : MipsPat<(fneg (fsub (fmul FGR32Opnd:$fs, FGR32Opnd:$ft), FGR32Opnd:$fr)), + (NMSUB_S FGR32Opnd:$fr, FGR32Opnd:$fs, FGR32Opnd:$ft)>, INSN_MIPS4_32R2_NOT_32R6_64R6; + + def : MipsPat<(fneg (fsub (fmul AFGR64Opnd:$fs, AFGR64Opnd:$ft), AFGR64Opnd:$fr)), + (NMSUB_D32 AFGR64Opnd:$fr, AFGR64Opnd:$fs, AFGR64Opnd:$ft)>, FGR_32, INSN_MIPS4_32R2_NOT_32R6_64R6; + + def : MipsPat<(fneg (fadd (fmul FGR32Opnd:$fs, FGR32Opnd:$ft), FGR32Opnd:$fr)), + (NMADD_S FGR32Opnd:$fr, FGR32Opnd:$fs, FGR32Opnd:$ft)>, INSN_MIPS4_32R2_NOT_32R6_64R6; + + def : MipsPat<(fneg (fadd (fmul AFGR64Opnd:$fs, AFGR64Opnd:$ft), AFGR64Opnd:$fr)), + (NMADD_D32 AFGR64Opnd:$fr, AFGR64Opnd:$fs, AFGR64Opnd:$ft)>, FGR_32, INSN_MIPS4_32R2_NOT_32R6_64R6; + + def : MipsPat<(fneg (fadd (fmul FGR64Opnd:$fs, FGR64Opnd:$ft), FGR64Opnd:$fr)), + (NMADD_D64 FGR64Opnd:$fr, FGR64Opnd:$fs, FGR64Opnd:$ft)>, FGR_64, INSN_MIPS4_32R2_NOT_32R6_64R6; + + def : MipsPat<(fneg (fsub (fmul FGR64Opnd:$fs, FGR64Opnd:$ft), FGR64Opnd:$fr)), + (NMSUB_D64 FGR64Opnd:$fr, FGR64Opnd:$fs, FGR64Opnd:$ft)>, FGR_64, INSN_MIPS4_32R2_NOT_32R6_64R6; +} + // Patterns for loads/stores with a reg+imm operand. let AdditionalPredicates = [NotInMicroMips] in { let AddedComplexity = 40 in { Index: test/CodeGen/Mips/nmadd.ll =================================================================== --- test/CodeGen/Mips/nmadd.ll +++ test/CodeGen/Mips/nmadd.ll @@ -0,0 +1,63 @@ +; RUN: llc < %s -march=mips64el -mcpu=mips64 -target-abi=n64 -enable-no-nans-fp-math | FileCheck %s -check-prefixes=ALL,64-NM-OP +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -target-abi=n64 -enable-no-nans-fp-math | FileCheck %s -check-prefixes=ALL,64R2-NM-OPERATION + + +; Function Attrs: norecurse nounwind readnone +define float @add1(float %f, float %g, float %h) local_unnamed_addr #0 { +entry: +;ALL-LABEL: @add1 + +; 64-NM-OPERATION: nmadd.s $f0, $f14, $f12, $f13 + +; 64R2-NM-OPERATION: nmadd.s $f0, $f14, $f12, $f13 + + %mul = fmul nnan float %f, %g + %add = fadd nnan float %mul, %h + %sub = fsub nnan float -0.000000e+00, %add + ret float %sub +} + +; Function Attrs: norecurse nounwind readnone +define double @add2(double %f, double %g, double %h) local_unnamed_addr #0 { +entry: +;ALL-LABEL: @add2 + +; 64-NM-OPERATION: nmadd.d $f0, $f14, $f12, $f13 + +; 64R2-NM-OPERATION: nmadd.d $f0, $f14, $f12, $f13 + + %mul = fmul nnan double %f, %g + %add = fadd nnan double %mul, %h + %sub = fsub nnan double -0.000000e+00, %add + ret double %sub +} + +; Function Attrs: norecurse nounwind readnone +define float @sub1(float %f, float %g, float %h) local_unnamed_addr #0 { +entry: +;ALL-LABEL: @sub1 + +; 64-NM-OPERATION: nmsub.s $f0, $f14, $f12, $f13 + +; 64R2-NM-OPERATION: nmsub.s $f0, $f14, $f12, $f13 + + %mul = fmul nnan float %f, %g + %sub = fsub nnan float %mul, %h + %sub1 = fsub nnan float -0.000000e+00, %sub + ret float %sub1 +} + +; Function Attrs: norecurse nounwind readnone +define double @sub2(double %f, double %g, double %h) local_unnamed_addr #0 { +entry: +;ALL-LABEL: @sub2 + +; 64-NM-OPERATION: nmsub.d $f0, $f14, $f12, $f13 + +; 64R2-NM-OPERATION: nmsub.d $f0, $f14, $f12, $f13 + + %mul = fmul nnan double %f, %g + %sub = fsub nnan double %mul, %h + %sub1 = fsub nnan double -0.000000e+00, %sub + ret double %sub1 +}