Patchwork [1/N,ia64] -mfused-madd cleanup

login
register
mail settings
Submitter Richard Henderson
Date Nov. 12, 2010, 12:38 a.m.
Message ID <4CDC8C7C.3060509@redhat.com>
Download mbox | patch
Permalink /patch/70896/
State New
Headers show

Comments

Richard Henderson - Nov. 12, 2010, 12:38 a.m.
On 11/10/2010 03:24 PM, Steve Ellcey wrote:
> 
> Do you know if getting rid of rules like this one will affect the code:
> 
> -(define_insn "*madddf4_trunc"
> -  [(set (match_operand:SF 0 "fr_register_operand" "=f")
> -       (float_truncate:SF
> -         (plus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
> -                           (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
> -                  (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
> -  "TARGET_FUSED_MADD"
> -  "fma.s %0 = %F1, %F2, %F3"
> -  [(set_attr "itanium_class" "fmac")])
> 
> 
> I am wondering if relying on FMA_EXPR will change the generated code for
> "float x = (float) a * b + c" where a, b, and c are doubles.  Will we
> generate an fma followed by an fnorm truncation instead of just a fma.s.

Revised patch.

  * Given that this is the very same insn (albeit with different arguments) that
    implements the FADD and FMUL patterns, and we unconditionally supply truncating
    versions for those, and the fact that we have been unconditionally supplying
    these patterns to-date and no one has complained: I will continue to supply
    them unconditionally.

    Thus, float_truncate patterns re-added.

  * RTX costing for FMA, FADD, FMUL.

Ok?

Bootstrap and tested on ia64-linux.


r~
Steve Ellcey - Nov. 15, 2010, 8:29 p.m.
On Thu, 2010-11-11 at 16:38 -0800, Richard Henderson wrote:

> Revised patch.
> 
> Ok?
> 
> Bootstrap and tested on ia64-linux.
> 
> 
> r~

Sorry for not getting back sooner, I was under the weather for a bit.
There is something odd going on with these patches.  When I apply them
here I get a build failure with a stage2/stage3 comparision failure.
This is happening on IA64 Linux and HP-UX but I haven't had a chance to
figure out why yet.

Steve Ellcey
sje@cup.hp.com
Andrew Pinski - Nov. 15, 2010, 8:31 p.m.
On Mon, Nov 15, 2010 at 12:29 PM, Steve Ellcey <sje@cup.hp.com> wrote:
> This is happening on IA64 Linux and HP-UX but I haven't had a chance to
> figure out why yet.

Was it in a libcpp file?  If so that was just fixed this morning.

Thanks,
Andrew Pinski
Steve Ellcey - Nov. 15, 2010, 9 p.m.
On Mon, 2010-11-15 at 12:31 -0800, Andrew Pinski wrote:
> On Mon, Nov 15, 2010 at 12:29 PM, Steve Ellcey <sje@cup.hp.com> wrote:
> > This is happening on IA64 Linux and HP-UX but I haven't had a chance to
> > figure out why yet.
> 
> Was it in a libcpp file?  If so that was just fixed this morning.
> 
> Thanks,
> Andrew Pinski

Yes, 'libcpp/symtab.o differs'.  Other then that problem the code looked
OK to me so I have no objection to it being checked in.

Steve Ellcey
sje@cup.hp.com
Steve Ellcey - Nov. 16, 2010, 4:52 p.m.
On Mon, 2010-11-15 at 12:31 -0800, Andrew Pinski wrote:
> On Mon, Nov 15, 2010 at 12:29 PM, Steve Ellcey <sje@cup.hp.com> wrote:
> > This is happening on IA64 Linux and HP-UX but I haven't had a chance to
> > figure out why yet.
> 
> Was it in a libcpp file?  If so that was just fixed this morning.
> 
> Thanks,
> Andrew Pinski

Hm, that failure was with a libcpp failure but this morning I am seeing
a bootstrap failure on IA64 Linux in fortran/trans-openmp.o

Comparing stages 2 and 3
warning: gcc/cc1plus-checksum.o differs
warning: gcc/cc1-checksum.o differs
Bootstrap comparison failure!
gcc/fortran/trans-openmp.o differs

This is at version 166790 so it should have the fix for PR 46474 in it.

Steve Ellcey
sje@cup.hp.com
Richard Henderson - Nov. 16, 2010, 6:04 p.m.
On 11/16/2010 08:52 AM, Steve Ellcey wrote:
> Hm, that failure was with a libcpp failure but this morning I am seeing
> a bootstrap failure on IA64 Linux in fortran/trans-openmp.o
> 
> Comparing stages 2 and 3
> warning: gcc/cc1plus-checksum.o differs
> warning: gcc/cc1-checksum.o differs
> Bootstrap comparison failure!
> gcc/fortran/trans-openmp.o differs
> 
> This is at version 166790 so it should have the fix for PR 46474 in it.

I can replicate this.  I was about to say that I didn't see this last
night when I checked in the fma patch, but then I noticed that I had
bootstrapped with c/c++ only.

The problem doesn't seem to be directly fma related though.  Unlike the
libcpp problem, there is no floating-point in trans-openmp.c...

Looking into it.


r~
Richard Henderson - Nov. 16, 2010, 6:26 p.m.
On 11/16/2010 10:04 AM, Richard Henderson wrote:
> The problem doesn't seem to be directly fma related though.  Unlike the
> libcpp problem, there is no floating-point in trans-openmp.c...

Verified that it is another -g vs -g0 problem, as opposed to
a "real" code generation problem.


r~
Steve Ellcey - Nov. 19, 2010, 6:45 p.m.
On Tue, 2010-11-16 at 10:26 -0800, Richard Henderson wrote:
> On 11/16/2010 10:04 AM, Richard Henderson wrote:
> > The problem doesn't seem to be directly fma related though.  Unlike the
> > libcpp problem, there is no floating-point in trans-openmp.c...
> 
> Verified that it is another -g vs -g0 problem, as opposed to
> a "real" code generation problem.
> 
> 
> r~

So what do we do about it?  I am not familiar with the -g/-g0 problem
but I assume that it means the difference you are seeing is just in the
debug information.

Steve Ellcey
sje@cup.hp.com
Richard Henderson - Nov. 19, 2010, 7:02 p.m.
On 11/19/2010 10:45 AM, Steve Ellcey wrote:
> So what do we do about it?  I am not familiar with the -g/-g0 problem
> but I assume that it means the difference you are seeing is just in the
> debug information.

No, it's real code differences caused by the inclusion of debug info.

I'm still working on it.  My ia64 box is somewhat slow single-threaded;
I probably should be doing the test case reduction on a faster machine...


r~
Richard Henderson - Nov. 19, 2010, 10:16 p.m.
On 11/19/2010 11:02 AM, Richard Henderson wrote:
> No, it's real code differences caused by the inclusion of debug info.
> 
> I'm still working on it.  My ia64 box is somewhat slow single-threaded;
> I probably should be doing the test case reduction on a faster machine...

Filed as PR 46571.  Still working on it...


r~

Patch

Index: gcc/testsuite/gcc.target/ia64/mno-fused-madd-vect.c
===================================================================
--- gcc/testsuite/gcc.target/ia64/mno-fused-madd-vect.c	(revision 166605)
+++ gcc/testsuite/gcc.target/ia64/mno-fused-madd-vect.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do compile */
-/* { dg-options "-O2 -mno-fused-madd -ftree-vectorize" } */
+/* { dg-options "-O2 -ffp-contract=off -ftree-vectorize" } */
 /* { dg-final { scan-assembler "fpmpy" } } */
 
 /* fpma and fpms will show in either way because there are no
Index: gcc/testsuite/gcc.target/ia64/mno-fused-madd.c
===================================================================
--- gcc/testsuite/gcc.target/ia64/mno-fused-madd.c	(revision 166605)
+++ gcc/testsuite/gcc.target/ia64/mno-fused-madd.c	(working copy)
@@ -1,5 +1,5 @@ 
 /* { dg-do compile */
-/* { dg-options "-O2 -mno-fused-madd" } */
+/* { dg-options "-O2 -ffp-contract=off" } */
 /* { dg-final { scan-assembler-not "fma" } } */
 /* { dg-final { scan-assembler-not "fms" } } */
 /* { dg-final { scan-assembler-not "fnma" } } */
Index: gcc/config.gcc
===================================================================
--- gcc/config.gcc	(revision 166605)
+++ gcc/config.gcc	(working copy)
@@ -333,7 +333,7 @@ 
 ia64-*-*)
 	extra_headers=ia64intrin.h
 	need_64bit_hwint=yes
-	extra_options="${extra_options} g.opt"
+	extra_options="${extra_options} g.opt fused-madd.opt"
 	;;
 hppa*-*-*)
 	cpu_type=pa
Index: gcc/config/fused-madd.opt
===================================================================
--- gcc/config/fused-madd.opt	(revision 0)
+++ gcc/config/fused-madd.opt	(revision 0)
@@ -0,0 +1,25 @@ 
+; -mfused-madd option (some targets only).
+;
+; Copyright (C) 2010
+; Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; <http://www.gnu.org/licenses/>.
+
+mfused-madd
+Target Undocumented Alias(ffp-contract=, fast, off) Warn(%<-mfused-madd%> is deprecated; use %<-ffp-contract=%> instead)
+
+; This comment is to ensure we retain the blank line above.
Index: gcc/config/ia64/vms.h
===================================================================
--- gcc/config/ia64/vms.h	(revision 166605)
+++ gcc/config/ia64/vms.h	(working copy)
@@ -45,7 +45,7 @@ 
 
 /* Need .debug_line info generated from gcc and gas.  */
 #undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_GNU_AS | MASK_FUSED_MADD)
+#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_GNU_AS)
 
 #define VMS_DEBUG_MAIN_POINTER "TRANSFER$BREAK$GO"
 
Index: gcc/config/ia64/ia64.opt
===================================================================
--- gcc/config/ia64/ia64.opt	(revision 166605)
+++ gcc/config/ia64/ia64.opt	(working copy)
@@ -178,8 +178,4 @@ 
 Target Report Var(mflag_sel_sched_dont_check_control_spec) Init(0)
 Don't generate checks for control speculation in selective scheduling
 
-mfused-madd
-Target Report Mask(FUSED_MADD)
-Enable fused multiply/add and multiply/subtract instructions
-
 ; This comment is to ensure we retain the blank line above.
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	(revision 166605)
+++ gcc/config/ia64/ia64.c	(working copy)
@@ -5273,13 +5273,18 @@ 
       *total = COSTS_N_INSNS (3);
       return true;
 
+    case FMA:
+      *total = COSTS_N_INSNS (4);
+      return true;
+
     case MULT:
       /* For multiplies wider than HImode, we have to go to the FPU,
          which normally involves copies.  Plus there's the latency
          of the multiply itself, and the latency of the instructions to
          transfer integer regs to FP regs.  */
-      /* ??? Check for FP mode.  */
-      if (GET_MODE_SIZE (GET_MODE (x)) > 2)
+      if (FLOAT_MODE_P (GET_MODE (x)))
+	*total = COSTS_N_INSNS (4);
+      else if (GET_MODE_SIZE (GET_MODE (x)) > 2)
         *total = COSTS_N_INSNS (10);
       else
 	*total = COSTS_N_INSNS (2);
@@ -5287,6 +5292,13 @@ 
 
     case PLUS:
     case MINUS:
+      if (FLOAT_MODE_P (GET_MODE (x)))
+	{
+	  *total = COSTS_N_INSNS (4);
+	  return true;
+	}
+      /* FALLTHRU */
+
     case ASHIFT:
     case ASHIFTRT:
     case LSHIFTRT:
Index: gcc/config/ia64/ia64.h
===================================================================
--- gcc/config/ia64/ia64.h	(revision 166605)
+++ gcc/config/ia64/ia64.h	(working copy)
@@ -96,7 +96,7 @@ 
 /* Default target_flags if no switches are specified  */
 
 #ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_FUSED_MADD)
+#define TARGET_DEFAULT (MASK_DWARF2_ASM)
 #endif
 
 #ifndef TARGET_CPU_DEFAULT
Index: gcc/config/ia64/vect.md
===================================================================
--- gcc/config/ia64/vect.md	(revision 166605)
+++ gcc/config/ia64/vect.md	(working copy)
@@ -903,106 +903,29 @@ 
   "fpnegabs %0 = %1"
   [(set_attr "itanium_class" "fmisc")])
 
-;; In order to convince combine to merge plus and mult to a useful fpma,
-;; we need a couple of extra patterns.
 (define_expand "addv2sf3"
-  [(parallel
-    [(set (match_operand:V2SF 0 "fr_register_operand" "")
-	  (plus:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
-		     (match_operand:V2SF 2 "fr_register_operand" "")))
-     (use (match_dup 3))])]
+  [(set (match_operand:V2SF 0 "fr_register_operand" "")
+	(fma:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
+		  (match_dup 3)
+		  (match_operand:V2SF 2 "fr_register_operand" "")))]
   ""
 {
   rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
   operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
-  if (!TARGET_FUSED_MADD)
-    {
-      emit_insn (gen_fpma (operands[0], operands[1], operands[3], operands[2]));
-      DONE;
-    }
 })
 
-;; The split condition here could be combine_completed, if we had such.
-(define_insn_and_split "*addv2sf3_1"
-  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(plus:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		   (match_operand:V2SF 2 "fr_register_operand" "f")))
-   (use (match_operand:V2SF 3 "fr_register_operand" "f"))]
-  ""
-  "#"
-  "reload_completed"
-  [(set (match_dup 0)
-	(plus:V2SF
-	  (mult:V2SF (match_dup 1) (match_dup 3))
-	  (match_dup 2)))]
-  "")
-
-(define_insn_and_split "*addv2sf3_2"
-  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(plus:V2SF
-	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		     (match_operand:V2SF 2 "fr_register_operand" "f"))
-	  (match_operand:V2SF 3 "fr_register_operand" "f")))
-    (use (match_operand:V2SF 4 "" "X"))]
-  ""
-  "#"
-  ""
-  [(set (match_dup 0)
-	(plus:V2SF
-	  (mult:V2SF (match_dup 1) (match_dup 2))
-	  (match_dup 3)))]
-  "")
-
-;; In order to convince combine to merge minus and mult to a useful fpms,
-;; we need a couple of extra patterns.
 (define_expand "subv2sf3"
-  [(parallel
-    [(set (match_operand:V2SF 0 "fr_register_operand" "")
-	  (minus:V2SF (match_operand:V2SF 1 "fr_register_operand" "")
-		      (match_operand:V2SF 2 "fr_register_operand" "")))
-     (use (match_dup 3))])]
+  [(set (match_operand:V2SF 0 "fr_register_operand" "")
+	(fma:V2SF
+	  (match_operand:V2SF 1 "fr_register_operand" "")
+	  (match_dup 3)
+	  (neg:V2SF (match_operand:V2SF 2 "fr_register_operand" ""))))]
   ""
 {
   rtvec v = gen_rtvec (2, CONST1_RTX (SFmode), CONST1_RTX (SFmode));
   operands[3] = force_reg (V2SFmode, gen_rtx_CONST_VECTOR (V2SFmode, v));
-  if (!TARGET_FUSED_MADD)
-    {
-      emit_insn (gen_fpms (operands[0], operands[1], operands[3], operands[2]));
-      DONE;
-    }
 })
 
