fix gcc.c-torture/execute/20031215-1.c compilation

Richard Henderson rth@redhat.com
Thu May 19 04:22:00 GMT 2005


This fixes the ICE wrt having a V_USE and not a V_*_DEF for
an assignment.  Diego's assumption that we couldn't see a
store to a readonly memory is false.  We can if the statement
is in fact invalid.  If the C++ front end cases were fixed, I
suppose we could transform this into a __builtin_trap, but...

The test case still fails at execute because the rtl ifcvt pass
transforms

	if (x != 0)
	  x = 0;

into

	x = 0;

under the assumption that the redundant store is harmless.
It isn't harmless in this case, obviously.  I'll tackle that
in a separate patch.

Tested on i686-linux.


r~



        * tree-ssa-operands.c (opf_non_specific): New.
        (get_asm_expr_operands): Set it.
        (add_call_clobber_ops, add_call_read_ops): Likewise.
        (add_stmt_operand): Test it instead of opf_kill_def when
        considering unmodifiable variables.

Index: tree-ssa-operands.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-operands.c,v
retrieving revision 2.83
diff -u -p -d -r2.83 tree-ssa-operands.c
--- tree-ssa-operands.c	18 May 2005 13:26:17 -0000	2.83
+++ tree-ssa-operands.c	19 May 2005 04:07:20 -0000
@@ -99,6 +99,10 @@ Boston, MA 02111-1307, USA.  */
    VUSE for 'b'.  */
 #define opf_no_vops 	(1 << 2)
 
+/* Operand is a "non-specific" kill for call-clobbers and such.  This is used
+   to distinguish "reset the world" events from explicit MODIFY_EXPRs.  */
+#define opf_non_specific  (1 << 3)
+
 /* This structure maintain a sorted list of operands which is created by
    parse_ssa_operand.  */
 struct opbuild_list_d GTY (())
@@ -1552,7 +1556,7 @@ get_asm_expr_operands (tree stmt)
 	  EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
 	      {
 		tree var = referenced_var (i);
-		add_stmt_operand (&var, s_ann, opf_is_def);
+		add_stmt_operand (&var, s_ann, opf_is_def | opf_non_specific);
 	      }
 
 	/* Now clobber all addressables.  */
@@ -1570,7 +1574,7 @@ get_asm_expr_operands (tree stmt)
 		  && get_subvars_for_var (var) != NULL)
 		continue;		
 
-	      add_stmt_operand (&var, s_ann, opf_is_def);
+	      add_stmt_operand (&var, s_ann, opf_is_def | opf_non_specific);
 	    }
 
 	break;
@@ -1756,19 +1760,20 @@ add_stmt_operand (tree *var_p, stmt_ann_
   /* If the variable cannot be modified and this is a V_MAY_DEF change
      it into a VUSE.  This happens when read-only variables are marked
      call-clobbered and/or aliased to writeable variables.  So we only
-     check that this only happens on stores, and not writes to GIMPLE
-     registers.
-     
-     FIXME: The C++ FE is emitting assignments in the IL stream for
-     read-only globals.  This is wrong, but for the time being disable
-     this transformation on V_MUST_DEF operands (otherwise, we
-     mis-optimize SPEC2000's eon).  */
-  if ((flags & opf_is_def)
-      && !(flags & opf_kill_def)
-      && unmodifiable_var_p (var))
+     check that this only happens on non-specific stores.
+
+     Note that if this is a specific store, i.e. associated with a
+     modify_expr, then we can't suppress the V_DEF, lest we run into
+     validation problems.
+
+     This can happen when programs cast away const, leaving us with a
+     store to read-only memory.  If the statement is actually executed
+     at runtime, then the program is ill formed.  If the statement is
+     not executed then all is well.  At the very least, we cannot ICE.  */
+  if ((flags & opf_non_specific) && unmodifiable_var_p (var))
     {
       gcc_assert (!is_real_op);
-      flags &= ~opf_is_def;
+      flags &= ~(opf_is_def | opf_kill_def);
     }
 
   if (is_real_op)
@@ -1976,7 +1981,7 @@ add_call_clobber_ops (tree stmt)
       if (unmodifiable_var_p (var))
 	add_stmt_operand (&var, &empty_ann, opf_none);
       else
-	add_stmt_operand (&var, &empty_ann, opf_is_def);
+	add_stmt_operand (&var, &empty_ann, opf_is_def | opf_non_specific);
     }
 
   clobbered_aliased_loads = empty_ann.makes_aliased_loads;
@@ -2061,7 +2066,7 @@ add_call_read_ops (tree stmt)
   EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, u, bi)
     {
       tree var = referenced_var (u);
-      add_stmt_operand (&var, &empty_ann, opf_none);
+      add_stmt_operand (&var, &empty_ann, opf_none | opf_non_specific);
     }
 
   ro_call_aliased_loads = empty_ann.makes_aliased_loads;



More information about the Gcc-patches mailing list