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 (half of) PR38932


This patch fixes the submitter's test case and the attached minimal test
case.  The other test case in the audit trail is not fixed.  Ok?  Should
I create a separate bug?  Should I commit the failing test case too
(without xfail)?

Paolo
2008-01-22  Paolo Bonzini  <bonzini@gnu.org>

	PR tree-optimization/38932
	* fold-const.c (fold_unary_no_overflow): New.
	* tree.h (fold_unary_no_overflow): Declare.
	* tree-ssa-ccp.c (ccp_fold): Use fold_unary_no_overflow.
	* tree-ssa-sccvn.c (visit_reference_op_load,
	simplify_unary_expression): Likewise.

2008-01-22  Paolo Bonzini  <bonzini@gnu.org>

	PR tree-optimization/38932
	* gcc.dg/pr38932-1.c: New.

Index: tree-ssa-ccp.c
===================================================================
--- tree-ssa-ccp.c	(revision 143512)
+++ tree-ssa-ccp.c	(working copy)
@@ -1002,18 +1002,7 @@ ccp_fold (gimple stmt)
 		  return op0;
 		}
 
-              res = fold_unary (subcode, gimple_expr_type (stmt), op0);
-
-	      /* If the operation was a conversion do _not_ mark a
-	         resulting constant with TREE_OVERFLOW if the original
-		 constant was not.  These conversions have implementation
-		 defined behavior and retaining the TREE_OVERFLOW flag
-		 here would confuse later passes such as VRP.  */
-	      if (res
-		  && TREE_CODE (res) == INTEGER_CST
-		  && TREE_CODE (op0) == INTEGER_CST
-		  && CONVERT_EXPR_CODE_P (subcode))
-		TREE_OVERFLOW (res) = TREE_OVERFLOW (op0);
+              res = fold_unary_no_overflow (subcode, gimple_expr_type (stmt), op0);
 
 	      return res;
             }
Index: tree-ssa-sccvn.c
===================================================================
--- tree-ssa-sccvn.c	(revision 143512)
+++ tree-ssa-sccvn.c	(working copy)
@@ -1761,7 +1761,8 @@ visit_reference_op_load (tree lhs, tree 
 	  tree tem = valueize_expr (vn_get_expr_for (TREE_OPERAND (val, 0)));
 	  if ((CONVERT_EXPR_P (tem)
 	       || TREE_CODE (tem) == VIEW_CONVERT_EXPR)
-	      && (tem = fold_unary (TREE_CODE (val), TREE_TYPE (val), tem)))
+	      && (tem = fold_unary_no_overflow (TREE_CODE (val),
+						TREE_TYPE (val), tem)))
 	    val = tem;
 	}
       result = val;
@@ -2182,8 +2183,8 @@ simplify_unary_expression (gimple stmt)
   if (op0 == orig_op0)
     return NULL_TREE;
 
-  result = fold_unary (gimple_assign_rhs_code (stmt),
-		       gimple_expr_type (stmt), op0);
+  result = fold_unary_no_overflow (gimple_assign_rhs_code (stmt),
+				   gimple_expr_type (stmt), op0);
   if (result)
     {
       STRIP_USELESS_TYPE_CONVERSION (result);
Index: fold-const.c
===================================================================
--- fold-const.c	(revision 143512)
+++ fold-const.c	(working copy)
@@ -8628,6 +8628,24 @@ fold_unary (enum tree_code code, tree ty
     } /* switch (code) */
 }
 
+
+/* If the operation was a conversion do _not_ mark a resulting constant
+   with TREE_OVERFLOW if the original constant was not.  These conversions
+   have implementation defined behavior and retaining the TREE_OVERFLOW
+   flag here would confuse later passes such as VRP.  */
+tree
+fold_unary_no_overflow (enum tree_code code, tree type, tree op0)
+{
+  tree res = fold_unary (code, type, op0);
+  if (res
+      && TREE_CODE (res) == INTEGER_CST
+      && TREE_CODE (op0) == INTEGER_CST
+      && CONVERT_EXPR_CODE_P (code))
+    TREE_OVERFLOW (res) = TREE_OVERFLOW (op0);
+
+  return res;
+}
+
 /* Fold a binary expression of code CODE and type TYPE with operands
    OP0 and OP1, containing either a MIN-MAX or a MAX-MIN combination.
    Return the folded expression if folding is successful.  Otherwise,
Index: tree.h
===================================================================
--- tree.h	(revision 143512)
+++ tree.h	(working copy)
@@ -4733,6 +4733,7 @@ extern tree native_interpret_expr (tree,
 
 extern tree fold (tree);
 extern tree fold_unary (enum tree_code, tree, tree);
+extern tree fold_unary_no_overflow (enum tree_code, tree, tree);
 extern tree fold_binary (enum tree_code, tree, tree, tree);
 extern tree fold_ternary (enum tree_code, tree, tree, tree, tree);
 extern tree fold_build1_stat (enum tree_code, tree, tree MEM_STAT_DECL);



/* { dg-do compile } */
/* { dg-options "-O2" } */

/* This variable needed only to exercise FRE instead of CCP.  */
unsigned char g;

extern void abort();

void f (long long int p)
{
  g = 255;
  if (p >= (-9223372036854775807LL - 1) - (signed char) g)
    p = 1;

  if (p)
    abort ();
}



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