This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] potential fix for PR middle-end/7151


I know the sparc bits below are OK, but I want some eyes on
the reload bits please.  A full sparc-linux regression run passed with
these changes, and I'm running a sparc64-linux one now.

What happens is that SUBREG's are not handled for the
SECONDARY_MEMORY_NEEDED cases in gen_reload() so we abort when trying
to generate a reload for:

	(set (reg:SI INTEGER_REGNO) (subreg:SI (reg:DI FLOAT_REGNO) 0))

which has to be done via secondary memory on Sparc.

I argue the reload change to be correct, because when this case is
triggered it currently just goes "emit (set OUT IN)" which is
guarenteed to abort.

I do not argue that the reload fix is complete.  Here is why.

I tried to verify that other parts of reload handle SUBREGs properly
as well.  In reload.c:push_reload() there is all of this logic about
emitting two reloads for a subreg.  This occurs when
reload_inner_reg_of_subreg() returns true.  In this case, the toplevel
SUBREG reload won't get checked by the SECONDARY_MEMORY_NEEDED check
because we will preserve the SUBREG and that check only accepts REG.

So, shouldn't these two SECONDARY_MEMORY_NEEDED checks in
push_reload() have similar logic to what I'm adding here to
reload1.c:gen_reload() ?

I believe it is needed.

Comments?

2002-09-30  David S. Miller  <davem@redhat.com>

	PR middle-end/7151
	* reload1.c (gen_reload:SECONDARY_MEMORY_NEEDED): Handle SUBREG.
	* config/sparc/sparc.md (movdi_insn_sp32_v9): Accept 'e' regs.
	(movdi reg/reg split): Match only on sparc32, and v9 when int regs.
	
	
--- reload1.c.~1~	Tue May 21 16:42:54 2002
+++ reload1.c	Mon Sep 30 18:24:28 2002
@@ -7354,6 +7354,9 @@ gen_reload (out, in, opnum, type)
 {
   rtx last = get_last_insn ();
   rtx tem;
+#ifdef SECONDARY_MEMORY_NEEDED
+  int in_regnum, out_regnum;
+#endif
 
   /* If IN is a paradoxical SUBREG, remove it and try to put the
      opposite SUBREG on OUT.  Likewise for a paradoxical SUBREG on OUT.  */
@@ -7516,20 +7519,22 @@ gen_reload (out, in, opnum, type)
 
 #ifdef SECONDARY_MEMORY_NEEDED
   /* If we need a memory location to do the move, do it that way.  */
-  else if (GET_CODE (in) == REG && REGNO (in) < FIRST_PSEUDO_REGISTER
-	   && GET_CODE (out) == REG && REGNO (out) < FIRST_PSEUDO_REGISTER
-	   && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (REGNO (in)),
-				       REGNO_REG_CLASS (REGNO (out)),
+  else if ((in_regnum = true_regnum (in)) >= 0
+	   && in_regnum < FIRST_PSEUDO_REGISTER
+	   && (out_regnum = true_regnum (out)) >= 0
+	   && out_regnum < FIRST_PSEUDO_REGISTER
+	   && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (in_regnum),
+				       REGNO_REG_CLASS (out_regnum),
 				       GET_MODE (out)))
     {
       /* Get the memory to use and rewrite both registers to its mode.  */
       rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type);
 
       if (GET_MODE (loc) != GET_MODE (out))
-	out = gen_rtx_REG (GET_MODE (loc), REGNO (out));
+	out = gen_rtx_REG (GET_MODE (loc), out_regnum);
 
       if (GET_MODE (loc) != GET_MODE (in))
-	in = gen_rtx_REG (GET_MODE (loc), REGNO (in));
+	in = gen_rtx_REG (GET_MODE (loc), in_regnum);
 
       gen_reload (loc, in, opnum, type);
       gen_reload (out, loc, opnum, type);
--- config/sparc/sparc.md.~1~	Thu Sep 19 20:55:38 2002
+++ config/sparc/sparc.md	Mon Sep 30 18:44:18 2002
@@ -2517,7 +2517,7 @@
   ;
 }")
 
-;; Be careful, fmovd does not exist when !arch64.
+;; Be careful, fmovd does not exist when !v9.
 ;; We match MEM moves directly when we have correct even
 ;; numbered registers, but fall into splits otherwise.
 ;; The constraint ordering here is really important to
@@ -2531,9 +2531,9 @@
 
 (define_insn "*movdi_insn_sp32_v9"
   [(set (match_operand:DI 0 "nonimmediate_operand"
-					"=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f")
+					"=T,o,T,U,o,r,r,r,?T,?f,?f,?o,?f,?e,?e,?W")
         (match_operand:DI 1 "input_operand"
-					" J,J,U,T,r,o,i,r, f, T, o, f, f"))]
+					" J,J,U,T,r,o,i,r, f, T, o, f, f, e, W, e"))]
   "! TARGET_ARCH64 && TARGET_V9
    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
   "@
@@ -2549,9 +2549,13 @@
    ldd\\t%1, %0
    #
    #
-   #"
-  [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*")
-   (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2")])
+   #
+   fmovd\\t%1, %0
+   ldd\\t%1, %0
+   std\\t%1, %0"
+  [(set_attr "type" "store,store,store,load,*,*,*,*,fpstore,fpload,*,*,*,fpmove,fpload,fpstore")
+   (set_attr "length" "*,2,*,*,2,2,2,2,*,*,2,2,2,*,*,*")
+   (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
 
 (define_insn "*movdi_insn_sp32"
   [(set (match_operand:DI 0 "nonimmediate_operand"
@@ -2861,7 +2865,14 @@
 (define_split
   [(set (match_operand:DI 0 "register_operand" "")
         (match_operand:DI 1 "const_double_operand" ""))]
-  "! TARGET_ARCH64 && reload_completed"
+  "reload_completed
+   && (! TARGET_V9
+       || (! TARGET_ARCH64
+           && ((GET_CODE (operands[0]) == REG
+                && REGNO (operands[0]) < 32)
+               || (GET_CODE (operands[0]) == SUBREG
+                   && GET_CODE (SUBREG_REG (operands[0])) == REG
+                   && REGNO (SUBREG_REG (operands[0])) < 32))))"
   [(clobber (const_int 0))]
   "
 {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]