public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][mem-ref2] Fix expansion of MEM_REF of registers
@ 2010-06-11 14:09 Richard Guenther
  0 siblings, 0 replies; only message in thread
From: Richard Guenther @ 2010-06-11 14:09 UTC (permalink / raw)
  To: gcc-patches


While we do not (yet) create too many of those the current code
does not deal with all cases correctly.  The following patch
aims to fix that (and it was also tested together with a patch
that exposes way more MEM_REFs of this kind).

The expander is one part that I would like to get reviews on before
merging the branch - I will at some point post a separate merge
patch for these parts.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to the
branch.

Richard.

2010-06-11  Richard Guenther  <rguenther@suse.de>

	* expr.c (store_field): If expanding a MEM_REF of a non-addressable
	decl use bitfield operations.
	(expand_expr_real_1): More properly deal with the register base
	case.

	* gcc.dg/torture/20100610-1.c: New testcase.

Index: gcc/expr.c
===================================================================
*** gcc/expr.c	(revision 160604)
--- gcc/expr.c	(working copy)
*************** store_field (rtx target, HOST_WIDE_INT b
*** 5847,5853 ****
  	 operations.  */
        || (bitsize >= 0
  	  && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST
! 	  && compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)), bitsize) != 0))
      {
        rtx temp;
        gimple nop_def;
--- 5847,5861 ----
  	 operations.  */
        || (bitsize >= 0
  	  && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST
! 	  && compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)), bitsize) != 0)
!       /* If we are expanding a MEM_REF of a non-BLKmode non-addressable
!          decl we must use bitfield operations.  */
!       || (bitsize >= 0
! 	  && TREE_CODE (exp) == MEM_REF
! 	  && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
! 	  && DECL_P (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
! 	  && !TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (exp, 0),0 ))
! 	  && DECL_MODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) != BLKmode))
      {
        rtx temp;
        gimple nop_def;
*************** expand_expr_real_1 (tree exp, rtx target
*** 8806,8829 ****
  		gcc_assert (base);
  		offset = size_binop (PLUS_EXPR, offset, bitsize_int (off));
  	      }
  	    if (DECL_P (base)
  		&& !TREE_ADDRESSABLE (base)
! 		&& integer_zerop (offset)
! 		&& DECL_MODE (base) != BLKmode
! 		&& host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
! 		&& (GET_MODE_BITSIZE (DECL_MODE (base))
! 		    == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp)))))
! 	      return expand_expr (build1 (VIEW_CONVERT_EXPR,
! 					  TREE_TYPE (exp), base),
! 				  target, tmode, modifier);
! 	    if (DECL_P (base)
! 		&& !TREE_ADDRESSABLE (base)
! 		&& TYPE_MODE (TREE_TYPE (exp)) != BLKmode)
! 	      return expand_expr (build3 (BIT_FIELD_REF, TREE_TYPE (exp),
! 					  base,
! 					  bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)))),
! 					  offset),
! 				  target, tmode, modifier);
  	  }
  	address_mode = targetm.addr_space.address_mode (as);
  	op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, address_mode,
--- 8814,8843 ----
  		gcc_assert (base);
  		offset = size_binop (PLUS_EXPR, offset, bitsize_int (off));
  	      }
+ 	    /* If we are expanding a MEM_REF of a non-BLKmode non-addressable
+ 	       decl we must use bitfield operations.  */
  	    if (DECL_P (base)
  		&& !TREE_ADDRESSABLE (base)
! 		&& DECL_MODE (base) != BLKmode)
! 	      {
! 		tree bftype;
! 		if (integer_zerop (offset)
! 		    && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
! 		    && (GET_MODE_BITSIZE (DECL_MODE (base))
! 			== TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp)))))
! 		  return expand_expr (build1 (VIEW_CONVERT_EXPR,
! 					      TREE_TYPE (exp), base),
! 				      target, tmode, modifier);
! 		gcc_assert (!DECL_RTL_SET_P (base) || REG_P (DECL_RTL (base)));
! 		bftype = TREE_TYPE (base);
! 		if (TYPE_MODE (TREE_TYPE (exp)) != BLKmode)
! 		  bftype = TREE_TYPE (exp);
! 		return expand_expr (build3 (BIT_FIELD_REF, bftype,
! 					    base,
! 					    TYPE_SIZE (TREE_TYPE (exp)),
! 					    offset),
! 				    target, tmode, modifier);
! 	      }
  	  }
  	address_mode = targetm.addr_space.address_mode (as);
  	op0 = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, address_mode,
Index: gcc/testsuite/gcc.dg/torture/20100610-1.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/20100610-1.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/20100610-1.c	(revision 0)
***************
*** 0 ****
--- 1,36 ----
+ /* { dg-do run } */
+ /* { dg-require-effective-target lp64 } */
+ 
+ struct X { long x };
+ static inline long __attribute__((always_inline))
+ test (int o1, int o2, int sz)
+ {
+   struct X i, j;
+   i.x = 0xdeadbeefdeadbeef;
+   j.x = 0x1122334455667788;
+   memcpy ((char *)&i + o1, (char *)&j + o2, sz);
+   return i.x;
+ }
+ extern void abort (void);
+ int main()
+ {
+   if (test (0, 0, 8) != 0x1122334455667788)
+     abort ();
+   if (test (0, 0, 5) == 0xdeadbe4455667788)
+     {
+       if (test (0, 1, 5) != 0xdeadbe3344556677)
+ 	abort ();
+       if (test (3, 1, 3) != 0xdead556677adbeef)
+ 	abort ();
+     } 
+   else if (test (0, 0, 5) == 0x1122334455adbeef)
+     {
+       if (test (0, 1, 5) != 0x2233445566adbeef)
+ 	abort ();
+       if (test (3, 1, 3) != 0xdeadbe223344beef)
+ 	abort ();
+     }
+   else
+     abort ();
+   return 0;
+ }

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-06-11 13:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-11 14:09 [PATCH][mem-ref2] Fix expansion of MEM_REF of registers Richard Guenther

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).