[PATCH] Fix PR40496

Richard Guenther rguenther@suse.de
Fri Jul 10 12:01:00 GMT 2009


This fixes PR40496.  Loop unrolling creates new PHI nodes and randomly
selects a base variable for its result.  This causes problems if
PHI arguments do not have fully compatible types.  The fix is to
choose a result type that all arguments can be assigned to.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2009-07-10  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/40496
	* tree-ssa-loop-manip.c (tree_transform_and_unroll_loop): Create
	the PHI result with a compatible type.

	* g++.dg/opt/pr40496.C: New testcase.

Index: gcc/tree-ssa-loop-manip.c
===================================================================
*** gcc/tree-ssa-loop-manip.c	(revision 149458)
--- gcc/tree-ssa-loop-manip.c	(working copy)
*************** tree_transform_and_unroll_loop (struct l
*** 990,999 ****
        /* Prefer using original variable as a base for the new ssa name.
  	 This is necessary for virtual ops, and useful in order to avoid
  	 losing debug info for real ops.  */
!       if (TREE_CODE (next) == SSA_NAME)
  	var = SSA_NAME_VAR (next);
!       else if (TREE_CODE (init) == SSA_NAME)
  	var = SSA_NAME_VAR (init);
        else
  	{
  	  var = create_tmp_var (TREE_TYPE (init), "unrinittmp");
--- 990,1008 ----
        /* Prefer using original variable as a base for the new ssa name.
  	 This is necessary for virtual ops, and useful in order to avoid
  	 losing debug info for real ops.  */
!       if (TREE_CODE (next) == SSA_NAME
! 	  && useless_type_conversion_p (TREE_TYPE (next),
! 					TREE_TYPE (init)))
  	var = SSA_NAME_VAR (next);
!       else if (TREE_CODE (init) == SSA_NAME
! 	       && useless_type_conversion_p (TREE_TYPE (init),
! 					     TREE_TYPE (next)))
  	var = SSA_NAME_VAR (init);
+       else if (useless_type_conversion_p (TREE_TYPE (next), TREE_TYPE (init)))
+ 	{
+ 	  var = create_tmp_var (TREE_TYPE (next), "unrinittmp");
+ 	  add_referenced_var (var);
+ 	}
        else
  	{
  	  var = create_tmp_var (TREE_TYPE (init), "unrinittmp");
Index: gcc/testsuite/g++.dg/opt/pr40496.C
===================================================================
*** gcc/testsuite/g++.dg/opt/pr40496.C	(revision 0)
--- gcc/testsuite/g++.dg/opt/pr40496.C	(revision 0)
***************
*** 0 ****
--- 1,18 ----
+ // { dg-do compile }
+ // { dg-options "-O2 -fprefetch-loop-arrays -msse2" { target i?86-*-* x86_64-*-* } }
+ 
+ struct DOMStringHandle
+ {
+   unsigned int fLength;
+   int fRefCount;
+ };
+ static void *freeListPtr;
+ void foo(DOMStringHandle *dsg)
+ {
+   int i;
+   for (i = 1; i < 1023; i++)
+     {
+       *(void **) &dsg[i] = freeListPtr;
+       freeListPtr = &dsg[i];
+     }
+ }



More information about the Gcc-patches mailing list