[llvm] [SPARC] Use FMA instructions when we have UA2007 (PR #148434)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 18 11:27:40 PDT 2025
https://github.com/koachan updated https://github.com/llvm/llvm-project/pull/148434
>From 407b6023ce891775d2d78162ce60dc1415374ea3 Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Sun, 13 Jul 2025 21:02:43 +0700
Subject: [PATCH 1/2] [SPARC] Use FMA instructions when we have UA2007
---
llvm/lib/Target/Sparc/SparcISelLowering.cpp | 15 ++-
llvm/lib/Target/Sparc/SparcISelLowering.h | 5 +
llvm/lib/Target/Sparc/SparcInstrUAOSA.td | 12 ++
llvm/test/CodeGen/SPARC/float-ua2007.ll | 138 ++++++++++++++++++++
4 files changed, 168 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/CodeGen/SPARC/float-ua2007.ll
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index 21dbe8f585b3e..8dd8071fc6fab 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -1799,12 +1799,14 @@ SparcTargetLowering::SparcTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::FCOS , MVT::f64, Expand);
setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
setOperationAction(ISD::FREM , MVT::f64, Expand);
- setOperationAction(ISD::FMA , MVT::f64, Expand);
+ setOperationAction(ISD::FMA, MVT::f64,
+ Subtarget->isUA2007() ? Legal : Expand);
setOperationAction(ISD::FSIN , MVT::f32, Expand);
setOperationAction(ISD::FCOS , MVT::f32, Expand);
setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
setOperationAction(ISD::FREM , MVT::f32, Expand);
- setOperationAction(ISD::FMA, MVT::f32, Expand);
+ setOperationAction(ISD::FMA, MVT::f32,
+ Subtarget->isUA2007() ? Legal : Expand);
setOperationAction(ISD::ROTL , MVT::i32, Expand);
setOperationAction(ISD::ROTR , MVT::i32, Expand);
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
@@ -3570,6 +3572,15 @@ bool SparcTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
return isCheapToSpeculateCtlz(Ty);
}
+bool SparcTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
+ EVT VT) const {
+ return Subtarget->isUA2007();
+}
+
+bool SparcTargetLowering::enableAggressiveFMAFusion(EVT VT) const {
+ return Subtarget->isUA2007();
+}
+
// Override to disable global variable loading on Linux.
void SparcTargetLowering::insertSSPDeclarations(Module &M) const {
if (!Subtarget->isTargetLinux())
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h
index 0d220f8c3d32e..58dcd4c9bfa2f 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.h
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.h
@@ -177,6 +177,11 @@ namespace llvm {
bool isCheapToSpeculateCttz(Type *Ty) const override;
+ bool enableAggressiveFMAFusion(EVT VT) const override;
+
+ bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
+ EVT VT) const override;
+
bool shouldInsertFencesForAtomic(const Instruction *I) const override {
// FIXME: We insert fences for each atomics and generate
// sub-optimal code for PSO/TSO. (Approximately nobody uses any
diff --git a/llvm/lib/Target/Sparc/SparcInstrUAOSA.td b/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
index 3a30e552e6db1..ffd4423137e3f 100644
--- a/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
+++ b/llvm/lib/Target/Sparc/SparcInstrUAOSA.td
@@ -66,3 +66,15 @@ defm CXBCOND : F2_56<"cxb", 1>;
def FPMADDX : FourOp<"fpmaddx", 0b110111, 0b0000, DFPRegs>;
def FPMADDXHI : FourOp<"fpmaddxhi", 0b110111, 0b0100, DFPRegs>;
} // Predicates = [HasOSA2011]
+
+// UA2007 instruction patterns.
+let Predicates = [HasUA2007] in {
+def : Pat<(f32 (any_fma f32:$rs1, f32:$rs2, f32:$add)), (FMADDS $rs1, $rs2, $add)>;
+def : Pat<(f64 (any_fma f64:$rs1, f64:$rs2, f64:$add)), (FMADDD $rs1, $rs2, $add)>;
+def : Pat<(f32 (any_fma f32:$rs1, f32:$rs2, (fneg f32:$sub))), (FMSUBS $rs1, $rs2, $sub)>;
+def : Pat<(f64 (any_fma f64:$rs1, f64:$rs2, (fneg f64:$sub))), (FMSUBD $rs1, $rs2, $sub)>;
+def : Pat<(f32 (fneg (any_fma f32:$rs1, f32:$rs2, f32:$add))), (FNMADDS $rs1, $rs2, $add)>;
+def : Pat<(f64 (fneg (any_fma f64:$rs1, f64:$rs2, f64:$add))), (FNMADDD $rs1, $rs2, $add)>;
+def : Pat<(f32 (fneg (any_fma f32:$rs1, f32:$rs2, (fneg f32:$sub)))), (FNMSUBS $rs1, $rs2, $sub)>;
+def : Pat<(f64 (fneg (any_fma f64:$rs1, f64:$rs2, (fneg f64:$sub)))), (FNMSUBD $rs1, $rs2, $sub)>;
+} // Predicates = [HasUA2007]
diff --git a/llvm/test/CodeGen/SPARC/float-ua2007.ll b/llvm/test/CodeGen/SPARC/float-ua2007.ll
new file mode 100644
index 0000000000000..9534333927639
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/float-ua2007.ll
@@ -0,0 +1,138 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=sparc64 -mattr=-ua2007 < %s | FileCheck %s -check-prefix=NO-UA2007
+; RUN: llc -mtriple=sparc64 -mattr=+ua2007 < %s | FileCheck %s -check-prefix=UA2007
+
+define float @fmadds(float %a, float %b, float %c) nounwind {
+; NO-UA2007-LABEL: fmadds:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: fmuls %f1, %f3, %f0
+; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: fadds %f0, %f5, %f0
+;
+; UA2007-LABEL: fmadds:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fmadds %f1, %f3, %f5, %f0
+ %ret = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
+ ret float %ret
+}
+
+define double @fmaddd(double %a, double %b, double %c) nounwind {
+; NO-UA2007-LABEL: fmaddd:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: fmuld %f0, %f2, %f0
+; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: faddd %f0, %f4, %f0
+;
+; UA2007-LABEL: fmaddd:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fmaddd %f0, %f2, %f4, %f0
+ %ret = call double @llvm.fmuladd.f64(double %a, double %b, double %c)
+ ret double %ret
+}
+
+define float @fmsubs(float %a, float %b, float %c) nounwind {
+; NO-UA2007-LABEL: fmsubs:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: fmuls %f1, %f3, %f0
+; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: fsubs %f0, %f5, %f0
+;
+; UA2007-LABEL: fmsubs:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fmsubs %f1, %f3, %f5, %f0
+ %neg = fneg float %c
+ %ret = call float @llvm.fmuladd.f32(float %a, float %b, float %neg)
+ ret float %ret
+}
+
+define double @fmsubd(double %a, double %b, double %c) nounwind {
+; NO-UA2007-LABEL: fmsubd:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: fmuld %f0, %f2, %f0
+; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: fsubd %f0, %f4, %f0
+;
+; UA2007-LABEL: fmsubd:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fmsubd %f0, %f2, %f4, %f0
+ %neg = fneg double %c
+ %ret = call double @llvm.fmuladd.f64(double %a, double %b, double %neg)
+ ret double %ret
+}
+
+define float @fnmadds(float %a, float %b, float %c) nounwind {
+; NO-UA2007-LABEL: fnmadds:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: fmuls %f1, %f3, %f0
+; NO-UA2007-NEXT: fadds %f0, %f5, %f0
+; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: fnegs %f0, %f0
+;
+; UA2007-LABEL: fnmadds:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fnmadds %f1, %f3, %f5, %f0
+ %fma = call float @llvm.fmuladd.f32(float %a, float %b, float %c)
+ %ret = fneg float %fma
+ ret float %ret
+}
+
+define double @fnmaddd(double %a, double %b, double %c) nounwind {
+; NO-UA2007-LABEL: fnmaddd:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: fmuld %f0, %f2, %f0
+; NO-UA2007-NEXT: faddd %f0, %f4, %f0
+; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: fnegd %f0, %f0
+;
+; UA2007-LABEL: fnmaddd:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fnmaddd %f0, %f2, %f4, %f0
+ %fma = call double @llvm.fmuladd.f64(double %a, double %b, double %c)
+ %ret = fneg double %fma
+ ret double %ret
+}
+
+define float @fnmsubs(float %a, float %b, float %c) nounwind {
+; NO-UA2007-LABEL: fnmsubs:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: fmuls %f1, %f3, %f0
+; NO-UA2007-NEXT: fsubs %f0, %f5, %f0
+; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: fnegs %f0, %f0
+;
+; UA2007-LABEL: fnmsubs:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fnmsubs %f1, %f3, %f5, %f0
+ %neg = fneg float %c
+ %fma = call float @llvm.fmuladd.f32(float %a, float %b, float %neg)
+ %ret = fneg float %fma
+ ret float %ret
+}
+
+define double @fnmsubd(double %a, double %b, double %c) nounwind {
+; NO-UA2007-LABEL: fnmsubd:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: fmuld %f0, %f2, %f0
+; NO-UA2007-NEXT: fsubd %f0, %f4, %f0
+; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: fnegd %f0, %f0
+;
+; UA2007-LABEL: fnmsubd:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fnmsubd %f0, %f2, %f4, %f0
+ %neg = fneg double %c
+ %fma = call double @llvm.fmuladd.f64(double %a, double %b, double %neg)
+ %ret = fneg double %fma
+ ret double %ret
+}
+
+declare float @llvm.fmuladd.f32(float, float, float)
+declare double @llvm.fmuladd.f64(double, double, double)
>From a724dece873d848c06ea9beef3ef2f9881b7cb5e Mon Sep 17 00:00:00 2001
From: Koakuma <koachan at protonmail.com>
Date: Sat, 19 Jul 2025 01:27:09 +0700
Subject: [PATCH 2/2] Add combine tests & change FMA fusion to be conditional
on softfloat
---
llvm/lib/Target/Sparc/SparcISelLowering.cpp | 4 +-
llvm/test/CodeGen/SPARC/float-ua2007.ll | 221 +++++++++++++++++---
2 files changed, 197 insertions(+), 28 deletions(-)
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index 8dd8071fc6fab..7beb0ab8f80dc 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -3574,11 +3574,11 @@ bool SparcTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {
bool SparcTargetLowering::isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
EVT VT) const {
- return Subtarget->isUA2007();
+ return !Subtarget->useSoftFloat();
}
bool SparcTargetLowering::enableAggressiveFMAFusion(EVT VT) const {
- return Subtarget->isUA2007();
+ return !Subtarget->useSoftFloat();
}
// Override to disable global variable loading on Linux.
diff --git a/llvm/test/CodeGen/SPARC/float-ua2007.ll b/llvm/test/CodeGen/SPARC/float-ua2007.ll
index 9534333927639..5e7194463507c 100644
--- a/llvm/test/CodeGen/SPARC/float-ua2007.ll
+++ b/llvm/test/CodeGen/SPARC/float-ua2007.ll
@@ -1,13 +1,15 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc -mtriple=sparc64 -mattr=-ua2007 < %s | FileCheck %s -check-prefix=NO-UA2007
-; RUN: llc -mtriple=sparc64 -mattr=+ua2007 < %s | FileCheck %s -check-prefix=UA2007
+; RUN: llc -mtriple=sparc64 --fp-contract=fast -mattr=-ua2007 < %s | FileCheck %s -check-prefix=NO-UA2007
+; RUN: llc -mtriple=sparc64 --fp-contract=fast -mattr=+ua2007 < %s | FileCheck %s -check-prefix=UA2007
define float @fmadds(float %a, float %b, float %c) nounwind {
; NO-UA2007-LABEL: fmadds:
; NO-UA2007: ! %bb.0:
-; NO-UA2007-NEXT: fmuls %f1, %f3, %f0
-; NO-UA2007-NEXT: retl
-; NO-UA2007-NEXT: fadds %f0, %f5, %f0
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fmaf
+; NO-UA2007-NEXT: nop
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
;
; UA2007-LABEL: fmadds:
; UA2007: ! %bb.0:
@@ -20,9 +22,11 @@ define float @fmadds(float %a, float %b, float %c) nounwind {
define double @fmaddd(double %a, double %b, double %c) nounwind {
; NO-UA2007-LABEL: fmaddd:
; NO-UA2007: ! %bb.0:
-; NO-UA2007-NEXT: fmuld %f0, %f2, %f0
-; NO-UA2007-NEXT: retl
-; NO-UA2007-NEXT: faddd %f0, %f4, %f0
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fma
+; NO-UA2007-NEXT: nop
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
;
; UA2007-LABEL: fmaddd:
; UA2007: ! %bb.0:
@@ -35,9 +39,11 @@ define double @fmaddd(double %a, double %b, double %c) nounwind {
define float @fmsubs(float %a, float %b, float %c) nounwind {
; NO-UA2007-LABEL: fmsubs:
; NO-UA2007: ! %bb.0:
-; NO-UA2007-NEXT: fmuls %f1, %f3, %f0
-; NO-UA2007-NEXT: retl
-; NO-UA2007-NEXT: fsubs %f0, %f5, %f0
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fmaf
+; NO-UA2007-NEXT: fnegs %f5, %f5
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
;
; UA2007-LABEL: fmsubs:
; UA2007: ! %bb.0:
@@ -51,9 +57,11 @@ define float @fmsubs(float %a, float %b, float %c) nounwind {
define double @fmsubd(double %a, double %b, double %c) nounwind {
; NO-UA2007-LABEL: fmsubd:
; NO-UA2007: ! %bb.0:
-; NO-UA2007-NEXT: fmuld %f0, %f2, %f0
-; NO-UA2007-NEXT: retl
-; NO-UA2007-NEXT: fsubd %f0, %f4, %f0
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fma
+; NO-UA2007-NEXT: fnegd %f4, %f4
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
;
; UA2007-LABEL: fmsubd:
; UA2007: ! %bb.0:
@@ -67,10 +75,12 @@ define double @fmsubd(double %a, double %b, double %c) nounwind {
define float @fnmadds(float %a, float %b, float %c) nounwind {
; NO-UA2007-LABEL: fnmadds:
; NO-UA2007: ! %bb.0:
-; NO-UA2007-NEXT: fmuls %f1, %f3, %f0
-; NO-UA2007-NEXT: fadds %f0, %f5, %f0
-; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fmaf
+; NO-UA2007-NEXT: nop
; NO-UA2007-NEXT: fnegs %f0, %f0
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
;
; UA2007-LABEL: fnmadds:
; UA2007: ! %bb.0:
@@ -84,10 +94,12 @@ define float @fnmadds(float %a, float %b, float %c) nounwind {
define double @fnmaddd(double %a, double %b, double %c) nounwind {
; NO-UA2007-LABEL: fnmaddd:
; NO-UA2007: ! %bb.0:
-; NO-UA2007-NEXT: fmuld %f0, %f2, %f0
-; NO-UA2007-NEXT: faddd %f0, %f4, %f0
-; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fma
+; NO-UA2007-NEXT: nop
; NO-UA2007-NEXT: fnegd %f0, %f0
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
;
; UA2007-LABEL: fnmaddd:
; UA2007: ! %bb.0:
@@ -101,10 +113,12 @@ define double @fnmaddd(double %a, double %b, double %c) nounwind {
define float @fnmsubs(float %a, float %b, float %c) nounwind {
; NO-UA2007-LABEL: fnmsubs:
; NO-UA2007: ! %bb.0:
-; NO-UA2007-NEXT: fmuls %f1, %f3, %f0
-; NO-UA2007-NEXT: fsubs %f0, %f5, %f0
-; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fmaf
+; NO-UA2007-NEXT: fnegs %f5, %f5
; NO-UA2007-NEXT: fnegs %f0, %f0
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
;
; UA2007-LABEL: fnmsubs:
; UA2007: ! %bb.0:
@@ -119,10 +133,12 @@ define float @fnmsubs(float %a, float %b, float %c) nounwind {
define double @fnmsubd(double %a, double %b, double %c) nounwind {
; NO-UA2007-LABEL: fnmsubd:
; NO-UA2007: ! %bb.0:
-; NO-UA2007-NEXT: fmuld %f0, %f2, %f0
-; NO-UA2007-NEXT: fsubd %f0, %f4, %f0
-; NO-UA2007-NEXT: retl
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fma
+; NO-UA2007-NEXT: fnegd %f4, %f4
; NO-UA2007-NEXT: fnegd %f0, %f0
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
;
; UA2007-LABEL: fnmsubd:
; UA2007: ! %bb.0:
@@ -134,5 +150,158 @@ define double @fnmsubd(double %a, double %b, double %c) nounwind {
ret double %ret
}
+
+define float @combine_madds(float %a, float %b, float %c) nounwind {
+; NO-UA2007-LABEL: combine_madds:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fmaf
+; NO-UA2007-NEXT: nop
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
+;
+; UA2007-LABEL: combine_madds:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fmadds %f1, %f3, %f5, %f0
+ %mul = fmul float %a, %b
+ %add = fadd float %mul, %c
+ ret float %add
+}
+
+define double @combine_maddd(double %a, double %b, double %c) nounwind {
+; NO-UA2007-LABEL: combine_maddd:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fma
+; NO-UA2007-NEXT: nop
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
+;
+; UA2007-LABEL: combine_maddd:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fmaddd %f0, %f2, %f4, %f0
+ %mul = fmul double %a, %b
+ %add = fadd double %mul, %c
+ ret double %add
+}
+
+define float @combine_msubs(float %a, float %b, float %c) nounwind {
+; NO-UA2007-LABEL: combine_msubs:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fmaf
+; NO-UA2007-NEXT: fnegs %f5, %f5
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
+;
+; UA2007-LABEL: combine_msubs:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fmsubs %f1, %f3, %f5, %f0
+ %mul = fmul float %a, %b
+ %sub = fsub float %mul, %c
+ ret float %sub
+}
+
+define double @combine_msubd(double %a, double %b, double %c) nounwind {
+; NO-UA2007-LABEL: combine_msubd:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fma
+; NO-UA2007-NEXT: fnegd %f4, %f4
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
+;
+; UA2007-LABEL: combine_msubd:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fmsubd %f0, %f2, %f4, %f0
+ %mul = fmul double %a, %b
+ %sub = fsub double %mul, %c
+ ret double %sub
+}
+
+define float @combine_nmadds(float %a, float %b, float %c) nounwind {
+; NO-UA2007-LABEL: combine_nmadds:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fmaf
+; NO-UA2007-NEXT: nop
+; NO-UA2007-NEXT: fnegs %f0, %f0
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
+;
+; UA2007-LABEL: combine_nmadds:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fnmadds %f1, %f3, %f5, %f0
+ %mul = fmul float %a, %b
+ %add = fadd float %mul, %c
+ %neg = fneg float %add
+ ret float %neg
+}
+
+define double @combine_nmaddd(double %a, double %b, double %c) nounwind {
+; NO-UA2007-LABEL: combine_nmaddd:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fma
+; NO-UA2007-NEXT: nop
+; NO-UA2007-NEXT: fnegd %f0, %f0
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
+;
+; UA2007-LABEL: combine_nmaddd:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fnmaddd %f0, %f2, %f4, %f0
+ %mul = fmul double %a, %b
+ %add = fadd double %mul, %c
+ %neg = fneg double %add
+ ret double %neg
+}
+
+define float @combine_nmsubs(float %a, float %b, float %c) nounwind {
+; NO-UA2007-LABEL: combine_nmsubs:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fmaf
+; NO-UA2007-NEXT: fnegs %f5, %f5
+; NO-UA2007-NEXT: fnegs %f0, %f0
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
+;
+; UA2007-LABEL: combine_nmsubs:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fnmsubs %f1, %f3, %f5, %f0
+ %mul = fmul float %a, %b
+ %sub = fsub float %mul, %c
+ %neg = fneg float %sub
+ ret float %neg
+}
+
+define double @combine_nmsubd(double %a, double %b, double %c) nounwind {
+; NO-UA2007-LABEL: combine_nmsubd:
+; NO-UA2007: ! %bb.0:
+; NO-UA2007-NEXT: save %sp, -176, %sp
+; NO-UA2007-NEXT: call fma
+; NO-UA2007-NEXT: fnegd %f4, %f4
+; NO-UA2007-NEXT: fnegd %f0, %f0
+; NO-UA2007-NEXT: ret
+; NO-UA2007-NEXT: restore
+;
+; UA2007-LABEL: combine_nmsubd:
+; UA2007: ! %bb.0:
+; UA2007-NEXT: retl
+; UA2007-NEXT: fnmsubd %f0, %f2, %f4, %f0
+ %mul = fmul double %a, %b
+ %sub = fsub double %mul, %c
+ %neg = fneg double %sub
+ ret double %neg
+}
+
declare float @llvm.fmuladd.f32(float, float, float)
declare double @llvm.fmuladd.f64(double, double, double)
More information about the llvm-commits
mailing list