]> granicus.if.org Git - llvm/commitdiff
[mips] Generate NMADD and NMSUB instructions when fneg node is present
authorPetar Jovanovic <petar.jovanovic@imgtec.com>
Sun, 27 Aug 2017 21:07:24 +0000 (21:07 +0000)
committerPetar Jovanovic <petar.jovanovic@imgtec.com>
Sun, 27 Aug 2017 21:07:24 +0000 (21:07 +0000)
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
lib/Target/Mips/MipsInstrFPU.td
test/CodeGen/Mips/nmadd.ll [new file with mode: 0644]

index 5600f71ff68e9be2a9bf218679d2b30bafe5209e..f0bbc84048769fe29ebb49473bca0c25b3553752 100644 (file)
@@ -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<NMADD_S_MM, NMSUB_S_MM, FGR32Opnd>;
+  defm : NMADD_NMSUB<NMADD_D32_MM, NMSUB_D32_MM, AFGR64Opnd>;
+}
+
 //===----------------------------------------------------------------------===//
 // Floating Point Patterns
 //===----------------------------------------------------------------------===//
index 115494dbce4be23466de2886031b958005f2cdf5..999e5fadb817b5c011752b392122af7ee0321291 100644 (file)
@@ -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<Instruction Nmadd, Instruction Nmsub, RegisterOperand RC> {
+  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<NMADD_S, NMSUB_S, FGR32Opnd>, INSN_MIPS4_32R2_NOT_32R6_64R6;
+  defm : NMADD_NMSUB<NMADD_D32, NMSUB_D32, AFGR64Opnd>, FGR_32, INSN_MIPS4_32R2_NOT_32R6_64R6;
+  defm : NMADD_NMSUB<NMADD_D64, NMSUB_D64, FGR64Opnd>, 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 (file)
index 0000000..dfaa6ed
--- /dev/null
@@ -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
+}