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]

[tree-ssa] fix latent & real bugs in BIT_FIELD_REFs


Hello,

this is the updated version of my patch to handle BIT_FIELD_REFs
correctly.  BIT_FIELD_REFs on the left side of MODIFY_EXPRs are never
produced (at least in 3.2, 3.5 mainline and 3.5 tree-ssa which were the
trees I had at hand), still I added the check that its operand is not a
register.

I also found a bug in their handling on the right side: get_virtual_var
did not go through them.  Note that in that case BIT_FIELD_REFs can
refer to both real and virtual operands, so get_virtual_var should check
if the BIT_FIELD_REF refers to a non-register operand.  Luckily a test
case was easy to build.

I also changed the ChangeLog entry for get_expr_operands, the change is
indeed unnecessary but very safe.

Bootstrapped/regtested on i686-pc-linux-gnu, ok to apply?

2004-03-24  Paolo Bonzini  <bonzini@gnu.org>

	* tree-alias-common.c (find_func_aliases): Support
	assigning to BIT_FIELD_REFs.
	* tree-cfg.c (verify_expr): Don't allow assign to
	a register with BIT_FIELD_REF.
	* tree-dfa.c (get_virtual_var): Go through BIT_FIELD_REFs
	if they access a non-register.
	(discover_nonconstant_array_refs_r): Go through BIT_FIELD_REFs.
	* tree-simple.c: Document that BIT_FIELD_REFs are valid lvalues.
	* tree-ssa-operands.c (get_expr_operands): Avoid a recursive
	call for BIT_FIELD_REFs.
	* tree-ssa.c (set_is_used): Go through BIT_FIELD_REFs.

2004-03-24  Paolo Bonzini  <bonzini@gnu.org>

	* gcc.dg/tree-ssa/20040324-1.c: New testcase.

