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 PR53676


This fixes PR53676, extending SCEV analysis to analyze truncated
operations by analyzing the operation on truncated operands instead.

Bootstrapped and tested on x86_64-unknown-linux-gnu, I plan to
install this tomorrow.

Richard.

2012-06-26  Richard Guenther  <rguenther@suse.de>

	PR middle-end/53676
	* tree-chrec.c (chrec_convert_1): Represent truncation to
	a type with undefined overflow as truncation to an unsigned
	type converted to the type with undefined overflow.
	* tree-scalar-evolution.c (interpret_rhs_expr): For computing
	the scalar evolution of a truncated widened operation avoid
	looking at the non-existing evolution of the widened operation
	result.

	* gcc.dg/tree-ssa/scev-6.c: New testcase.

Index: gcc/tree-chrec.c
===================================================================
*** gcc/tree-chrec.c	(revision 188927)
--- gcc/tree-chrec.c	(working copy)
*************** keep_cast:
*** 1365,1370 ****
--- 1365,1387 ----
      res = fold_build2 (TREE_CODE (chrec), type,
  		       fold_convert (type, TREE_OPERAND (chrec, 0)),
  		       fold_convert (type, TREE_OPERAND (chrec, 1)));
+   /* Similar perform the trick that (signed char)((int)x + 2) can be
+      narrowed to (signed char)((unsigned char)x + 2).  */
+   else if (use_overflow_semantics
+ 	   && TREE_CODE (chrec) == POLYNOMIAL_CHREC
+ 	   && TREE_CODE (ct) == INTEGER_TYPE
+ 	   && TREE_CODE (type) == INTEGER_TYPE
+ 	   && TYPE_OVERFLOW_UNDEFINED (type)
+ 	   && TYPE_PRECISION (type) < TYPE_PRECISION (ct))
+     {
+       tree utype = unsigned_type_for (type);
+       res = build_polynomial_chrec (CHREC_VARIABLE (chrec),
+ 				    fold_convert (utype,
+ 						  CHREC_LEFT (chrec)),
+ 				    fold_convert (utype,
+ 						  CHREC_RIGHT (chrec)));
+       res = chrec_convert_1 (type, res, at_stmt, use_overflow_semantics);
+     }
    else
      res = fold_convert (type, chrec);
  
Index: gcc/tree-scalar-evolution.c
===================================================================
*** gcc/tree-scalar-evolution.c	(revision 188927)
--- gcc/tree-scalar-evolution.c	(working copy)
*************** interpret_rhs_expr (struct loop *loop, g
*** 1634,1639 ****
--- 1634,1640 ----
  		    tree type, tree rhs1, enum tree_code code, tree rhs2)
  {
    tree res, chrec1, chrec2;
+   gimple def;
  
    if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
      {
*************** interpret_rhs_expr (struct loop *loop, g
*** 1759,1765 ****
        break;
  
      CASE_CONVERT:
!       chrec1 = analyze_scalar_evolution (loop, rhs1);
        res = chrec_convert (type, chrec1, at_stmt);
        break;
  
--- 1760,1788 ----
        break;
  
      CASE_CONVERT:
!       /* In case we have a truncation of a widened operation that in
!          the truncated type has undefined overflow behavior analyze
! 	 the operation done in an unsigned type of the same precision
! 	 as the final truncation.  We cannot derive a scalar evolution
! 	 for the widened operation but for the truncated result.  */
!       if (TREE_CODE (type) == INTEGER_TYPE
! 	  && TREE_CODE (TREE_TYPE (rhs1)) == INTEGER_TYPE
! 	  && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (rhs1))
! 	  && TYPE_OVERFLOW_UNDEFINED (type)
! 	  && TREE_CODE (rhs1) == SSA_NAME
! 	  && (def = SSA_NAME_DEF_STMT (rhs1))
! 	  && is_gimple_assign (def)
! 	  && TREE_CODE_CLASS (gimple_assign_rhs_code (def)) == tcc_binary
! 	  && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
! 	{
! 	  tree utype = unsigned_type_for (type);
! 	  chrec1 = interpret_rhs_expr (loop, at_stmt, utype,
! 				       gimple_assign_rhs1 (def),
! 				       gimple_assign_rhs_code (def),
! 				       gimple_assign_rhs2 (def));
! 	}
!       else
! 	chrec1 = analyze_scalar_evolution (loop, rhs1);
        res = chrec_convert (type, chrec1, at_stmt);
        break;
  
Index: gcc/testsuite/gcc.dg/tree-ssa/scev-6.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/scev-6.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/scev-6.c	(revision 0)
***************
*** 0 ****
--- 1,23 ----
+ /* { dg-do run } */
+ /* { dg-options "-O2 -fdump-tree-optimized" } */
+ 
+ int main()
+ {
+   int i;
+   signed char result = 0;
+   for (i = 0; i != 8000; ++i)
+     {
+       int tem = result;
+       tem = tem + 2;
+       result = tem;
+     }
+   if (__builtin_abs ((int)(signed char)((unsigned char ) result + 128)) != 0)
+     __builtin_abort ();
+   return 0;
+ }
+ 
+ /* SCEV constant propagation should be able to compute the overall effect
+    of the loop.  */
+ 
+ /* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */


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