diff mbox

[gcc/MIPS] Add options to disable/enable madd.fmt/msub.fmt instructions

Message ID 150DBC9F-6E26-4F10-A2B0-0AB8E13D6B86@imgtec.com
State New
Headers show

Commit Message

Yunqiang Su Dec. 22, 2016, 4:12 a.m. UTC
[PATCH] Add options to disable/enable madd.fmt/msub.fmt instructions

The build-time options are:
  --with-unfused-madd4=yes/no
  --without-unfused-madd4

The runtime options are:
  -munfused-madd4
  -mno-unfused-madd4

These options are needed due to madd.fmt/msub.fmt on some
platform is broken, which may generate wrong calculator result.

Comments

Paul Hua Dec. 22, 2016, 5:11 a.m. UTC | #1
Hi,

> +On MIPS targets, set the @option{-mno-unfused-madd4} option by default.
> +On some platform, like Loongson 3A/3B 1000/2000/3000, madd.fmt/msub.fmt is
> +broken, which may which may generate wrong calculator result.

The Loongson 3A/3B 1000/2000/3000 madd.fmt/msub.fmt are fused madd instructions.
Can you try this patch:
https://gcc.gnu.org/ml/gcc-patches/2016-11/msg00255.html .

Is this patch testing on trunk? I build the trunk failure for a long time.
Yunqiang Su Dec. 22, 2016, 1:32 p.m. UTC | #2
> 在 2016年12月22日,13:11,Paul Hua <paul.hua.gm@gmail.com> 写道:

> 

> Hi,

> 

>> +On MIPS targets, set the @option{-mno-unfused-madd4} option by default.

>> +On some platform, like Loongson 3A/3B 1000/2000/3000, madd.fmt/msub.fmt is

>> +broken, which may which may generate wrong calculator result.

> 

> The Loongson 3A/3B 1000/2000/3000 madd.fmt/msub.fmt are fused madd instructions.

> Can you try this patch:

> https://gcc.gnu.org/ml/gcc-patches/2016-11/msg00255.html .

> 

> Is this patch testing on trunk? I build the trunk failure for a long time.


I don’t think your patch is correct.
No matter Loongson’s madd.fmt are fused or unfused, they give wrong result.
So for Loongson, madd.fmt should be disabled at all.
you can test it with:

#include <stdio.h>

double a = 0.6;
double b = 0.4;
double c = 0.6;
double d = 0.4;

int main(void)
{
        double x = a * b - c * d;
        printf("%le\n", x);
        return 0;
}
diff mbox

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 7afbc54bc78..a3fdb0273c0 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3940,7 +3940,7 @@  case "${target}" in
 		;;
 
 	mips*-*-*)
-		supported_defaults="abi arch arch_32 arch_64 float fpu nan fp_32 odd_spreg_32 tune tune_32 tune_64 divide llsc mips-plt synci"
+		supported_defaults="abi arch arch_32 arch_64 float fpu nan fp_32 odd_spreg_32 unfused_madd4 tune tune_32 tune_64 divide llsc mips-plt synci"
 
 		case ${with_float} in
 		"" | soft | hard)
@@ -3997,6 +3997,19 @@  case "${target}" in
 			exit 1
 			;;
 		esac
+		
+		case ${with_unfused_madd4} in
+		"" | yes)
+			with_unfused_madd4="unfused-madd4"
+			;;
+		no)
+			with_unfused_madd4="no-unfused-madd4"
+			;;
+		*)
+			echo "Unknown unfused_madd4 type used in --with-unfused-madd4=$with_unfused_madd4" 1>&2
+			exit 1
+			;;
+		esac
 
 		case ${with_abi} in
 		"" | 32 | o64 | n32 | 64 | eabi)
@@ -4496,7 +4509,7 @@  case ${target} in
 esac
 
 t=
-all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 divide llsc mips-plt synci tls"
+all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan fp_32 odd_spreg_32 unfused_madd4 divide llsc mips-plt synci tls"
 for option in $all_defaults
 do
 	eval "val=\$with_"`echo $option | sed s/-/_/g`
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index c7eb2a8e7bd..c2c231a483c 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -19829,6 +19829,16 @@  mips_option_override (void)
          will be produced.  */
       target_flags |= MASK_ODD_SPREG;
     }
