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]

[PATCH] Fix PR38747


This fixes PR38747 a bug where forwprop generates wrong-code when
creating a VIEW_CONVERT_EXPR from a type-punned load.  The simple
fix is to not do that.  A proper fix for optimization issues
that involve type-punning is to be implemented in value-numbering
instead.  The fix also happens to fix PR36143.

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

Richard.

2009-09-24  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/36143
	PR tree-optimization/38747
	* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Only
	create VIEW_CONVERT_EXPRs for TBAA compatible accesses.

	* gcc.dg/tree-ssa/fre-vce-1.c: XFAIL.
	* gcc.dg/tree-ssa/forwprop-6.c: Likewise.
	* g++.dg/torture/pr38747.C: New testcase.
	* g++.dg/tree-ssa/pr19637.C: Un-XFAIL.

Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c	(revision 152114)
--- gcc/tree-ssa-forwprop.c	(working copy)
*************** forward_propagate_addr_expr_1 (tree name
*** 831,837 ****
        && !TYPE_VOLATILE (TREE_TYPE (rhs))
        && !TYPE_VOLATILE (TREE_TYPE (TREE_OPERAND (def_rhs, 0)))
        && operand_equal_p (TYPE_SIZE (TREE_TYPE (rhs)),
! 			  TYPE_SIZE (TREE_TYPE (TREE_OPERAND (def_rhs, 0))), 0)) 
     {
       tree def_rhs_base, new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
       new_rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), new_rhs);
--- 831,839 ----
        && !TYPE_VOLATILE (TREE_TYPE (rhs))
        && !TYPE_VOLATILE (TREE_TYPE (TREE_OPERAND (def_rhs, 0)))
        && operand_equal_p (TYPE_SIZE (TREE_TYPE (rhs)),
! 			  TYPE_SIZE (TREE_TYPE (TREE_OPERAND (def_rhs, 0))), 0)
!       /* Make sure we only do TBAA compatible replacements.  */
!       && get_alias_set (TREE_OPERAND (def_rhs, 0)) == get_alias_set (rhs))
     {
       tree def_rhs_base, new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
       new_rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), new_rhs);
Index: gcc/testsuite/gcc.dg/tree-ssa/fre-vce-1.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/fre-vce-1.c	(revision 152114)
--- gcc/testsuite/gcc.dg/tree-ssa/fre-vce-1.c	(working copy)
*************** void a2 (struct s1 sv, int i)
*** 32,37 ****
  }
  
  /* { dg-final { scan-tree-dump-times "sv_\[0-9\]\\\(D\\\)->i" 2 "fre" } } */
! /* { dg-final { scan-tree-dump-times "sv.i" 2 "fre" } } */
! 
  /* { dg-final { cleanup-tree-dump "fre" } } */
--- 32,38 ----
  }
  
  /* { dg-final { scan-tree-dump-times "sv_\[0-9\]\\\(D\\\)->i" 2 "fre" } } */
! /* We can't value-number *(float *)&sv.i as VIEW_CONVERT_EXPR of the
!    value of sv.i.  */
! /* { dg-final { scan-tree-dump-times "sv.i" 2 "fre" { xfail *-*-* } } } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-6.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/forwprop-6.c	(revision 152114)
--- gcc/testsuite/gcc.dg/tree-ssa/forwprop-6.c	(working copy)
*************** void f(void)
*** 17,22 ****
  }
  
  /* We should be able to convert the cast to a VCE in forwprop1,
!    even if there is an aliasing violation. */
! /* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 1 "forwprop1"} } */
  /* { dg-final { cleanup-tree-dump "forwprop1" } } */
--- 17,27 ----
  }
  
  /* We should be able to convert the cast to a VCE in forwprop1,
!    even if there is an aliasing violation.
!    ???  While this would be useful and nice to our users in this
!    particular situation before doing this transformation we have to
!    assure that a is killed by a dominating store via type float for
!    it to be valid.  Then we might as well handle the situation by
!    value-numbering, removing the load alltogether.  */
! /* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 1 "forwprop1" { xfail *-*-* } } } */
  /* { dg-final { cleanup-tree-dump "forwprop1" } } */
Index: gcc/testsuite/g++.dg/torture/pr38747.C
===================================================================
*** gcc/testsuite/g++.dg/torture/pr38747.C	(revision 0)
--- gcc/testsuite/g++.dg/torture/pr38747.C	(revision 0)
***************
*** 0 ****
--- 1,19 ----
+ /* { dg-do run } */
+ 
+ extern "C" void abort (void);
+ inline void *operator new (__SIZE_TYPE__, void *__p) throw () { return __p; }
+ 
+ int __attribute__((noinline))
+ foo(void)
+ {
+   float f = 0;
+   int *i = new (&f) int (1);
+   return *(int *)&f;
+ }
+ 
+ int main()
+ {
+   if (foo() != 1)
+     abort ();
+   return 0;
+ }
Index: gcc/testsuite/g++.dg/tree-ssa/pr19637.C
===================================================================
*** gcc/testsuite/g++.dg/tree-ssa/pr19637.C	(revision 152114)
--- gcc/testsuite/g++.dg/tree-ssa/pr19637.C	(working copy)
*************** int foo_void_offset(void)
*** 29,34 ****
    return reinterpret_cast<Foo *>(&i[0])->i[0];
  }
  
! /* Regarding the xfail, see PR36143.  */
! /* { dg-final { scan-tree-dump-times "return 1;" 3 "dom1" { xfail *-*-* } } } */
  /* { dg-final { cleanup-tree-dump "dom1" } } */
--- 29,33 ----
    return reinterpret_cast<Foo *>(&i[0])->i[0];
  }
  
! /* { dg-final { scan-tree-dump-times "return 1;" 3 "dom1" } } */
  /* { dg-final { cleanup-tree-dump "dom1" } } */


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