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 PR58742


This implements simple pattern matching for folding of
pointer subtraction GIMPLE IL which is performed in an
integer type.  It handles the simple case, like the
others in associate_plusminus (cases involving cancellation).

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

Richard.

2014-01-28  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/58742
	* tree-ssa-forwprop.c (associate_plusminus): Handle
	pointer subtraction of the form (T)(P + A) - (T)P.

Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c	(revision 207180)
--- gcc/tree-ssa-forwprop.c	(working copy)
*************** associate_plusminus (gimple_stmt_iterato
*** 2543,2548 ****
--- 2543,2549 ----
  	CST +- (CST +- A)  ->  CST +- A
  	CST +- (A +- CST)  ->  CST +- A
  	A + ~A             ->  -1
+ 	(T)(P + A) - (T)P  -> (T)A
  
       via commutating the addition and contracting operations to zero
       by reassociation.  */
*************** associate_plusminus (gimple_stmt_iterato
*** 2646,2651 ****
--- 2647,2701 ----
  		  gimple_set_modified (stmt, true);
  		}
  	    }
+ 	  else if (CONVERT_EXPR_CODE_P (def_code) && code == MINUS_EXPR
+ 		   && TREE_CODE (rhs2) == SSA_NAME)
+ 	    {
+ 	      /* (T)(ptr + adj) - (T)ptr -> (T)adj.  */
+ 	      gimple def_stmt2 = SSA_NAME_DEF_STMT (rhs2);
+ 	      if (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
+ 		  && is_gimple_assign (def_stmt2)
+ 		  && can_propagate_from (def_stmt2)
+ 		  && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt2))
+ 		  && TREE_CODE (gimple_assign_rhs1 (def_stmt2)) == SSA_NAME)
+ 		{
+ 		  /* Now we have (T)A - (T)ptr.  */
+ 		  tree ptr = gimple_assign_rhs1 (def_stmt2);
+ 		  def_stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
+ 		  if (is_gimple_assign (def_stmt2)
+ 		      && gimple_assign_rhs_code (def_stmt2) == POINTER_PLUS_EXPR
+ 		      && gimple_assign_rhs1 (def_stmt2) == ptr)
+ 		    {
+ 		      /* And finally (T)(ptr + X) - (T)ptr.  */
+ 		      tree adj = gimple_assign_rhs2 (def_stmt2);
+ 		      /* If the conversion of the pointer adjustment to the
+ 		         final type requires a sign- or zero-extension we
+ 			 have to punt - it is not defined which one is
+ 			 correct.  */
+ 		      if (TYPE_PRECISION (TREE_TYPE (rhs1))
+ 			  <= TYPE_PRECISION (TREE_TYPE (adj))
+ 			  || (TREE_CODE (adj) == INTEGER_CST
+ 			      && tree_int_cst_sign_bit (adj) == 0))
+ 			{
+ 			  if (useless_type_conversion_p (TREE_TYPE (rhs1),
+ 							 TREE_TYPE (adj)))
+ 			    {
+ 			      code = TREE_CODE (adj);
+ 			      rhs1 = adj;
+ 			    }
+ 			  else
+ 			    {
+ 			      code = NOP_EXPR;
+ 			      rhs1 = adj;
+ 			    }
+ 			  rhs2 = NULL_TREE;
+ 			  gimple_assign_set_rhs_with_ops (gsi, code, rhs1,
+ 							  NULL_TREE);
+ 			  gcc_assert (gsi_stmt (*gsi) == stmt);
+ 			  gimple_set_modified (stmt, true);
+ 			}
+ 		    }
+ 		}
+ 	    }
  	}
      }
  


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