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] gen_lowpart and lvalues


Hi,

We're having problems with the following change to gen_lowpart in 3.4.x:

2003-03-06  Roger Sayle  <roger@eyesopen.com>

        * emit-rtl.c (gen_lowpart): When requesting the low-part of a
        MEM, try loading the MEM into a register and taking the low-part
        of that, to help CSE see the use of the MEM in its true mode.

http://gcc.gnu.org/ml/gcc-patches/2003-03/msg00521.html

This change implies that gen_lowpart cannot be used on lvalues anymore under 
certain circumstances.  That's really problematic for VIEW_CONVERT_EXPRs:

    case VIEW_CONVERT_EXPR:
      op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, mode, modifier);

      /* If the input and output modes are both the same, we are done.
	 Otherwise, if neither mode is BLKmode and both are integral and within
	 a word, we can use gen_lowpart.  If neither is true, make sure the
	 operand is in memory and convert the MEM to the new mode.  */
      if (TYPE_MODE (type) == GET_MODE (op0))
	;
      else if (TYPE_MODE (type) != BLKmode && GET_MODE (op0) != BLKmode
	       && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
	       && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
	       && GET_MODE_SIZE (TYPE_MODE (type)) <= UNITS_PER_WORD
	       && GET_MODE_SIZE (GET_MODE (op0)) <= UNITS_PER_WORD)
	op0 = gen_lowpart (TYPE_MODE (type), op0);


Moreover, the same assumption is visible in other places:

convert_move:

      /* Next, try converting via full word.  */
      else if (GET_MODE_BITSIZE (from_mode) < BITS_PER_WORD
	       && ((code = can_extend_p (to_mode, word_mode, unsignedp))
		   != CODE_FOR_nothing))
	{
	  if (REG_P (to))
	    {
	      if (reg_overlap_mentioned_p (to, from))
		from = force_reg (from_mode, from);
	      emit_insn (gen_rtx_CLOBBER (VOIDmode, to));
	    }
	  convert_move (gen_lowpart (word_mode, to), from, unsignedp);
	  emit_unop_insn (code, to,
			  gen_lowpart (word_mode, to), equiv_code);
	  return;
	}

[...]

      lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);

      lowpart = gen_lowpart (lowpart_mode, to);
      emit_move_insn (lowpart, lowfrom);


store_bit_field:

  if (GET_MODE (value) != VOIDmode
      && GET_MODE_CLASS (GET_MODE (value)) != MODE_INT
      && GET_MODE_CLASS (GET_MODE (value)) != MODE_PARTIAL_INT)
    {
      value = gen_reg_rtx (int_mode_for_mode (GET_MODE (value)));
      emit_move_insn (gen_lowpart (GET_MODE (orig_value), value), orig_value);
    }


Note the head comment of the function:

/* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a value,
   return an rtx (MEM, SUBREG, or CONST_INT) that refers to the
   least-significant part of X.

"refers" really seems to convey the lvalue-ness of the function.


So we propose to back out the change (present on 3.4.x and mainline).


2005-02-24  Eric Botcazou  <ebotcazou@adacore.com>

	Revert
	2003-03-06  Roger Sayle  <roger@eyesopen.com>

	* emit-rtl.c (gen_lowpart): When requesting the low-part of a
	MEM, try loading the MEM into a register and taking the low-part
	of that, to help CSE see the use of the MEM in its true mode.


-- 
Eric Botcazou
Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v
retrieving revision 1.365.4.9
diff -u -p -r1.365.4.9 emit-rtl.c
--- emit-rtl.c	14 Dec 2004 03:12:03 -0000	1.365.4.9
+++ emit-rtl.c	24 Feb 2005 07:52:13 -0000
@@ -1226,14 +1226,6 @@ gen_lowpart (enum machine_mode mode, rtx
       /* The only additional case we can do is MEM.  */
       int offset = 0;
 
-      /* The following exposes the use of "x" to CSE.  */
-      if (GET_MODE_SIZE (GET_MODE (x)) <= UNITS_PER_WORD
-	  && SCALAR_INT_MODE_P (GET_MODE (x))
-	  && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
-				    GET_MODE_BITSIZE (GET_MODE (x)))
-	  && ! no_new_pseudos)
-	return gen_lowpart (mode, force_reg (GET_MODE (x), x));
-
       if (WORDS_BIG_ENDIAN)
 	offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
 		  - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));

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