From 8679b1f292f042631bc3a84352a2e70aded59e1f Mon Sep 17 00:00:00 2001 From: Petar Jovanovic Date: Sun, 27 Aug 2017 21:07:24 +0000 Subject: [PATCH] [mips] Generate NMADD and NMSUB instructions when fneg node is present This patch enables generation of NMADD and NMSUB instructions when fneg node is present. These instructions are currently only generated if fsub node is present. Patch by Stanislav Ocovaj. Differential Revision: https://reviews.llvm.org/D34507 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311862 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MicroMipsInstrFPU.td | 6 ++ lib/Target/Mips/MipsInstrFPU.td | 14 +++++ test/CodeGen/Mips/nmadd.ll | 83 ++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 test/CodeGen/Mips/nmadd.ll diff --git a/lib/Target/Mips/MicroMipsInstrFPU.td b/lib/Target/Mips/MicroMipsInstrFPU.td index 5600f71ff68..f0bbc840487 100644 --- a/lib/Target/Mips/MicroMipsInstrFPU.td +++ b/lib/Target/Mips/MicroMipsInstrFPU.td @@ -269,6 +269,12 @@ let AdditionalPredicates = [InMicroMips] in { ISA_MIPS1_NOT_32R6_64R6, HARDFLOAT; } +// To generate NMADD and NMSUB instructions when fneg node is present +let AdditionalPredicates = [NoNaNsFPMath, HasMadd4, InMicroMips, NotMips32r6] in { + defm : NMADD_NMSUB; + defm : NMADD_NMSUB; +} + //===----------------------------------------------------------------------===// // Floating Point Patterns //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsInstrFPU.td b/lib/Target/Mips/MipsInstrFPU.td index 115494dbce4..999e5fadb81 100644 --- a/lib/Target/Mips/MipsInstrFPU.td +++ b/lib/Target/Mips/MipsInstrFPU.td @@ -859,6 +859,20 @@ def : MipsPat<(f32 (fpround FGR64Opnd:$src)), def : MipsPat<(f64 (fpextend FGR32Opnd:$src)), (CVT_D64_S FGR32Opnd:$src)>, FGR_64; +// To generate NMADD and NMSUB instructions when fneg node is present +multiclass NMADD_NMSUB { + def : MipsPat<(fneg (fadd (fmul RC:$fs, RC:$ft), RC:$fr)), + (Nmadd RC:$fr, RC:$fs, RC:$ft)>; + def : MipsPat<(fneg (fsub (fmul RC:$fs, RC:$ft), RC:$fr)), + (Nmsub RC:$fr, RC:$fs, RC:$ft)>; +} + +let AdditionalPredicates = [NoNaNsFPMath, HasMadd4, NotInMicroMips] in { + defm : NMADD_NMSUB, INSN_MIPS4_32R2_NOT_32R6_64R6; + defm : NMADD_NMSUB, FGR_32, INSN_MIPS4_32R2_NOT_32R6_64R6; + defm : NMADD_NMSUB, 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 { diff --git a/test/CodeGen/Mips/nmadd.ll b/test/CodeGen/Mips/nmadd.ll new file mode 100644 index 00000000000..dfaa6ed8666 --- /dev/null +++ b/test/CodeGen/Mips/nmadd.ll @@ -0,0 +1,83 @@ +; Check whether nmadd/nmsub instructions are properly generated +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -enable-no-nans-fp-math | FileCheck %s -check-prefixes=ALL,CHECK-NM +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -mattr=+fp64 -enable-no-nans-fp-math | FileCheck %s -check-prefixes=ALL,CHECK-NM +; RUN: llc < %s -march=mipsel -mcpu=mips32r2 -mattr=micromips -enable-no-nans-fp-math -asm-show-inst | FileCheck %s -check-prefixes=ALL,CHECK-NM,CHECK-MM +; RUN: llc < %s -march=mips64el -mcpu=mips64 -target-abi=n64 -enable-no-nans-fp-math | FileCheck %s -check-prefixes=ALL,CHECK-NM-64 +; RUN: llc < %s -march=mips64el -mcpu=mips64r2 -target-abi=n64 -enable-no-nans-fp-math | FileCheck %s -check-prefixes=ALL,CHECK-NM-64 +; RUN: llc < %s -march=mips64el -mcpu=mips4 -target-abi=n64 -enable-no-nans-fp-math | FileCheck %s -check-prefixes=ALL,CHECK-NM-64 +; RUN: llc < %s -march=mipsel -mcpu=mips32 -enable-no-nans-fp-math | FileCheck %s -check-prefixes=ALL,CHECK-NOT-NM +; RUN: llc < %s -march=mipsel -mcpu=mips32r6 -enable-no-nans-fp-math | FileCheck %s -check-prefixes=ALL,CHECK-NOT-NM +; RUN: llc < %s -march=mips64el -mcpu=mips3 -target-abi=n64 -enable-no-nans-fp-math | FileCheck %s -check-prefixes=ALL,CHECK-NOT-NM-64 +; RUN-TODO: llc < %s -march=mipsel -mcpu=mips32r6 -mattr=micromips -enable-no-nans-fp-math | FileCheck %s -check-prefixes=ALL,CHECK-NOT-NM + +define float @add1(float %f, float %g, float %h) local_unnamed_addr #0 { +entry: +; ALL-LABEL: add1 + +; CHECK-NM-64: nmadd.s $f0, $f14, $f12, $f13 +; CHECK-NM: nmadd.s $f0, $f0, $f12, $f14 +; CHECK-MM: NMADD_S_MM +; CHECK-NOT-NM-64 mul.s $f0, $f12, $f13 +; CHECK-NOT-NM-64: neg.s $f0, $f0 +; CHECK-NOT-NM: mul.s $f0, $f12, $f14 +; CHECK-NOT-NM: neg.s $f0, $f0 + + %mul = fmul nnan float %f, %g + %add = fadd nnan float %mul, %h + %sub = fsub nnan float -0.000000e+00, %add + ret float %sub +} + +define double @add2(double %f, double %g, double %h) local_unnamed_addr #0 { +entry: +; ALL-LABEL: add2 + +; CHECK-NM-64: nmadd.d $f0, $f14, $f12, $f13 +; CHECK-NM: nmadd.d $f0, $f0, $f12, $f14 +; CHECK-MM: NMADD_D32_MM +; CHECK-NOT-NM-64 mul.d $f0, $f12, $f13 +; CHECK-NOT-NM-64: neg.d $f0, $f0 +; CHECK-NOT-NM: mul.d $f0, $f12, $f14 +; CHECK-NOT-NM: neg.d $f0, $f0 + + %mul = fmul nnan double %f, %g + %add = fadd nnan double %mul, %h + %sub = fsub nnan double -0.000000e+00, %add + ret double %sub +} + +define float @sub1(float %f, float %g, float %h) local_unnamed_addr #0 { +entry: +; ALL-LABEL: sub1 + +; CHECK-NM-64: nmsub.s $f0, $f14, $f12, $f13 +; CHECK-NM: nmsub.s $f0, $f0, $f12, $f14 +; CHECK-MM: NMSUB_S_MM +; CHECK-NOT-NM-64 mul.s $f0, $f12, $f13 +; CHECK-NOT-NM-64: neg.s $f0, $f0 +; CHECK-NOT-NM: mul.s $f0, $f12, $f14 +; CHECK-NOT-NM: neg.s $f0, $f0 + + %mul = fmul nnan float %f, %g + %sub = fsub nnan float %mul, %h + %sub1 = fsub nnan float -0.000000e+00, %sub + ret float %sub1 +} + +define double @sub2(double %f, double %g, double %h) local_unnamed_addr #0 { +entry: +; ALL-LABEL: sub2 + +; CHECK-NM-64: nmsub.d $f0, $f14, $f12, $f13 +; CHECK-NM: nmsub.d $f0, $f0, $f12, $f14 +; CHECK-MM: NMSUB_D32_MM +; CHECK-NOT-NM-64 mul.d $f0, $f12, $f13 +; CHECK-NOT-NM-64: neg.d $f0, $f0 +; CHECK-NOT-NM: mul.d $f0, $f12, $f14 +; CHECK-NOT-NM: neg.d $f0, $f0 + + %mul = fmul nnan double %f, %g + %sub = fsub nnan double %mul, %h + %sub1 = fsub nnan double -0.000000e+00, %sub + ret double %sub1 +} -- 2.50.1