This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] Fix constant propagation bug
- From: law at redhat dot com
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 09 Mar 2004 11:26:41 -0700
- Subject: [tree-ssa] Fix constant propagation bug
- Reply-to: law at redhat dot com
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)
+ ;
+ }
+ }