Skip to content

Commit

Permalink
[mips] Generate NMADD and NMSUB instructions when fneg node is present
Browse files Browse the repository at this point in the history
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

llvm-svn: 311862
  • Loading branch information
petar-jovanovic committed Aug 27, 2017
1 parent 617e898 commit f11daad
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
6 changes: 6 additions & 0 deletions llvm/lib/Target/Mips/MicroMipsInstrFPU.td
Expand Up @@ -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
//===----------------------------------------------------------------------===//
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/Target/Mips/MipsInstrFPU.td
Expand Up @@ -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 {
Expand Down
83 changes: 83 additions & 0 deletions 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
}

0 comments on commit f11daad

Please sign in to comment.