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]

[PATCH] Fix ACATS failures on SPARC


Hi,

This patch fixes 2 out of 3 ACATS failures on mainline for SPARC (and at -O2 
on 3.4 branch), namely:

FAIL:	c35503p
FAIL:	cc1221b


The culprit is again the put_var_into_stack machinery in function.c.  The 
sequence of events is as follows:

- we start with

(insn 39 38 40 (set (reg:SI 115)
        (ashiftrt:SI (reg:SI 116)
            (const_int 24 [0x18]))) -1 (nil)
    (expr_list:REG_EQUAL (sign_extend:SI (subreg:QI (reg/v:SI 110 [ R2b ]) 
3))
        (nil)))

- we put (reg/v:SI 110 [ R2b ]) into the stack, at

    (mem/f:SI (plus:SI (reg/f:SI 103 virtual-stack-vars)
                    (const_int -4)) [0 S4 A16]))

- we get

(insn 39 38 40 (set (reg:SI 115)
        (ashiftrt:SI (reg:SI 116)
            (const_int 24 [0x18]))) -1 (nil)
    (expr_list:REG_EQUAL (sign_extend:SI (mem/f:QI (plus:SI (reg/f:SI 103 
virtual-stack-vars)
                    (const_int 2 [0x2])) [0 S1 A16]))
        (nil)))

and of course we would have expected (const_int -1) instead of (const_int 2).


Interestingly, the same substitution happens two insns before

(insn 37 36 110 (set (reg/v:QI 114 [ c35503p__sint___U ])
        (mem/f:QI (plus:SI (reg/f:SI 103 virtual-stack-vars)
                (const_int -1 [0xffffffffffffffff])) [0 S1 A8])) 46 
{*movqi_insn} (nil)
    (nil))

and gives the correct result.  The difference is that the latter is done in 
the pattern of an insn, while the former is done in a REG_EQUAL note.


The problem lies in fixup_var_refs_insn: it is invoked with 'var' and 
'promoted_mode' arguments, the latter being tied to the former.  Now at the 
end of the function we have:

  /* Also fix up any invalid exprs in the REG_NOTES of this insn.
     But don't touch other insns referred to by reg-notes;
     we will get them elsewhere.  */
  while (note)
    {
      if (GET_CODE (note) != INSN_LIST)
	XEXP (note, 0)
	  = walk_fixup_memory_subreg (XEXP (note, 0), insn,
				      promoted_mode, 1);
      note = XEXP (note, 1);
    }

That is, we pass 'promote_mode' to any invalid exprs in the notes, which may 
have nothing to do with 'var'.

In our present case, insn 39 is first fixed with a 'var' for which 
'promoted_mode' is QImode before being fixed with the right 'var', for which 
'promoted_mode' is SImode.  Hence the discrepancy of 3.

The proposed fix is to pass 'var' along with 'promoted_mode' to 
walk_fixup_memory_subreg.

Bootstrapped/regtested on sparc64-sun-solaris2.9 and sparc-sun-solaris2.8.

OK for mainline?


2004-05-05  Eric Botcazou  <ebotcazou@act-europe.fr>

	* function.c (walk_fixup_memory_subreg): New parameter 'var'.
	Call fixup_memory_subreg only if the MEM is equal to 'var'.
	Adjust recursive calls to self.
	(fixup_var_refs_insn): Pass 'var' to walk_fixup_memory_subreg.


-- 
Eric Botcazou
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.483.4.11
diff -u -p -r1.483.4.11 function.c
--- function.c	22 Apr 2004 21:34:54 -0000	1.483.4.11
+++ function.c	5 May 2004 14:47:07 -0000
@@ -248,7 +248,7 @@ static void fixup_var_refs_insn (rtx, rt
 static void fixup_var_refs_1 (rtx, enum machine_mode, rtx *, rtx,
 			      struct fixup_replacement **, rtx);
 static rtx fixup_memory_subreg (rtx, rtx, enum machine_mode, int);
-static rtx walk_fixup_memory_subreg (rtx, rtx, enum machine_mode, int);
+static rtx walk_fixup_memory_subreg (rtx, rtx, rtx, enum machine_mode, int);
 static rtx fixup_stack_1 (rtx, rtx);
 static void optimize_bit_field (rtx, rtx, rtx *);
 static void instantiate_decls (tree, int);
@@ -1819,7 +1819,7 @@ fixup_var_refs_insn (rtx insn, rtx var, 
     {
       if (GET_CODE (note) != INSN_LIST)
 	XEXP (note, 0)
-	  = walk_fixup_memory_subreg (XEXP (note, 0), insn,
+	  = walk_fixup_memory_subreg (XEXP (note, 0), insn, var,
 				      promoted_mode, 1);
       note = XEXP (note, 1);
     }
@@ -2506,17 +2506,17 @@ fixup_memory_subreg (rtx x, rtx insn, en
   return result;
 }
 
-/* Do fixup_memory_subreg on all (SUBREG (MEM ...) ...) contained in X.
+/* Do fixup_memory_subreg on all (SUBREG (VAR) ...) contained in X.
+   VAR is a MEM that used to be a pseudo register with mode PROMOTED_MODE.
    Replace subexpressions of X in place.
-   If X itself is a (SUBREG (MEM ...) ...), return the replacement expression.
+   If X itself is a (SUBREG (VAR) ...), return the replacement expression.
    Otherwise return X, with its contents possibly altered.
 
-   INSN, PROMOTED_MODE and UNCRITICAL are as for
-   fixup_memory_subreg.  */
+   INSN and UNCRITICAL are as for fixup_memory_subreg.  */
 
 static rtx
-walk_fixup_memory_subreg (rtx x, rtx insn, enum machine_mode promoted_mode,
-			  int uncritical)
+walk_fixup_memory_subreg (rtx x, rtx insn, rtx var,
+			  enum machine_mode promoted_mode, int uncritical)
 {
   enum rtx_code code;
   const char *fmt;
@@ -2527,7 +2527,7 @@ walk_fixup_memory_subreg (rtx x, rtx ins
 
   code = GET_CODE (x);
 
-  if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == MEM)
+  if (code == SUBREG && SUBREG_REG (x) == var)
     return fixup_memory_subreg (x, insn, promoted_mode, uncritical);
 
   /* Nothing special about this RTX; fix its operands.  */
@@ -2536,14 +2536,14 @@ walk_fixup_memory_subreg (rtx x, rtx ins
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     {
       if (fmt[i] == 'e')
-	XEXP (x, i) = walk_fixup_memory_subreg (XEXP (x, i), insn,
+	XEXP (x, i) = walk_fixup_memory_subreg (XEXP (x, i), insn, var,
 						promoted_mode, uncritical);
       else if (fmt[i] == 'E')
 	{
 	  int j;
 	  for (j = 0; j < XVECLEN (x, i); j++)
 	    XVECEXP (x, i, j)
-	      = walk_fixup_memory_subreg (XVECEXP (x, i, j), insn,
+	      = walk_fixup_memory_subreg (XVECEXP (x, i, j), insn, var,
 					  promoted_mode, uncritical);
 	}
     }

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