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 PR69776, FRE/PRE not honoring middle-end memory model


FRE/PREs redundant store removal code doesn't honor the middle-end
memory model which says that all stores change the dynamic type of
the affected memory region.  So it removed the second 'int' store in

  MEM[(int *)p_3] = 1;
  MEM[(double *)p_3] = 0.0;
  MEM[(int *)p_3] = 1;

which is not valid (if not done later DSE removes the first int store
which _is_ valid).

So I am bootstrapping and testing the following fix on 
x86_64-unknown-linux-gnu.

Richard.

2016-02-12  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/69776
	* tree-ssa-sccvn.h (vn_reference_lookup): Adjust prototype.
	* tree-ssa-sccvn.c (vn_reference_lookup): Add parameter to
	indicate whether we can use TBAA to disambiguate against stores.
	Use alias-set zero if not.
	(visit_reference_op_store): Do not use TBAA when looking up
	redundant stores.
	* tree-ssa-pre.c (compute_avail): Use TBAA here.
	(eliminate_dom_walker::before_dom_children): But not when looking
	up redundant stores.

	* gcc.dg/torture/pr69776.c: New testcase.

Index: gcc/tree-ssa-sccvn.h
===================================================================
*** gcc/tree-ssa-sccvn.h	(revision 233369)
--- gcc/tree-ssa-sccvn.h	(working copy)
*************** bool ao_ref_init_from_vn_reference (ao_r
*** 216,222 ****
  tree vn_reference_lookup_pieces (tree, alias_set_type, tree,
  				 vec<vn_reference_op_s> ,
  				 vn_reference_t *, vn_lookup_kind);
! tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *);
  void vn_reference_lookup_call (gcall *, vn_reference_t *, vn_reference_t);
  vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
  					   vec<vn_reference_op_s> ,
--- 216,222 ----
  tree vn_reference_lookup_pieces (tree, alias_set_type, tree,
  				 vec<vn_reference_op_s> ,
  				 vn_reference_t *, vn_lookup_kind);
