[PATCH] Fix RTL-sharing bug in combine - bootstrap failure

Ulrich Weigand weigand@i1.informatik.uni-erlangen.de
Wed Jul 16 13:27:00 GMT 2003


Hello,

this fixes an RTL sharing bug in combine that causes bootstrap
failures on s390(x).  The symptom was a broken C++ compiler,
caused by a miscompile of dfs_access_in_type in cp/search.c.

This in turn was caused by a long-standing RTL sharing bug
in combine_simplify_rtx, which got exposed by Kazu Hirata's
recent check-in:
http://gcc.gnu.org/ml/gcc-patches/2003-07/msg01302.html

The problem is that combine_simplify_rtx uses
      cond = if_then_else_cond (x, &true_rtx, &false_rtx);
which is designed so that the resulting true_rtx and false_rtx
can share RTL with the original x.

However, combine_simplify_rtx later does 
 	  true_rtx = subst (true_rtx, pc_rtx, pc_rtx, 0, 0);
 	  false_rtx = subst (false_rtx, pc_rtx, pc_rtx, 0, 0);
which means that if the subst suceeds and updates parts of
true_rtx or false_rtx in place, the original RTL for x can
be changed as well.

If the attempt at IF_THEN_ELSE simplification later fails
(because true_rtx or false_rtx are still too complex),
combine_simplify_rtx falls back on the original x to 
continue simplification -- which has been clobbered in the
meantime ...

Bootstrapped/regtested on s390-ibm-linux on s390x-ibm-linux.
OK?  

What about 3.3?  It doesn't actually show up there in any 
test case I'm aware of, but it's certainly a latent bug ...

Bye,
Ulrich


ChangeLog:

	* combine.c (combine_simplify_rtx): Fix RTL sharing bug.

Index: gcc/combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.369
diff -c -p -r1.369 combine.c
*** gcc/combine.c	13 Jul 2003 19:03:28 -0000	1.369
--- gcc/combine.c	16 Jul 2003 02:11:55 -0000
*************** combine_simplify_rtx (rtx x, enum machin
*** 3634,3641 ****
  
  	  /* Simplify the alternative arms; this may collapse the true and
  	     false arms to store-flag values.  */
! 	  true_rtx = subst (true_rtx, pc_rtx, pc_rtx, 0, 0);
! 	  false_rtx = subst (false_rtx, pc_rtx, pc_rtx, 0, 0);
  
  	  /* If true_rtx and false_rtx are not general_operands, an if_then_else
  	     is unlikely to be simpler.  */
--- 3634,3641 ----
  
  	  /* Simplify the alternative arms; this may collapse the true and
  	     false arms to store-flag values.  */
! 	  true_rtx = subst (copy_rtx (true_rtx), pc_rtx, pc_rtx, 0, 0);
! 	  false_rtx = subst (copy_rtx (false_rtx), pc_rtx, pc_rtx, 0, 0);
  
  	  /* If true_rtx and false_rtx are not general_operands, an if_then_else
  	     is unlikely to be simpler.  */
-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de



More information about the Gcc-patches mailing list