+  
+  /* If neither -munfused-madd nor -mno-unfused-madd was given on the command
+     line, set MASK_UNFSUED_MADD based on the ISA.  */
+  if ((target_flags_explicit & MASK_UNFUSED_MADD4) == 0)
+    {
+      if (!ISA_HAS_UNFUSED_MADD4)
+	target_flags &= ~MASK_UNFUSED_MADD4;
+      else
+	target_flags |= MASK_UNFUSED_MADD4;
+    }
 
   if (!ISA_HAS_COMPACT_BRANCHES && mips_cb == MIPS_CB_ALWAYS)
     {
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index bb66c428dd1..6cf571906a6 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -863,6 +863,7 @@  struct mips_cpu_info {
 	    ":%{!msoft-float:%{!msingle-float:%{!mfp*:%{!mmsa:-mfp%(VALUE)}}}}}" }, \
   {"odd_spreg_32", "%{" OPT_ARCH32 ":%{!msoft-float:%{!msingle-float:" \
 		   "%{!modd-spreg:%{!mno-odd-spreg:-m%(VALUE)}}}}}" }, \
+  {"unfused_madd4", "%{!munfused-madd4:%{!mno-unfused-madd4:-m%(VALUE)}}" }, \
   {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
   {"llsc", "%{!mllsc:%{!mno-llsc:-m%(VALUE)}}" }, \
   {"mips-plt", "%{!mplt:%{!mno-plt:-m%(VALUE)}}" }, \
@@ -1060,7 +1061,7 @@  struct mips_cpu_info {
 
 /* ISA has 4 operand unfused madd instructions of the form
    'd = [+-] (a * b [+-] c)'.  */
-#define ISA_HAS_UNFUSED_MADD4	(ISA_HAS_FP4 && !TARGET_MIPS8000)
+#define ISA_HAS_UNFUSED_MADD4	(ISA_HAS_FP4 && !TARGET_MIPS8000 && TARGET_UNFUSED_MADD4)
 
 /* ISA has 3 operand r6 fused madd instructions of the form
    'c = c [+-] (a * b)'.  */
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index 08dd83e14ce..b154752a0df 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -416,6 +416,10 @@  modd-spreg
 Target Report Mask(ODD_SPREG)
 Enable use of odd-numbered single-precision registers.
 
+munfused-madd4
+Target Report Mask(UNFUSED_MADD4)
+Enable unfused multiply-add/multiply-sub instruction, aka madd.fmt/msub.fmt.
+
 mframe-header-opt
 Target Report Var(flag_frame_header_optimization) Optimization
 Optimize frame header.
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index b911d76dd66..00501c88420 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1320,6 +1320,16 @@  On MIPS targets, set the @option{-mno-odd-spreg} option by default when using
 the o32 ABI.  This is normally used in conjunction with
 @option{--with-fp-32=64} in order to target the o32 FP64A ABI extension.
 
+@item --with-unfused-madd4
+On MIPS targets, set the @option{-munfused-madd4} option by default.
+On some platform, like Loongson 3A/3B 1000/2000/3000, madd.fmt/msub.fmt is
+broken, which may which may generate wrong calculator result.
+
+@item --without-unfused-madd4
+On MIPS targets, set the @option{-mno-unfused-madd4} option by default.
+On some platform, like Loongson 3A/3B 1000/2000/3000, madd.fmt/msub.fmt is
+broken, which may which may generate wrong calculator result.
+
 @item --with-nan=@var{encoding}
 On MIPS targets, set the default encoding convention to use for the
 special not-a-number (NaN) IEEE 754 floating-point data.  The
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 5c92fe69335..3ac80280eb8 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -862,6 +862,7 @@  Objective-C and Objective-C++ Dialects}.
 -mgp32  -mgp64  -mfp32  -mfpxx  -mfp64  -mhard-float  -msoft-float @gol
 -mno-float  -msingle-float  -mdouble-float @gol
 -modd-spreg -mno-odd-spreg @gol
+-munfused-madd4 -mno-unfused-madd4 @gol
 -mabs=@var{mode}  -mnan=@var{encoding} @gol
 -mdsp  -mno-dsp  -mdspr2  -mno-dspr2 @gol
 -mmcu -mmno-mcu @gol
@@ -19238,6 +19239,14 @@  for the o32 ABI.  This is the default for processors that are known to
 support these registers.  When using the o32 FPXX ABI, @option{-mno-odd-spreg}
 is set by default.
 
+@item -munfused-madd4
+@itemx -mno-unfused-madd4
+@opindex munfused-madd4
+@opindex munfused-madd4
+Enable or disable generate madd.fmt/msub.fmt instructions.
+On some platform, like Loongson 3A/3B 1000/2000/3000, madd.fmt/msub.fmt is
+broken, which may generate wrong calculator result.
+
 @item -mabs=2008
 @itemx -mabs=legacy
 @opindex mabs=2008