! tree vn_reference_lookup (tree, tree, vn_lookup_kind, vn_reference_t *, bool);
  void vn_reference_lookup_call (gcall *, vn_reference_t *, vn_reference_t);
  vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
  					   vec<vn_reference_op_s> ,
Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c	(revision 233369)
--- gcc/tree-ssa-sccvn.c	(working copy)
*************** vn_reference_lookup_pieces (tree vuse, a
*** 2230,2240 ****
     number if it exists in the hash table.  Return NULL_TREE if it does
     not exist in the hash table or if the result field of the structure
     was NULL..  VNRESULT will be filled in with the vn_reference_t
!    stored in the hashtable if one exists.  */
  
  tree
  vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
! 		     vn_reference_t *vnresult)
  {
    vec<vn_reference_op_s> operands;
    struct vn_reference_s vr1;
--- 2230,2241 ----
     number if it exists in the hash table.  Return NULL_TREE if it does
     not exist in the hash table or if the result field of the structure
     was NULL..  VNRESULT will be filled in with the vn_reference_t
!    stored in the hashtable if one exists.  When TBAA_P is false assume
!    we are looking up a store and treat it as having alias-set zero.  */
  
  tree
  vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
! 		     vn_reference_t *vnresult, bool tbaa_p)
  {
    vec<vn_reference_op_s> operands;
    struct vn_reference_s vr1;
*************** vn_reference_lookup (tree op, tree vuse,
*** 2264,2269 ****
--- 2265,2272 ----
  	  || !ao_ref_init_from_vn_reference (&r, vr1.set, vr1.type,
  					     vr1.operands))
  	ao_ref_init (&r, op);
+       if (! tbaa_p)
+ 	r.ref_alias_set = r.base_alias_set = 0;
        vn_walk_kind = kind;
        wvnresult =
  	(vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,
*************** visit_reference_op_load (tree lhs, tree
*** 3350,3356 ****
    last_vuse = gimple_vuse (stmt);
    last_vuse_ptr = &last_vuse;
    result = vn_reference_lookup (op, gimple_vuse (stmt),
! 				default_vn_walk_kind, NULL);
    last_vuse_ptr = NULL;
  
    /* We handle type-punning through unions by value-numbering based
--- 3353,3359 ----
    last_vuse = gimple_vuse (stmt);
    last_vuse_ptr = &last_vuse;
    result = vn_reference_lookup (op, gimple_vuse (stmt),
! 				default_vn_walk_kind, NULL, true);
    last_vuse_ptr = NULL;
  
    /* We handle type-punning through unions by value-numbering based
*************** visit_reference_op_store (tree lhs, tree
*** 3472,3478 ****
       Otherwise, the vdefs for the store are used when inserting into
       the table, since the store generates a new memory state.  */
  
!   result = vn_reference_lookup (lhs, vuse, VN_NOWALK, NULL);
  
    if (result)
      {
--- 3475,3481 ----
       Otherwise, the vdefs for the store are used when inserting into
       the table, since the store generates a new memory state.  */
  
!   result = vn_reference_lookup (lhs, vuse, VN_NOWALK, NULL, false);
  
    if (result)
      {
*************** visit_reference_op_store (tree lhs, tree
*** 3487,3493 ****
        && default_vn_walk_kind == VN_WALK)
      {
        assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
!       vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult);
        if (vnresult)
  	{
  	  VN_INFO (vdef)->use_processed = true;
--- 3490,3496 ----
        && default_vn_walk_kind == VN_WALK)
      {
        assign = build2 (MODIFY_EXPR, TREE_TYPE (lhs), lhs, op);
!       vn_reference_lookup (assign, vuse, VN_NOWALK, &vnresult, false);
        if (vnresult)
  	{
  	  VN_INFO (vdef)->use_processed = true;
Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c	(revision 233369)
--- gcc/tree-ssa-pre.c	(working copy)
*************** compute_avail (void)
*** 3745,3751 ****
  		      vn_reference_t ref;
  		      vn_reference_lookup (gimple_assign_rhs1 (stmt),
  					   gimple_vuse (stmt),
! 					   VN_WALK, &ref);
  		      if (!ref)
  			continue;
  
--- 3745,3751 ----
  		      vn_reference_t ref;
  		      vn_reference_lookup (gimple_assign_rhs1 (stmt),
  					   gimple_vuse (stmt),
! 					   VN_WALK, &ref, true);
  		      if (!ref)
  			continue;
  
*************** eliminate_dom_walker::before_dom_childre
*** 4208,4214 ****
            tree val;
  	  tree rhs = gimple_assign_rhs1 (stmt);
            val = vn_reference_lookup (gimple_assign_lhs (stmt),
!                                      gimple_vuse (stmt), VN_WALK, NULL);
            if (TREE_CODE (rhs) == SSA_NAME)
              rhs = VN_INFO (rhs)->valnum;
            if (val
--- 4208,4214 ----
            tree val;
  	  tree rhs = gimple_assign_rhs1 (stmt);
            val = vn_reference_lookup (gimple_assign_lhs (stmt),
!                                      gimple_vuse (stmt), VN_WALK, NULL, false);
            if (TREE_CODE (rhs) == SSA_NAME)
              rhs = VN_INFO (rhs)->valnum;
            if (val
Index: gcc/testsuite/gcc.dg/torture/pr69776.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr69776.c	(revision 0)
--- gcc/testsuite/gcc.dg/torture/pr69776.c	(working copy)
***************
*** 0 ****
--- 1,28 ----
+ /* { dg-do run } */
+ /* { dg-additional-options "-fstrict-aliasing" } */
+ 
+ extern void *malloc (__SIZE_TYPE__);
+ extern void abort (void);
+ 
+ void __attribute__((noinline,noclone))
+ foo (int *pi)
+ {
+   if (*pi != 1)
+     abort ();
+ }
+ 
+ int
+ main()
+ {
+   void *p = malloc(sizeof (double));
+   int *pi = p;
+   double *pd = p;
+ 
+   *pi = 1;
+   int a = *pi;
+   *pd = 0;
+   *pi = a;
+   foo (pi);
+ 
+   return 0;
+ }


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