Index: gcc/tree-alias-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-alias-common.c,v
retrieving revision 1.1.2.53
diff -u -p -r1.1.2.53 tree-alias-common.c
--- gcc/tree-alias-common.c	12 Mar 2004 17:49:52 -0000	1.1.2.53
+++ gcc/tree-alias-common.c	24 Mar 2004 10:05:22 -0000
@@ -629,7 +629,8 @@ find_func_aliases (tree stp)
       else
 	{
 	  /* x.f = y  or x->f = y */
-	  if (TREE_CODE (op0) == COMPONENT_REF 
+	  if ((TREE_CODE (op0) == COMPONENT_REF 
+	       || TREE_CODE (op0) == BIT_FIELD_REF)
 	      && is_gimple_variable (op1))
 	    {
 	      if (rhsAV != NULL)
Index: gcc/tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.278
diff -u -p -r1.1.4.278 tree-cfg.c
--- gcc/tree-cfg.c	16 Mar 2004 22:31:55 -0000	1.1.4.278
+++ gcc/tree-cfg.c	24 Mar 2004 10:05:23 -0000
@@ -2938,6 +2938,16 @@ verify_expr (tree *tp, int *walk_subtree
 	}
       break;
 
+    case MODIFY_EXPR:
+      x = TREE_OPERAND (t, 0);
+      if (TREE_CODE (x) == BIT_FIELD_REF
+	  && is_gimple_reg (TREE_OPERAND (x, 0)))
+	{
+	  error ("GIMPLE register modified with BIT_FIELD_REF");
+	  return *tp;
+	}
+      break;
+
     case ADDR_EXPR:
       x = TREE_OPERAND (t, 0);
       while (TREE_CODE (x) == ARRAY_REF
Index: gcc/tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.222
diff -u -p -r1.1.4.222 tree-dfa.c
--- gcc/tree-dfa.c	19 Mar 2004 17:51:45 -0000	1.1.4.222
+++ gcc/tree-dfa.c	24 Mar 2004 10:05:23 -0000
@@ -984,7 +984,8 @@ get_virtual_var (tree var)
   while (code == ARRAY_REF
          || code == COMPONENT_REF
 	 || code == REALPART_EXPR
-	 || code == IMAGPART_EXPR)
+	 || code == IMAGPART_EXPR
+         || (code == BIT_FIELD_REF && !is_gimple_reg (TREE_OPERAND (var, 0))))
     {
       var = TREE_OPERAND (var, 0);
       code = TREE_CODE (var);
@@ -1222,6 +1223,7 @@ discover_nonconstant_array_refs_r (tree 
       while ((TREE_CODE (t) == ARRAY_REF
 	      && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
 	     || (TREE_CODE (t) == COMPONENT_REF
+		 || TREE_CODE (t) == BIT_FIELD_REF
 		 || TREE_CODE (t) == REALPART_EXPR
 		 || TREE_CODE (t) == IMAGPART_EXPR))
 	t = TREE_OPERAND (t, 0);
Index: gcc/tree-simple.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-simple.c,v
retrieving revision 1.1.4.74
diff -u -p -r1.1.4.74 tree-simple.c
--- gcc/tree-simple.c	12 Mar 2004 04:19:06 -0000	1.1.4.74
+++ gcc/tree-simple.c	24 Mar 2004 10:05:23 -0000
@@ -113,8 +113,13 @@ Boston, MA 02111-1307, USA.  */
      op1 -> arglist
 
    addr-expr-arg : compref | ID
-   lhs: addr-expr-arg | '*' ID
+   lhs: addr-expr-arg | '*' ID | bitfieldref
    min-lval: ID | '*' ID
+   bitfieldref :
+     BIT_FIELD_REF
+       op0 -> compref | min-lval
+       op1 -> CONST
+       op2 -> CONST
    compref :
      COMPONENT_REF
        op0 -> compref | min-lval
Index: gcc/tree-ssa-operands.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-operands.c,v
retrieving revision 1.1.2.17
diff -u -p -r1.1.2.17 tree-ssa-operands.c
--- gcc/tree-ssa-operands.c	16 Mar 2004 22:31:56 -0000	1.1.2.17
+++ gcc/tree-ssa-operands.c	24 Mar 2004 10:05:23 -0000
@@ -1012,7 +1012,8 @@ get_expr_operands (tree stmt, tree *expr
 	   will not be constant propagated because the two partial
 	   definitions to 'a' will kill each other.  Note that SRA may be
 	   able to fix this problem if 'a' can be scalarized.  */
-  if (code == IMAGPART_EXPR || code == REALPART_EXPR || code == COMPONENT_REF)
+  if (code == IMAGPART_EXPR || code == REALPART_EXPR || code == COMPONENT_REF
+      || code == BIT_FIELD_REF)
     {
       /* If the LHS of the compound reference is not a regular variable,
 	 recurse to keep looking for more operands in the subexpression.  */
@@ -1088,7 +1089,6 @@ get_expr_operands (tree stmt, tree *expr
   /* Unary expressions.  */
   if (class == '1'
       || code == TRUTH_NOT_EXPR
-      || code == BIT_FIELD_REF
       || code == CONSTRUCTOR)
     {
       get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags, prev_vops);
Index: gcc/tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.216
diff -u -p -r1.1.4.216 tree-ssa.c
--- gcc/tree-ssa.c	19 Mar 2004 02:07:25 -0000	1.1.4.216
+++ gcc/tree-ssa.c	24 Mar 2004 10:05:23 -0000
@@ -435,6 +435,7 @@ set_is_used (tree t)
 	case COMPONENT_REF:
 	case REALPART_EXPR:
 	case IMAGPART_EXPR:
+	case BIT_FIELD_REF:
 	case INDIRECT_REF:
 	  t = TREE_OPERAND (t, 0);
 	  break;



/* { dg-do run } */
/* { dg-options "-O2" } */

/* Ensure that BIT_FIELD_REFs gets the appropriate VUSE.
   Contributed by Paolo Bonzini  <bonzini@gnu.org>.
   In this test, the if's are folded to BIT_FIELD_REFs but
   the VUSEs were not added due to a bug in get_virtual_var,
   therefore DOM did not see that i was modified between
   the two ifs and optimized away the second if.  */

struct x {
  unsigned b : 1;
  unsigned c : 1;
};

struct x i = {1, 1};

int main ()
{
  i.b = 1;
  if (i.b == 1 && i.c == 0)
    exit (0);
  i.c = 0;
  if (i.b == 1 && i.c == 0)
    exit (0);
  abort ();
}


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