This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix (half of) PR38932
- From: Paolo Bonzini <bonzini at gnu dot org>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 22 Jan 2009 13:14:31 +0100
- Subject: [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 ();
}