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 constant propagation bug


PRE exposed a latent bug in const/copy propagation.  Specifically we had
a PHI for virtual operands and we constant propagated a STRING_CST into
one of the PHI arguments.   That created something like this:


  # default_tupleseps_20 = PHI <default_tupleseps_24(5), "fubar" (2)>;
<L11>:;
  #   VUSE <default_tupleseps_20>;
  T.1_8 = *tupleseps_1;


We then decide to create *tupleseps_1 as if it was in block 2.  

That created something like

#  VUSE <"fubar">;
T.1_8 = *tupleseps_1;


All hell broke loose after that.  Nothing really expects to find constants
in virtual operands....


While we could try and do something special for this case, I really don't
think it's worth the effort.  When compiling the Fedora Core 2 packages
this trips exactly once across the 773 packages which currently build.

It's far easier to just disallow propagation of a constant into a virtual
operand.

Bootstrapped and regression tested on i686-pc-linux-gnu.

	* tree-flow-inline.h (may_propagate_copy): Do not allow propagation of
	a constant for a virtual operand.

	* gcc.c-torture/compile/20040309-1.c: New test.

Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-flow-inline.h,v
retrieving revision 1.1.2.67
diff -c -p -r1.1.2.67 tree-flow-inline.h
*** tree-flow-inline.h	21 Feb 2004 06:28:18 -0000	1.1.2.67
--- tree-flow-inline.h	9 Mar 2004 18:14:09 -0000
*************** may_propagate_copy (tree dest, tree orig
*** 438,447 ****
  	return false;
      }
  
!   /* We do not care about abnormal PHIs or user specified register
!      declarations for virtual operands.  */
!   if (! is_gimple_reg (dest))
!     return true;
  
    return (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)
  	  && (TREE_CODE (orig) != SSA_NAME
--- 438,466 ----
  	return false;
      }
  
!   /* If the destination is a SSA_NAME for a virtual operand, then we have
!      some special cases to handle.  */
!   if (TREE_CODE (dest) == SSA_NAME && !is_gimple_reg (dest))
!     {
!       /* If both operands are SSA_NAMEs referring to virtual operands, then
! 	 we can always propagate.  */
!       if (TREE_CODE (orig) == SSA_NAME)
! 	{
! 	  if (!is_gimple_reg (orig))
! 	    return true;
! 
! #ifdef ENABLE_CHECKING
! 	  /* If we have one real and one virtual operand, then something has
! 	     gone terribly wrong.  */
! 	  if (is_gimple_reg (orig))
! 	    abort ();
! #endif
! 	}
! 
!       /* We have a "copy" from something like a constant into a virtual
! 	 operand.  Reject these.  */
!       return false;
!     }
  
    return (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)
  	  && (TREE_CODE (orig) != SSA_NAME
Index: testsuite/gcc.c-torture/compile/20040309-1.c
===================================================================
RCS file: testsuite/gcc.c-torture/compile/20040309-1.c
diff -N testsuite/gcc.c-torture/compile/20040309-1.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.c-torture/compile/20040309-1.c	9 Mar 2004 18:15:08 -0000
***************
*** 0 ****
--- 1,20 ----
+ static const char default_tupleseps[] = ", \t";
+ 
+ 
+ fubar (tupleseps)
+      const char *tupleseps;
+ {
+   char *kp, *sp;
+   const char *septmp;
+   const char *tseplist;
+   tseplist = (tupleseps) ? tupleseps : default_tupleseps;
+   while (kp)
+     {
+       if (*tseplist)
+         septmp = tseplist;
+       bar (*septmp);
+       if (*tseplist)
+         if (*kp)
+           ;
+     }
+ }








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