-;; The split condition here could be combine_completed, if we had such.
-(define_insn_and_split "*subv2sf3_1"
-  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(minus:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		    (match_operand:V2SF 2 "fr_register_operand" "f")))
-   (use (match_operand:V2SF 3 "fr_register_operand" "f"))]
-  ""
-  "#"
-  "reload_completed"
-  [(set (match_dup 0)
-	(minus:V2SF
-	  (mult:V2SF (match_dup 1) (match_dup 3))
-	  (match_dup 2)))]
-  "")
-
-(define_insn_and_split "*subv2sf3_2"
-  [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(minus:V2SF
-	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		     (match_operand:V2SF 2 "fr_register_operand" "f"))
-	  (match_operand:V2SF 3 "fr_register_operand" "f")))
-    (use (match_operand:V2SF 4 "" "X"))]
-  ""
-  "#"
-  ""
-  [(set (match_dup 0)
-	(minus:V2SF
-	  (mult:V2SF (match_dup 1) (match_dup 2))
-	  (match_dup 3)))]
-  "")
-
 (define_insn "mulv2sf3"
   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
 	(mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
@@ -1011,22 +934,22 @@ 
   "fpmpy %0 = %1, %2"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "fpma"
+(define_insn "fmav2sf4"
   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(plus:V2SF
-	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		     (match_operand:V2SF 2 "fr_register_operand" "f"))
+	(fma:V2SF
+	  (match_operand:V2SF 1 "fr_register_operand" "f")
+	  (match_operand:V2SF 2 "fr_register_operand" "f")
 	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
   ""
   "fpma %0 = %1, %2, %3"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "fpms"
+(define_insn "fmsv2sf4"
   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(minus:V2SF
-	  (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		     (match_operand:V2SF 2 "fr_register_operand" "f"))
-	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
+	(fma:V2SF
+	  (match_operand:V2SF 1 "fr_register_operand" "f")
+	  (match_operand:V2SF 2 "fr_register_operand" "f")
+	  (neg:V2SF (match_operand:V2SF 3 "fr_register_operand" "f"))))]
   ""
   "fpms %0 = %1, %2, %3"
   [(set_attr "itanium_class" "fmac")])
@@ -1040,12 +963,11 @@ 
   "fpnmpy %0 = %1, %2"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*fpnma"
+(define_insn "fnmav2sf4"
   [(set (match_operand:V2SF 0 "fr_register_operand" "=f")
-	(plus:V2SF
-	  (neg:V2SF
-	    (mult:V2SF (match_operand:V2SF 1 "fr_register_operand" "f")
-		       (match_operand:V2SF 2 "fr_register_operand" "f")))
+	(fma:V2SF
+	  (neg:V2SF (match_operand:V2SF 1 "fr_register_operand" "f"))
+	  (match_operand:V2SF 2 "fr_register_operand" "f")
 	  (match_operand:V2SF 3 "fr_register_operand" "f")))]
   ""
   "fpnma %0 = %1, %2, %3"
Index: gcc/config/ia64/ia64.md
===================================================================
--- gcc/config/ia64/ia64.md	(revision 166605)
+++ gcc/config/ia64/ia64.md	(working copy)
@@ -206,7 +206,17 @@ 
 (automata_option "w")
 
 (include "itanium2.md")
+
+;; Mode iterators
 
+; Used for truncations from XFmode.
+(define_mode_iterator MODE_SDF [SF DF])
+
+(define_mode_attr suffix [
+  (SF ".s")
+  (DF ".d")
+  (XF "")
+  ])
 
 ;; ::::::::::::::::::::
 ;; ::
@@ -2757,24 +2767,6 @@ 
   "fmax %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmisc")])
 
-(define_insn "*maddsf4"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(plus:SF (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
-			  (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))
-		 (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubsf4"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(minus:SF (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
-			   (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))
-		  (match_operand:SF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fms.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
 (define_insn "*nmulsf3"
   [(set (match_operand:SF 0 "fr_register_operand" "=f")
 	(neg:SF (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
@@ -2783,16 +2775,6 @@ 
   "fnmpy.s %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*nmaddsf4"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(minus:SF (match_operand:SF 3 "fr_reg_or_fp01_operand" "fG") 
-		  (mult:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
-			   (match_operand:SF 2 "fr_reg_or_fp01_operand" "fG"))))]
-  "TARGET_FUSED_MADD"
-  "fnma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-;; Official C99 versions of the fmaf family of operations.
 (define_insn "fmasf4"
   [(set (match_operand:SF 0 "fr_register_operand" "=f")
 	(fma:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
@@ -2802,7 +2784,7 @@ 
   "fma.s %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*fmssf4"
+(define_insn "fmssf4"
   [(set (match_operand:SF 0 "fr_register_operand" "=f")
 	(fma:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG")
 		(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
@@ -2812,8 +2794,7 @@ 
   "fms.s %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-;; This insn is officially "-(a * b) + c" which is "(-a * b) + c".
-(define_insn "*nfmasf4"
+(define_insn "fnmasf4"
   [(set (match_operand:SF 0 "fr_register_operand" "=f")
 	(fma:SF (neg:SF (match_operand:SF 1 "fr_reg_or_fp01_operand" "fG"))
 		(match_operand:SF 2 "fr_reg_or_fp01_operand" "fG")
@@ -2934,44 +2915,6 @@ 
   "fmax %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmisc")])
 
-(define_insn "*madddf4"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(plus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
-		 (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fma.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*madddf4_trunc"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	  (plus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
-		   (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubdf4"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(minus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
-		  (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fms.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubdf4_trunc"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	  (minus:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			     (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))
-		    (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fms.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
 (define_insn "*nmuldf3"
   [(set (match_operand:DF 0 "fr_register_operand" "=f")
 	(neg:DF (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
@@ -2989,26 +2932,6 @@ 
   "fnmpy.s %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*nmadddf4"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
-		  (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG"))))]
-  "TARGET_FUSED_MADD"
-  "fnma.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*nmadddf4_truncsf"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	(minus:DF (match_operand:DF 3 "fr_reg_or_fp01_operand" "fG")
-		  (mult:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
-			   (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")))))]
-  "TARGET_FUSED_MADD"
-  "fnma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-;; Official C99 versions of the fma family of operations.
 (define_insn "fmadf4"
   [(set (match_operand:DF 0 "fr_register_operand" "=f")
 	(fma:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
@@ -3018,7 +2941,17 @@ 
   "fma.d %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*fmsdf4"
+(define_insn "*fmadf_trunc_sf"
+  [(set (match_operand:SF 0 "fr_register_operand" "=f")
+	(float_truncate:SF
+	  (fma:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
+		  (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
+		  (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
+  ""
+  "fma.s %0 = %F1, %F2, %F3"
+  [(set_attr "itanium_class" "fmac")])
+
+(define_insn "fmsdf4"
   [(set (match_operand:DF 0 "fr_register_operand" "=f")
 	(fma:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
 		(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
@@ -3028,8 +2961,19 @@ 
   "fms.d %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-;; See comment for nfmasf4.
-(define_insn "*nfmadf4"
+(define_insn "*fmsdf_trunc_sf"
+  [(set (match_operand:SF 0 "fr_register_operand" "=f")
+	(float_truncate:SF
+	  (fma:DF
+	    (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG")
+	    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
+	    (neg:DF
+	      (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ")))))]
+  ""
+  "fms.s %0 = %F1, %F2, %F3"
+  [(set_attr "itanium_class" "fmac")])
+
+(define_insn "fnmadf4"
   [(set (match_operand:DF 0 "fr_register_operand" "=f")
 	(fma:DF (neg:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG"))
 		(match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
@@ -3037,6 +2981,17 @@ 
   ""
   "fnma.d %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
+
+(define_insn "*fnmadf_trunc_sf"
+  [(set (match_operand:SF 0 "fr_register_operand" "=f")
+	(float_truncate:SF
+	  (fma:DF
+	    (neg:DF (match_operand:DF 1 "fr_reg_or_fp01_operand" "fG"))
+	    (match_operand:DF 2 "fr_reg_or_fp01_operand" "fG")
+	    (match_operand:DF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
+  ""
+  "fnma.s %0 = %F1, %F2, %F3"
+  [(set_attr "itanium_class" "fmac")])
 
 ;; ::::::::::::::::::::
 ;; ::
@@ -3177,64 +3132,6 @@ 
   "fmax %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmisc")])
 
-(define_insn "*maddxf4"
-  [(set (match_operand:XF 0 "fr_register_operand" "=f")
-	(plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			  (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		 (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fma %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*maddxf4_truncsf"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		   (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*maddxf4_truncdf"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(float_truncate:DF
-	  (plus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			    (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		   (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fma.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubxf4"
-  [(set (match_operand:XF 0 "fr_register_operand" "=f")
-	(minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		  (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ")))]
-  "TARGET_FUSED_MADD"
-  "fms %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubxf4_truncsf"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	  (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		    (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fms.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*msubxf4_truncdf"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(float_truncate:DF
-	  (minus:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG"))
-		    (match_operand:XF 3 "xfreg_or_signed_fp01_operand" "fZ"))))]
-  "TARGET_FUSED_MADD"
-  "fms.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
 (define_insn "*nmulxf3"
   [(set (match_operand:XF 0 "fr_register_operand" "=f")
 	(neg:XF (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
@@ -3263,39 +3160,6 @@ 
   "fnmpy.d %0 = %F1, %F2"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*nmaddxf4"
-  [(set (match_operand:XF 0 "fr_register_operand" "=f")
-	(minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG")
-		  (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			   (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
-   )))]
-  "TARGET_FUSED_MADD"
-  "fnma %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*nmaddxf4_truncsf"
-  [(set (match_operand:SF 0 "fr_register_operand" "=f")
-	(float_truncate:SF
-	  (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
-		    (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
-   ))))]
-  "TARGET_FUSED_MADD"
-  "fnma.s %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-(define_insn "*nmaddxf4_truncdf"
-  [(set (match_operand:DF 0 "fr_register_operand" "=f")
-	(float_truncate:DF
-	  (minus:XF (match_operand:XF 3 "xfreg_or_fp01_operand" "fG") 
-		    (mult:XF (match_operand:XF 1 "xfreg_or_fp01_operand" "fG")
-			     (match_operand:XF 2 "xfreg_or_fp01_operand" "fG")
-   ))))]
-  "TARGET_FUSED_MADD"
-  "fnma.d %0 = %F1, %F2, %F3"
-  [(set_attr "itanium_class" "fmac")])
-
-;; Official C99 versions of the fmal family of operations.
 (define_insn "fmaxf4"
   [(set (match_operand:XF 0 "fr_register_operand" "=f")
 	(fma:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
@@ -3305,7 +3169,18 @@ 
   "fma %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-(define_insn "*fmsxf4"
+(define_insn "*fmaxf_trunc_<mode>"
+  [(set (match_operand:MODE_SDF 0 "fr_register_operand" "=f")
+	(float_truncate:MODE_SDF
+	  (fma:XF
+	    (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
+	    (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")
+	    (match_operand:XF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
+  ""
+  "fma<suffix> %0 = %F1, %F2, %F3"
+  [(set_attr "itanium_class" "fmac")])
+
+(define_insn "fmsxf4"
   [(set (match_operand:XF 0 "fr_register_operand" "=f")
 	(fma:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
 		(match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")
@@ -3315,8 +3190,19 @@ 
   "fms %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
 
-;; See comment for nfmasf4.
-(define_insn "*nfmaxf4"
+(define_insn "*fmsxf_trunc_<mode>"
+  [(set (match_operand:MODE_SDF 0 "fr_register_operand" "=f")
+	(float_truncate:MODE_SDF
+	  (fma:XF
+	    (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG")
+	    (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")
+	    (neg:XF
+	      (match_operand:XF 3 "fr_reg_or_signed_fp01_operand" "fZ")))))]
+  ""
+  "fms<suffix> %0 = %F1, %F2, %F3"
+  [(set_attr "itanium_class" "fmac")])
+
+(define_insn "fnmaxf4"
   [(set (match_operand:XF 0 "fr_register_operand" "=f")
 	(fma:XF (neg:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG"))
 		(match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")
@@ -3324,6 +3210,17 @@ 
   ""
   "fnma %0 = %F1, %F2, %F3"
   [(set_attr "itanium_class" "fmac")])
+
+(define_insn "*fnmaxf_trunc_<mode>"
+  [(set (match_operand:MODE_SDF 0 "fr_register_operand" "=f")
+	(float_truncate:MODE_SDF
+	  (fma:XF
+	    (neg:XF (match_operand:XF 1 "fr_reg_or_fp01_operand" "fG"))
+	    (match_operand:XF 2 "fr_reg_or_fp01_operand" "fG")
+	    (match_operand:XF 3 "fr_reg_or_signed_fp01_operand" "fZ"))))]
+  ""
+  "fnma<suffix> %0 = %F1, %F2, %F3"
+  [(set_attr "itanium_class" "fmac")])
 
 ;; ::::::::::::::::::::
 ;; ::
Index: gcc/config/ia64/vms64.h
===================================================================
--- gcc/config/ia64/vms64.h	(revision 166605)
+++ gcc/config/ia64/vms64.h	(working copy)
@@ -36,6 +36,6 @@ 
 #define POINTER_SIZE 64
 
 #undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_GNU_AS | MASK_FUSED_MADD | MASK_MALLOC64)
+#define TARGET_DEFAULT (MASK_DWARF2_ASM | MASK_GNU_AS | MASK_MALLOC64)
 
 #include "config/vms/vms-crtl-64.h"
Index: gcc/config/ia64/hpux.h
===================================================================
--- gcc/config/ia64/hpux.h	(revision 166605)
+++ gcc/config/ia64/hpux.h	(working copy)
@@ -106,7 +106,7 @@ 
 
 #undef TARGET_DEFAULT
 #define TARGET_DEFAULT \
-  (MASK_DWARF2_ASM | MASK_BIG_ENDIAN | MASK_ILP32 | MASK_FUSED_MADD)
+  (MASK_DWARF2_ASM | MASK_BIG_ENDIAN | MASK_ILP32)
 
 /* ??? Might not be needed anymore.  */
 #define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) ((MODE) == TFmode)