Fix for mainline build on mips64el-linux

Joseph S. Myers joseph@codesourcery.com
Tue May 23 17:59:00 GMT 2006


On Fri, 5 May 2006, Roger Sayle wrote:

> 
> On Fri, 5 May 2006, Richard Sandiford wrote:
> > I might be worrying unduly, but I'm a little concerned about this patch.
> > I think simplify_subreg currently only returns lvalues when given an lvalue.
> > This patch appears to be the first time that we'll return an rvalue for an
> > lvalue input.
> 
> Do were ever interpret paradoxical SUBREGs are lvalues?  I thought that
> we use STRICT_LOW_PART as the destination of a SET in these cases.  But
> I'll admit that I wouldn't be surprised if we abused paradoxical SUBREGs
> somewhere, and then relied on conservation on lvalue-ness later.  Grrr.
> 
> Joseph, any chance we could go with the ultra-safe alternative of
> defining an undefined_operand_subword_p and using it in expr.c's
> emit_move_multi_word?  I suspect that this would help other code,
> and the new predicate might be useful in other areas.

How about the following patch?  It fixes build for mips64el-linux and 
passed testing with no regressions on x86_64-unknown-linux-gnu.

2006-05-23  Joseph Myers  <joseph@codesourcery.com>

	* expr.c (undefined_operand_subword_p): New.
	(emit_move_multi_word): Do not generate move from undefined bits
	of a paradoxical subreg.

Index: expr.c
===================================================================
--- expr.c	(revision 113993)
+++ expr.c	(working copy)
@@ -3096,6 +3096,38 @@
   return ret;
 }
 
+/* Return true if word I of OP (mode MODE) lies entirely in the
+   undefined bits of a paradoxical subreg.  */
+
+static bool
+undefined_operand_subword_p (rtx op, int i)
+{
+  enum machine_mode innermode, innermostmode;
+  int offset;
+  if (GET_CODE (op) != SUBREG)
+    return false;
+  innermode = GET_MODE (op);
+  innermostmode = GET_MODE (SUBREG_REG (op));
+  offset = i * UNITS_PER_WORD + SUBREG_BYTE (op);
+  /* The SUBREG_BYTE represents offset, as if the value were stored in
+     memory, except for a paradoxical subreg where we define
+     SUBREG_BYTE to be 0; undo this exception as in
+     simplify_subreg.  */
+  if (SUBREG_BYTE (op) == 0
+      && GET_MODE_SIZE (innermostmode) < GET_MODE_SIZE (innermode))
+    {
+      int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (innermode));
+      if (WORDS_BIG_ENDIAN)
+	offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
+      if (BYTES_BIG_ENDIAN)
+	offset += difference % UNITS_PER_WORD;
+    }
+  if (offset >= GET_MODE_SIZE (innermostmode)
+      || offset <= -GET_MODE_SIZE (word_mode))
+    return true;
+  return false;
+}
+
 /* A subroutine of emit_move_insn_1.  Generate a move from Y into X.
    MODE is any multi-word or full-word mode that lacks a move_insn
    pattern.  Note that you will get better code if you define such
@@ -3133,8 +3165,15 @@
        i++)
     {
       rtx xpart = operand_subword (x, i, 1, mode);
-      rtx ypart = operand_subword (y, i, 1, mode);
+      rtx ypart;
 
+      /* Do not generate code for a move if it would come entirely
+	 from the undefined bits of a paradoxical subreg.  */
+      if (undefined_operand_subword_p (y, i))
+	continue;
+
+      ypart = operand_subword (y, i, 1, mode);
+
       /* If we can't get a part of Y, put Y into memory if it is a
 	 constant.  Otherwise, force it into a register.  Then we must
 	 be able to get a part of Y.  */

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)



More information about the Gcc-patches mailing list