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]

fix 18008


A sufficient hack for this problem is to strip off a nop-expr that
implies a mask, when we're storing into a field of the same width.

Plus the mode mismatch fix mentioned in the PR, which I can't prove
is harmful, but is certainly confusing when looking at things.

Tested on i386 and i686 linux.


r~


        PR middle-end/18008
        * c-decl.c (finish_struct): Set DECL_MODE after resetting a
        field's type.
        * expr.c (store_field): Strip conversions to odd-bit-sized types
        if the destination field width matches.

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.623
diff -u -p -r1.623 c-decl.c
--- c-decl.c	5 Jan 2005 01:41:36 -0000	1.623
+++ c-decl.c	26 Jan 2005 23:14:37 -0000
@@ -5301,8 +5301,11 @@ finish_struct (tree t, tree fieldlist, t
 	    = tree_low_cst (DECL_INITIAL (*fieldlistp), 1);
 	  tree type = TREE_TYPE (*fieldlistp);
 	  if (width != TYPE_PRECISION (type))
-	    TREE_TYPE (*fieldlistp)
-	      = build_nonstandard_integer_type (width, TYPE_UNSIGNED (type));
+	    {
+	      TREE_TYPE (*fieldlistp)
+	        = build_nonstandard_integer_type (width, TYPE_UNSIGNED (type));
+	      DECL_MODE (*fieldlistp) = TYPE_MODE (TREE_TYPE (*fieldlistp));
+	    }
 	  DECL_INITIAL (*fieldlistp) = 0;
 	}
       else
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.773
diff -u -p -r1.773 expr.c
--- expr.c	26 Jan 2005 15:20:49 -0000	1.773
+++ expr.c	26 Jan 2005 23:14:40 -0000
@@ -5215,7 +5215,21 @@ store_field (rtx target, HOST_WIDE_INT b
 	  && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) == INTEGER_CST
 	  && compare_tree_int (TYPE_SIZE (TREE_TYPE (exp)), bitsize) != 0))
     {
-      rtx temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
+      rtx temp;
+
+      /* If EXP is a NOP_EXPR of precision less than its mode, then that
+	 implies a mask operation.  If the precision is the same size as
+	 the field we're storing into, that mask is redundant.  This is
+	 particularly common with bit field assignments generated by the
+	 C front end.  */
+      if (TREE_CODE (exp) == NOP_EXPR
+	  && INTEGRAL_TYPE_P (TREE_TYPE (exp))
+	  && (TYPE_PRECISION (TREE_TYPE (exp))
+	      < GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp))))
+	  && bitsize == TYPE_PRECISION (TREE_TYPE (exp)))
+	exp = TREE_OPERAND (exp, 0);
+
+      temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);
 
       /* If BITSIZE is narrower than the size of the type of EXP
 	 we will be narrowing TEMP.  Normally, what's wanted are the


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