summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/Mips/MicroMipsInstrFPU.td6
-rw-r--r--llvm/lib/Target/Mips/MipsInstrFPU.td14
-rw-r--r--llvm/test/CodeGen/Mips/nmadd.ll83
3 files changed, 103 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td b/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
index 5600f71ff68..f0bbc840487 100644
--- a/llvm/lib/Target/Mips/MicroMipsInstrFPU.td
+++ b/llvm/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<NMADD_S_MM, NMSUB_S_MM, FGR32Opnd>;
+ defm : NMADD_NMSUB<NMADD_D32_MM, NMSUB_D32_MM, AFGR64Opnd>;
+}
+
//===----------------------------------------------------------------------===//
// Floating Point Patterns
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/Mips/MipsInstrFPU.td b/llvm/lib/Target/Mips/MipsInstrFPU.td
index 115494dbce4..999e5fadb81 100644
--- a/llvm/lib/Target/Mips/MipsInstrFPU.td
+++ b/llvm/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<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/llvm/test/CodeGen/Mips/nmadd.ll b/llvm/test/CodeGen/Mips/nmadd.ll
new file mode 100644
index 00000000000..dfaa6ed8666
--- /dev/null
+++ b/llvm/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
+}
OpenPOWER on IntegriCloud