Commit 0c948c27 by Ian Lance Taylor Committed by Ian Lance Taylor

tree-vrp.c: Include "intl.h".

./:	* tree-vrp.c: Include "intl.h".
	(usable_range_p): New static function.
	(compare_values_warnv): Don't test TYPE_OVERFLOW_UNDEFINED for
	overflowed values, juts set *strict_overflow_p.
	(compare_values): Only return -2 if one of the operands is not a
	constant.
	(compare_ranges): Call usable_range_p.
	(compare_range_with_value): Likewise.
	(vrp_evaluate_conditional_warnv): Rename from
	vrp_evaluate_conditional.  Make static.  Change all callers.
	(vrp_evaluate_conditional): New function.
	(simplify_div_or_mod_using_ranges): Issue warning about reliance
	on signed overflow.
	(simplify_abs_using_ranges): Likewise.
	(simplify_stmt_for_jump_threading): Add within_stmt parameter.
	* tree-ssa-dom.c (simplify_stmt_for_jump_threading): Add
	within_stmt parameter.
	* tree-ssa-propagate.c (fold_predicate_in): Update call to
	vrp_evaluate_conditional.
	* tree-ssa-threadedge.c
	(record_temporary_equivalences_from_stmts_at_dest): Change
	simplify parameter to take a second tree parameter.
	(simplify_control_stmt_condition): Likewise.
	(thread_across_edge): Likewise.
	* tree-flow.h (vrp_evaluate_conditional): Update declaration.
	(thread_across_edge): Likewise.
	* gcc/Makefile.in (tree-vrp.o): Depend upon intl.h.
testsuite/:
	* gcc.dg/no-strict-overflow-5.c: New test.
	* gcc.dg/no-strict-overflow-6.c: New test.
	* gcc.dg/Wstrict-overflow-11.c: New test.
	* gcc.dg/Wstrict-overflow-12.c: New test.
	* gcc.dg/Wstrict-overflow-13.c: New test.
	* gcc.dg/Wstrict-overflow-14.c: New test.
	* gcc.dg/Wstrict-overflow-15.c: New test.

