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 PR79777


This fixes the case where we only late during insertion are able to
simplify an expression (when we re-instantiated range-info on all
SSA names).  We can't do anything here but give up since we'd end up
with a SSA name with two values which for sure will eventually end up
confusing elimination.

Hopefully for GCC 8 I can fix all this by re-writing SCCVN to RPO style
iteration.

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

Richard.

2017-03-02  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/79777
	* tree-ssa-pre.c (eliminate_insert): Give up if we simplify
	the to insert expression to sth existing.

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

Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c	(revision 245803)
--- gcc/tree-ssa-pre.c	(working copy)
*************** eliminate_insert (gimple_stmt_iterator *
*** 4133,4143 ****
    else
      res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
  			TREE_TYPE (val), leader);
!   gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
!   VN_INFO_GET (res)->valnum = val;
  
!   if (TREE_CODE (leader) == SSA_NAME)
!     gimple_set_plf (SSA_NAME_DEF_STMT (leader), NECESSARY, true);
  
    pre_stats.insertions++;
    if (dump_file && (dump_flags & TDF_DETAILS))
--- 4133,4174 ----
    else
      res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
  			TREE_TYPE (val), leader);
!   if (TREE_CODE (res) != SSA_NAME
!       || SSA_NAME_IS_DEFAULT_DEF (res)
!       || gimple_bb (SSA_NAME_DEF_STMT (res)))
!     {
!       gimple_seq_discard (stmts);
  
!       /* During propagation we have to treat SSA info conservatively
!          and thus we can end up simplifying the inserted expression
! 	 at elimination time to sth not defined in stmts.  */
!       /* But then this is a redundancy we failed to detect.  Which means
!          res now has two values.  That doesn't play well with how
! 	 we track availability here, so give up.  */
!       if (dump_file && (dump_flags & TDF_DETAILS))
! 	{
! 	  if (TREE_CODE (res) == SSA_NAME)
! 	    res = eliminate_avail (res);
! 	  if (res)
! 	    {
! 	      fprintf (dump_file, "Failed to insert expression for value ");
! 	      print_generic_expr (dump_file, val, 0);
! 	      fprintf (dump_file, " which is really fully redundant to ");
! 	      print_generic_expr (dump_file, res, 0);
! 	      fprintf (dump_file, "\n");
! 	    }
! 	}
! 
!       return NULL_TREE;
!     }
!   else
!     {
!       gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
!       VN_INFO_GET (res)->valnum = val;
! 
!       if (TREE_CODE (leader) == SSA_NAME)
! 	gimple_set_plf (SSA_NAME_DEF_STMT (leader), NECESSARY, true);
!     }
  
    pre_stats.insertions++;
    if (dump_file && (dump_flags & TDF_DETAILS))
Index: gcc/testsuite/gcc.dg/torture/pr79777.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr79777.c	(nonexistent)
--- gcc/testsuite/gcc.dg/torture/pr79777.c	(working copy)
***************
*** 0 ****
--- 1,38 ----
+ /* { dg-do compile } */
+ 
+ typedef unsigned short __u16;
+ typedef unsigned int __u32;
+ typedef unsigned char u8;
+ typedef unsigned int u32;
+ typedef __u16 __le16;
+ typedef __u32 __le32;
+ typedef u32 secno;
+ struct bplus_internal_node {
+     __le32 file_secno;
+     __le32 down;
+ };
+ struct bplus_header {
+     u8 n_used_nodes;
+     __le16 first_free;
+     union {
+ 	struct bplus_internal_node internal[0];
+     }
+     u;
+ };
+ 
+ __u16 __fswab16(__u16 val);
+ __u32 __fswab32(__u32 val);
+ void hpfs_ea_remove (__u32);
+ 
+ void hpfs_truncate_btree(secno f, int fno, unsigned secs, struct bplus_header *btree)
+ {
+   int i, j;
+   for (i = 0; i < btree->n_used_nodes; i++)
+     if ((__builtin_constant_p((__u32)(( __u32)(__le32)(btree->u.internal[i].file_secno))) ? ((__u32)( (((__u32)(( __u32)(__le32)(btree->u.internal[i].file_secno)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__le32)(btree->u.internal[i].file_secno)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__le32)(btree->u.internal[i].file_secno)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__le32)(btree->u.internal[i].file_secno)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__le32)(btree->u.internal[i].file_secno))) >= secs) goto f;
+   return;
+ f:
+   for (j = i + 1; j < btree->n_used_nodes; j++)
+     hpfs_ea_remove((__builtin_constant_p((__u32)(( __u32)(__le32)(btree->u.internal[j].down))) ? ((__u32)( (((__u32)(( __u32)(__le32)(btree->u.internal[j].down)) & (__u32)0x000000ffUL) << 24) | (((__u32)(( __u32)(__le32)(btree->u.internal[j].down)) & (__u32)0x0000ff00UL) << 8) | (((__u32)(( __u32)(__le32)(btree->u.internal[j].down)) & (__u32)0x00ff0000UL) >> 8) | (((__u32)(( __u32)(__le32)(btree->u.internal[j].down)) & (__u32)0xff000000UL) >> 24))) : __fswab32(( __u32)(__le32)(btree->u.internal[j].down))));
+   btree->n_used_nodes = i + 1;
+   btree->first_free = (( __le16)(__builtin_constant_p((__u16)((8 + 8 * btree->n_used_nodes))) ? ((__u16)( (((__u16)((8 + 8 * btree->n_used_nodes)) & (__u16)0x00ffU) << 8) | (((__u16)((8 + 8 * btree->n_used_nodes)) & (__u16)0xff00U) >> 8))) : __fswab16((8 + 8 * btree->n_used_nodes))));
+ }


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