From-SVN: r122706
parent 3c2d980c
2007-03-08 Ian Lance Taylor <iant@google.com>
* tree-vrp.c: Include "intl.h".
(usable_range_p): New static function.
(compare_values_warnv): Don't test TYPE_OVERFLOW_UNDEFINED for
overflowed values, juts set *strict_overflow_p.
(compare_values): Only return -2 if one of the operands is not a
constant.
(compare_ranges): Call usable_range_p.
(compare_range_with_value): Likewise.
(vrp_evaluate_conditional_warnv): Rename from
vrp_evaluate_conditional. Make static. Change all callers.
(vrp_evaluate_conditional): New function.
(simplify_div_or_mod_using_ranges): Issue warning about reliance
on signed overflow.
(simplify_abs_using_ranges): Likewise.
(simplify_stmt_for_jump_threading): Add within_stmt parameter.
* tree-ssa-dom.c (simplify_stmt_for_jump_threading): Add
within_stmt parameter.
* tree-ssa-propagate.c (fold_predicate_in): Update call to
vrp_evaluate_conditional.
* tree-ssa-threadedge.c
(record_temporary_equivalences_from_stmts_at_dest): Change
simplify parameter to take a second tree parameter.
(simplify_control_stmt_condition): Likewise.
(thread_across_edge): Likewise.
* tree-flow.h (vrp_evaluate_conditional): Update declaration.
(thread_across_edge): Likewise.
* gcc/Makefile.in (tree-vrp.o): Depend upon intl.h.
2007-03-08 Uros Bizjak <ubizjak@gmail.com> 2007-03-08 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.h (TARGET_SAHF): New define. * config/i386/i386.h (TARGET_SAHF): New define.
......
...@@ -2044,7 +2044,7 @@ tree-vn.o : tree-vn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \ ...@@ -2044,7 +2044,7 @@ tree-vn.o : tree-vn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \
tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ tree-vrp.o : tree-vrp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(GGC_H) \ $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(GGC_H) \
$(BASIC_BLOCK_H) tree-ssa-propagate.h $(FLAGS_H) $(TREE_DUMP_H) \ $(BASIC_BLOCK_H) tree-ssa-propagate.h $(FLAGS_H) $(TREE_DUMP_H) \
$(CFGLOOP_H) $(SCEV_H) tree-chrec.h $(TIMEVAR_H) toplev.h $(CFGLOOP_H) $(SCEV_H) tree-chrec.h $(TIMEVAR_H) toplev.h intl.h
tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ tree-cfg.o : tree-cfg.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) $(FLAGS_H) output.h \
$(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \ $(DIAGNOSTIC_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
......
2007-03-08 Ian Lance Taylor <iant@google.com>
* gcc.dg/no-strict-overflow-5.c: New test.
* gcc.dg/no-strict-overflow-6.c: New test.
* gcc.dg/Wstrict-overflow-11.c: New test.
* gcc.dg/Wstrict-overflow-12.c: New test.
* gcc.dg/Wstrict-overflow-13.c: New test.
* gcc.dg/Wstrict-overflow-14.c: New test.
* gcc.dg/Wstrict-overflow-15.c: New test.
2007-03-08 Richard Sandiford <richard@codesourcery.com> 2007-03-08 Richard Sandiford <richard@codesourcery.com>
* gcc.c-torture/execute/strcmp-1.x: New file. XFAIL execution * gcc.c-torture/execute/strcmp-1.x: New file. XFAIL execution
/* { dg-do compile } */
/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow=1" } */
/* Based on strict-overflow-5.c. */
/* We can only unroll when using strict overflow semantics. */
int foo (int i)
{
int index;
int r=0;
for (index = i; index <= i+4; index+=2) /* { dg-warning "assuming signed overflow does not occur" "correct warning" } */
r++;
return r;
}
/* { dg-do compile } */
/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow=2" } */
/* Source: Ian Lance Taylor. Dual of no-strict-overflow-6.c. */
/* VRP test. This turns into an infinite loop when using strict
overflow semantics. */
int
foo ()
{
int i, bits;
for (i = 1, bits = 1; i > 0; i += i) /* { dg-warning "assuming signed overflow does not occur" "correct warning" } */
++bits;
return bits;
}
/* { dg-do compile } */
/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow=2" } */
/* Source: Ian Lance Taylor. Dual of no-strict-overflow-6.c. */
/* VRP test. This turns into an infinite loop (depending on what
bigtime_test does), but at least we warn about it. */
extern int bigtime_test (int);
int
foo ()
{
int j;
for (j = 1; 0 < j; j *= 2) /* { dg-warning "assuming signed overflow does not occur" "correct warning" } */
if (! bigtime_test (j))
return 1;
return 0;
}
/* { dg-do compile } */
/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow=4" } */
/* Source: Ian Lance Taylor. */
int
foo (int j)
{
int i;
int sum = 0;
for (i = 1; i < j; i += i)
sum += i / 16; /* { dg-warning "assuming signed overflow does not occur" "" } */
return sum;
}
/* { dg-do compile } */
/* { dg-options "-fstrict-overflow -O2 -Wstrict-overflow=4" } */
/* Source: Ian Lance Taylor. */
int
foo (int j)
{
int i;
int sum = 0;
for (i = 1; i < j; i += i)
sum += __builtin_abs (i); /* { dg-warning "assuming signed overflow does not occur" "" } */
return sum;
}
/* { dg-do compile } */
/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */
/* Dual of strict-overflow-5.c. */
/* We can only unroll when using strict overflow semantics. */
int foo (int i)
{
int index;
int r=0;
for (index = i; index <= i+4; index+=2)
r++;
return r;
}
/* { dg-final { scan-tree-dump-times "r = 3" 0 "final_cleanup" } } */
/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
/* { dg-do compile } */
/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */
/* Source: Ian Lance Taylor. */
/* VRP test. We can not simplify the conditional when not using
strict overflow semantics. We don't test this with
-fstrict-overflow because it turns into an infinite loop. That is
OK but it would also be OK to not do that. */
int
foo ()
{
int i, bits;
for (i = 1, bits = 1; i > 0; i += i)
++bits;
return bits;
}
/* { dg-final { scan-tree-dump "return bits" "final_cleanup" } } */
/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
...@@ -776,7 +776,7 @@ bool fold_stmt_inplace (tree); ...@@ -776,7 +776,7 @@ bool fold_stmt_inplace (tree);
tree widen_bitfield (tree, tree, tree); tree widen_bitfield (tree, tree, tree);
/* In tree-vrp.c */ /* In tree-vrp.c */
tree vrp_evaluate_conditional (tree, bool, bool *); tree vrp_evaluate_conditional (tree, tree);
void simplify_stmt_using_ranges (tree); void simplify_stmt_using_ranges (tree);
/* In tree-ssa-dom.c */ /* In tree-ssa-dom.c */
...@@ -910,7 +910,7 @@ bool contains_abnormal_ssa_name_p (tree); ...@@ -910,7 +910,7 @@ bool contains_abnormal_ssa_name_p (tree);
/* In tree-ssa-threadedge.c */ /* In tree-ssa-threadedge.c */
extern bool potentially_threadable_block (basic_block); extern bool potentially_threadable_block (basic_block);
extern void thread_across_edge (tree, edge, bool, extern void thread_across_edge (tree, edge, bool,
VEC(tree, heap) **, tree (*) (tree)); VEC(tree, heap) **, tree (*) (tree, tree));
/* In tree-ssa-loop-im.c */ /* In tree-ssa-loop-im.c */
/* The possibilities of statement movement. */ /* The possibilities of statement movement. */
......
...@@ -554,7 +554,7 @@ restore_vars_to_original_value (void) ...@@ -554,7 +554,7 @@ restore_vars_to_original_value (void)
/* A trivial wrapper so that we can present the generic jump /* A trivial wrapper so that we can present the generic jump
threading code with a simple API for simplifying statements. */ threading code with a simple API for simplifying statements. */
static tree static tree
simplify_stmt_for_jump_threading (tree stmt) simplify_stmt_for_jump_threading (tree stmt, tree within_stmt ATTRIBUTE_UNUSED)
{ {
return lookup_avail_expr (stmt, false); return lookup_avail_expr (stmt, false);
} }
......
...@@ -1100,7 +1100,6 @@ fold_predicate_in (tree stmt) ...@@ -1100,7 +1100,6 @@ fold_predicate_in (tree stmt)
tree *pred_p = NULL; tree *pred_p = NULL;
bool modify_stmt_p = false; bool modify_stmt_p = false;
tree val; tree val;
bool sop;
if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
&& COMPARISON_CLASS_P (GIMPLE_STMT_OPERAND (stmt, 1))) && COMPARISON_CLASS_P (GIMPLE_STMT_OPERAND (stmt, 1)))
...@@ -1113,8 +1112,7 @@ fold_predicate_in (tree stmt) ...@@ -1113,8 +1112,7 @@ fold_predicate_in (tree stmt)
else else
return false; return false;
sop = false; val = vrp_evaluate_conditional (*pred_p, stmt);
val = vrp_evaluate_conditional (*pred_p, true, &sop);
if (val) if (val)
{ {
if (modify_stmt_p) if (modify_stmt_p)
......
...@@ -211,7 +211,8 @@ record_temporary_equivalences_from_phis (edge e, VEC(tree, heap) **stack) ...@@ -211,7 +211,8 @@ record_temporary_equivalences_from_phis (edge e, VEC(tree, heap) **stack)
static tree static tree
record_temporary_equivalences_from_stmts_at_dest (edge e, record_temporary_equivalences_from_stmts_at_dest (edge e,
VEC(tree, heap) **stack, VEC(tree, heap) **stack,
tree (*simplify) (tree)) tree (*simplify) (tree,
tree))
{ {
block_stmt_iterator bsi; block_stmt_iterator bsi;
tree stmt = NULL; tree stmt = NULL;
...@@ -315,7 +316,7 @@ record_temporary_equivalences_from_stmts_at_dest (edge e, ...@@ -315,7 +316,7 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
cached_lhs = fold (pre_fold_expr); cached_lhs = fold (pre_fold_expr);
if (TREE_CODE (cached_lhs) != SSA_NAME if (TREE_CODE (cached_lhs) != SSA_NAME
&& !is_gimple_min_invariant (cached_lhs)) && !is_gimple_min_invariant (cached_lhs))
cached_lhs = (*simplify) (stmt); cached_lhs = (*simplify) (stmt, stmt);
} }
/* Restore the statement's original uses/defs. */ /* Restore the statement's original uses/defs. */
...@@ -353,7 +354,7 @@ static tree ...@@ -353,7 +354,7 @@ static tree
simplify_control_stmt_condition (edge e, simplify_control_stmt_condition (edge e,
tree stmt, tree stmt,
tree dummy_cond, tree dummy_cond,
tree (*simplify) (tree), tree (*simplify) (tree, tree),
bool handle_dominating_asserts) bool handle_dominating_asserts)
{ {
tree cond, cached_lhs; tree cond, cached_lhs;
...@@ -439,7 +440,7 @@ simplify_control_stmt_condition (edge e, ...@@ -439,7 +440,7 @@ simplify_control_stmt_condition (edge e,
/* If we have not simplified the condition down to an invariant, /* If we have not simplified the condition down to an invariant,
then use the pass specific callback to simplify the condition. */ then use the pass specific callback to simplify the condition. */
if (! is_gimple_min_invariant (cached_lhs)) if (! is_gimple_min_invariant (cached_lhs))
cached_lhs = (*simplify) (dummy_cond); cached_lhs = (*simplify) (dummy_cond, stmt);
} }
/* We can have conditionals which just test the state of a variable /* We can have conditionals which just test the state of a variable
...@@ -466,7 +467,7 @@ simplify_control_stmt_condition (edge e, ...@@ -466,7 +467,7 @@ simplify_control_stmt_condition (edge e,
/* If we haven't simplified to an invariant yet, then use the /* If we haven't simplified to an invariant yet, then use the
pass specific callback to try and simplify it further. */ pass specific callback to try and simplify it further. */
if (cached_lhs && ! is_gimple_min_invariant (cached_lhs)) if (cached_lhs && ! is_gimple_min_invariant (cached_lhs))
cached_lhs = (*simplify) (stmt); cached_lhs = (*simplify) (stmt, stmt);
} }
else else
cached_lhs = NULL; cached_lhs = NULL;
...@@ -494,7 +495,7 @@ thread_across_edge (tree dummy_cond, ...@@ -494,7 +495,7 @@ thread_across_edge (tree dummy_cond,
edge e, edge e,
bool handle_dominating_asserts, bool handle_dominating_asserts,
VEC(tree, heap) **stack, VEC(tree, heap) **stack,
tree (*simplify) (tree)) tree (*simplify) (tree, tree))
{ {
tree stmt; tree stmt;
......
...@@ -33,6 +33,7 @@ Boston, MA 02110-1301, USA. */ ...@@ -33,6 +33,7 @@ Boston, MA 02110-1301, USA. */
#include "timevar.h" #include "timevar.h"
#include "diagnostic.h" #include "diagnostic.h"
#include "toplev.h" #include "toplev.h"
#include "intl.h"
#include "cfgloop.h" #include "cfgloop.h"
#include "tree-scalar-evolution.h" #include "tree-scalar-evolution.h"
#include "tree-ssa-propagate.h" #include "tree-ssa-propagate.h"
...@@ -46,6 +47,7 @@ static sbitmap found_in_subgraph; ...@@ -46,6 +47,7 @@ static sbitmap found_in_subgraph;
static int compare_values (tree val1, tree val2); static int compare_values (tree val1, tree val2);
static int compare_values_warnv (tree val1, tree val2, bool *); static int compare_values_warnv (tree val1, tree val2, bool *);
static void vrp_meet (value_range_t *, value_range_t *); static void vrp_meet (value_range_t *, value_range_t *);
static tree vrp_evaluate_conditional_warnv (tree, bool, bool *);
/* Location information for ASSERT_EXPRs. Each instance of this /* Location information for ASSERT_EXPRs. Each instance of this
structure describes an ASSERT_EXPR for an SSA name. Since a single structure describes an ASSERT_EXPR for an SSA name. Since a single
...@@ -543,6 +545,32 @@ overflow_infinity_range_p (value_range_t *vr) ...@@ -543,6 +545,32 @@ overflow_infinity_range_p (value_range_t *vr)
|| is_overflow_infinity (vr->max))); || is_overflow_infinity (vr->max)));
} }
/* Return false if we can not make a valid comparison based on VR;
this will be the case if it uses an overflow infinity and overflow
is not undefined (i.e., -fno-strict-overflow is in effect).
Otherwise return true, and set *STRICT_OVERFLOW_P to true if VR
uses an overflow infinity. */
static bool
usable_range_p (value_range_t *vr, bool *strict_overflow_p)
{
gcc_assert (vr->type == VR_RANGE);
if (is_overflow_infinity (vr->min))
{
*strict_overflow_p = true;
if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->min)))
return false;
}
if (is_overflow_infinity (vr->max))
{
*strict_overflow_p = true;
if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->max)))
return false;
}
return true;
}
/* Like tree_expr_nonnegative_warnv_p, but this function uses value /* Like tree_expr_nonnegative_warnv_p, but this function uses value
ranges obtained so far. */ ranges obtained so far. */
...@@ -783,9 +811,8 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p) ...@@ -783,9 +811,8 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
infinities. */ infinities. */
if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2)) if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2))
{ {
if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1))) if (strict_overflow_p != NULL)
return -2; *strict_overflow_p = true;
if (is_negative_overflow_infinity (val1)) if (is_negative_overflow_infinity (val1))
return is_negative_overflow_infinity (val2) ? 0 : -1; return is_negative_overflow_infinity (val2) ? 0 : -1;
else if (is_negative_overflow_infinity (val2)) else if (is_negative_overflow_infinity (val2))
...@@ -831,8 +858,8 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p) ...@@ -831,8 +858,8 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
} }
} }
/* Compare values like compare_values_warnv, but treat comparisons /* Compare values like compare_values_warnv, but treat comparisons of
which rely on undefined overflow as incomparable. */ nonconstants which rely on undefined overflow as incomparable. */
static int static int
compare_values (tree val1, tree val2) compare_values (tree val1, tree val2)
...@@ -842,7 +869,8 @@ compare_values (tree val1, tree val2) ...@@ -842,7 +869,8 @@ compare_values (tree val1, tree val2)
sop = false; sop = false;
ret = compare_values_warnv (val1, val2, &sop); ret = compare_values_warnv (val1, val2, &sop);
if (sop) if (sop
&& (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2)))
ret = -2; ret = -2;
return ret; return ret;
} }
...@@ -2359,7 +2387,7 @@ static void ...@@ -2359,7 +2387,7 @@ static void
extract_range_from_comparison (value_range_t *vr, tree expr) extract_range_from_comparison (value_range_t *vr, tree expr)
{ {
bool sop = false; bool sop = false;
tree val = vrp_evaluate_conditional (expr, false, &sop); tree val = vrp_evaluate_conditional_warnv (expr, false, &sop);
/* A disadvantage of using a special infinity as an overflow /* A disadvantage of using a special infinity as an overflow
representation is that we lose the ability to record overflow representation is that we lose the ability to record overflow
...@@ -2604,6 +2632,10 @@ compare_ranges (enum tree_code comp, value_range_t *vr0, value_range_t *vr1, ...@@ -2604,6 +2632,10 @@ compare_ranges (enum tree_code comp, value_range_t *vr0, value_range_t *vr1,
return NULL_TREE; return NULL_TREE;
} }
if (!usable_range_p (vr0, strict_overflow_p)
|| !usable_range_p (vr1, strict_overflow_p))
return NULL_TREE;
/* Simplify processing. If COMP is GT_EXPR or GE_EXPR, switch the /* Simplify processing. If COMP is GT_EXPR or GE_EXPR, switch the
operands around and change the comparison code. */ operands around and change the comparison code. */
if (comp == GT_EXPR || comp == GE_EXPR) if (comp == GT_EXPR || comp == GE_EXPR)
...@@ -2737,6 +2769,9 @@ compare_range_with_value (enum tree_code comp, value_range_t *vr, tree val, ...@@ -2737,6 +2769,9 @@ compare_range_with_value (enum tree_code comp, value_range_t *vr, tree val,
return NULL_TREE; return NULL_TREE;
} }
if (!usable_range_p (vr, strict_overflow_p))
return NULL_TREE;
if (comp == EQ_EXPR) if (comp == EQ_EXPR)
{ {
/* EQ_EXPR may only be computed if VR represents exactly /* EQ_EXPR may only be computed if VR represents exactly
...@@ -4531,8 +4566,9 @@ compare_names (enum tree_code comp, tree n1, tree n2, ...@@ -4531,8 +4566,9 @@ compare_names (enum tree_code comp, tree n1, tree n2,
Set *STRICT_OVERFLOW_P to indicate whether we relied on an overflow Set *STRICT_OVERFLOW_P to indicate whether we relied on an overflow
infinity to produce the result. */ infinity to produce the result. */
tree static tree
vrp_evaluate_conditional (tree cond, bool use_equiv_p, bool *strict_overflow_p) vrp_evaluate_conditional_warnv (tree cond, bool use_equiv_p,
bool *strict_overflow_p)
{ {
gcc_assert (TREE_CODE (cond) == SSA_NAME gcc_assert (TREE_CODE (cond) == SSA_NAME
|| TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison); || TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison);
...@@ -4609,6 +4645,55 @@ vrp_evaluate_conditional (tree cond, bool use_equiv_p, bool *strict_overflow_p) ...@@ -4609,6 +4645,55 @@ vrp_evaluate_conditional (tree cond, bool use_equiv_p, bool *strict_overflow_p)
return NULL_TREE; return NULL_TREE;
} }
/* Given COND within STMT, try to simplify it based on value range
information. Return NULL if the conditional can not be evaluated.
The ranges of all the names equivalent with the operands in COND
will be used when trying to compute the value. If the result is
based on undefined signed overflow, issue a warning if
appropriate. */
tree
vrp_evaluate_conditional (tree cond, tree stmt)
{
bool sop;
tree ret;
sop = false;
ret = vrp_evaluate_conditional_warnv (cond, true, &sop);
if (ret && sop)
{
enum warn_strict_overflow_code wc;
const char* warnmsg;
if (is_gimple_min_invariant (ret))
{
wc = WARN_STRICT_OVERFLOW_CONDITIONAL;
warnmsg = G_("assuming signed overflow does not occur when "
"simplifying conditional to constant");
}
else
{
wc = WARN_STRICT_OVERFLOW_COMPARISON;
warnmsg = G_("assuming signed overflow does not occur when "
"simplifying conditional");
}
if (issue_strict_overflow_warning (wc))
{
location_t locus;
if (!EXPR_HAS_LOCATION (stmt))
locus = input_location;
else
locus = EXPR_LOCATION (stmt);
warning (OPT_Wstrict_overflow, "%H%s", &locus, warnmsg);
}
}
return ret;
}
/* Visit conditional statement STMT. If we can determine which edge /* Visit conditional statement STMT. If we can determine which edge
will be taken out of STMT's basic block, record it in will be taken out of STMT's basic block, record it in
...@@ -4693,7 +4778,7 @@ vrp_visit_cond_stmt (tree stmt, edge *taken_edge_p) ...@@ -4693,7 +4778,7 @@ vrp_visit_cond_stmt (tree stmt, edge *taken_edge_p)
MICO, TRAMP3D and SPEC2000) showed that doing this results in MICO, TRAMP3D and SPEC2000) showed that doing this results in
4 more predicates folded in SPEC. */ 4 more predicates folded in SPEC. */
sop = false; sop = false;
val = vrp_evaluate_conditional (cond, false, &sop); val = vrp_evaluate_conditional_warnv (cond, false, &sop);
if (val) if (val)
{ {
if (!sop) if (!sop)
...@@ -5071,6 +5156,23 @@ simplify_div_or_mod_using_ranges (tree stmt, tree rhs, enum tree_code rhs_code) ...@@ -5071,6 +5156,23 @@ simplify_div_or_mod_using_ranges (tree stmt, tree rhs, enum tree_code rhs_code)
bool sop = false; bool sop = false;
val = compare_range_with_value (GT_EXPR, vr, integer_zero_node, &sop); val = compare_range_with_value (GT_EXPR, vr, integer_zero_node, &sop);
if (val
&& sop
&& integer_onep (val)
&& issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
{
location_t locus;
if (!EXPR_HAS_LOCATION (stmt))
locus = input_location;
else
locus = EXPR_LOCATION (stmt);
warning (OPT_Wstrict_overflow,
("%Hassuming signed overflow does not occur when "
"simplifying / or %% to >> or &"),
&locus);
}
} }
if (val && integer_onep (val)) if (val && integer_onep (val))
...@@ -5138,6 +5240,20 @@ simplify_abs_using_ranges (tree stmt, tree rhs) ...@@ -5138,6 +5240,20 @@ simplify_abs_using_ranges (tree stmt, tree rhs)
{ {
tree t; tree t;
if (sop && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
{
location_t locus;
if (!EXPR_HAS_LOCATION (stmt))
locus = input_location;
else
locus = EXPR_LOCATION (stmt);
warning (OPT_Wstrict_overflow,
("%Hassuming signed overflow does not occur when "
"simplifying abs (X) to X or -X"),
&locus);
}
if (integer_onep (val)) if (integer_onep (val))
t = build1 (NEGATE_EXPR, TREE_TYPE (op), op); t = build1 (NEGATE_EXPR, TREE_TYPE (op), op);
else else
...@@ -5330,21 +5446,21 @@ simplify_stmt_using_ranges (tree stmt) ...@@ -5330,21 +5446,21 @@ simplify_stmt_using_ranges (tree stmt)
restored. */ restored. */
static VEC(tree,heap) *stack; static VEC(tree,heap) *stack;
/* A trivial wrapper so that we can present the generic jump /* A trivial wrapper so that we can present the generic jump threading
threading code with a simple API for simplifying statements. */ code with a simple API for simplifying statements. STMT is the
statement we want to simplify, WITHIN_STMT provides the location
for any overflow warnings. */
static tree static tree
simplify_stmt_for_jump_threading (tree stmt) simplify_stmt_for_jump_threading (tree stmt, tree within_stmt)
{ {
bool sop;
/* We only use VRP information to simplify conditionals. This is /* We only use VRP information to simplify conditionals. This is
overly conservative, but it's unclear if doing more would be overly conservative, but it's unclear if doing more would be
worth the compile time cost. */ worth the compile time cost. */
if (TREE_CODE (stmt) != COND_EXPR) if (TREE_CODE (stmt) != COND_EXPR)
return NULL; return NULL;
sop = false; return vrp_evaluate_conditional (COND_EXPR_COND (stmt), within_stmt);
return vrp_evaluate_conditional (COND_EXPR_COND (stmt), true, &sop);
} }
/* Blocks which have more than one predecessor and more than /* Blocks which have more than one predecessor and more than
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment