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
This commit is contained in:
parent
3c2d980c94
commit
0c948c2746
15 changed files with 308 additions and 31 deletions
|
@ -1,3 +1,33 @@
|
|||
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>
|
||||
|
||||
* 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) \
|
|||
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) \
|
||||
$(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) \
|
||||
$(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 \
|
||||
|
|
|
@ -1,3 +1,13 @@
|
|||
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>
|
||||
|
||||
* gcc.c-torture/execute/strcmp-1.x: New file. XFAIL execution
|
||||
|
|
17
gcc/testsuite/gcc.dg/Wstrict-overflow-11.c
Normal file
17
gcc/testsuite/gcc.dg/Wstrict-overflow-11.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* { 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;
|
||||
}
|
16
gcc/testsuite/gcc.dg/Wstrict-overflow-12.c
Normal file
16
gcc/testsuite/gcc.dg/Wstrict-overflow-12.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* { 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;
|
||||
}
|
18
gcc/testsuite/gcc.dg/Wstrict-overflow-13.c
Normal file
18
gcc/testsuite/gcc.dg/Wstrict-overflow-13.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* { 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;
|
||||
}
|
15
gcc/testsuite/gcc.dg/Wstrict-overflow-14.c
Normal file
15
gcc/testsuite/gcc.dg/Wstrict-overflow-14.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* { 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;
|
||||
}
|
15
gcc/testsuite/gcc.dg/Wstrict-overflow-15.c
Normal file
15
gcc/testsuite/gcc.dg/Wstrict-overflow-15.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* { 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;
|
||||
}
|
20
gcc/testsuite/gcc.dg/no-strict-overflow-5.c
Normal file
20
gcc/testsuite/gcc.dg/no-strict-overflow-5.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* { 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" } } */
|
21
gcc/testsuite/gcc.dg/no-strict-overflow-6.c
Normal file
21
gcc/testsuite/gcc.dg/no-strict-overflow-6.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/* { 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);
|
|||
tree widen_bitfield (tree, tree, tree);
|
||||
|
||||
/* In tree-vrp.c */
|
||||
tree vrp_evaluate_conditional (tree, bool, bool *);
|
||||
tree vrp_evaluate_conditional (tree, tree);
|
||||
void simplify_stmt_using_ranges (tree);
|
||||
|
||||
/* In tree-ssa-dom.c */
|
||||
|
@ -910,7 +910,7 @@ bool contains_abnormal_ssa_name_p (tree);
|
|||
/* In tree-ssa-threadedge.c */
|
||||
extern bool potentially_threadable_block (basic_block);
|
||||
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 */
|
||||
/* The possibilities of statement movement. */
|
||||
|
|
|
@ -554,7 +554,7 @@ restore_vars_to_original_value (void)
|
|||
/* A trivial wrapper so that we can present the generic jump
|
||||
threading code with a simple API for simplifying statements. */
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1100,7 +1100,6 @@ fold_predicate_in (tree stmt)
|
|||
tree *pred_p = NULL;
|
||||
bool modify_stmt_p = false;
|
||||
tree val;
|
||||
bool sop;
|
||||
|
||||
if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
|
||||
&& COMPARISON_CLASS_P (GIMPLE_STMT_OPERAND (stmt, 1)))
|
||||
|
@ -1113,8 +1112,7 @@ fold_predicate_in (tree stmt)
|
|||
else
|
||||
return false;
|
||||
|
||||
sop = false;
|
||||
val = vrp_evaluate_conditional (*pred_p, true, &sop);
|
||||
val = vrp_evaluate_conditional (*pred_p, stmt);
|
||||
if (val)
|
||||
{
|
||||
if (modify_stmt_p)
|
||||
|
|
|
@ -211,7 +211,8 @@ record_temporary_equivalences_from_phis (edge e, VEC(tree, heap) **stack)
|
|||
static tree
|
||||
record_temporary_equivalences_from_stmts_at_dest (edge e,
|
||||
VEC(tree, heap) **stack,
|
||||
tree (*simplify) (tree))
|
||||
tree (*simplify) (tree,
|
||||
tree))
|
||||
{
|
||||
block_stmt_iterator bsi;
|
||||
tree stmt = NULL;
|
||||
|
@ -315,7 +316,7 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
|
|||
cached_lhs = fold (pre_fold_expr);
|
||||
if (TREE_CODE (cached_lhs) != SSA_NAME
|
||||
&& !is_gimple_min_invariant (cached_lhs))
|
||||
cached_lhs = (*simplify) (stmt);
|
||||
cached_lhs = (*simplify) (stmt, stmt);
|
||||
}
|
||||
|
||||
/* Restore the statement's original uses/defs. */
|
||||
|
@ -353,7 +354,7 @@ static tree
|
|||
simplify_control_stmt_condition (edge e,
|
||||
tree stmt,
|
||||
tree dummy_cond,
|
||||
tree (*simplify) (tree),
|
||||
tree (*simplify) (tree, tree),
|
||||
bool handle_dominating_asserts)
|
||||
{
|
||||
tree cond, cached_lhs;
|
||||
|
@ -439,7 +440,7 @@ simplify_control_stmt_condition (edge e,
|
|||
/* If we have not simplified the condition down to an invariant,
|
||||
then use the pass specific callback to simplify the condition. */
|
||||
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
|
||||
|
@ -466,7 +467,7 @@ simplify_control_stmt_condition (edge e,
|
|||
/* If we haven't simplified to an invariant yet, then use the
|
||||
pass specific callback to try and simplify it further. */
|
||||
if (cached_lhs && ! is_gimple_min_invariant (cached_lhs))
|
||||
cached_lhs = (*simplify) (stmt);
|
||||
cached_lhs = (*simplify) (stmt, stmt);
|
||||
}
|
||||
else
|
||||
cached_lhs = NULL;
|
||||
|
@ -494,7 +495,7 @@ thread_across_edge (tree dummy_cond,
|
|||
edge e,
|
||||
bool handle_dominating_asserts,
|
||||
VEC(tree, heap) **stack,
|
||||
tree (*simplify) (tree))
|
||||
tree (*simplify) (tree, tree))
|
||||
{
|
||||
tree stmt;
|
||||
|
||||
|
|
152
gcc/tree-vrp.c
152
gcc/tree-vrp.c
|
@ -33,6 +33,7 @@ Boston, MA 02110-1301, USA. */
|
|||
#include "timevar.h"
|
||||
#include "diagnostic.h"
|
||||
#include "toplev.h"
|
||||
#include "intl.h"
|
||||
#include "cfgloop.h"
|
||||
#include "tree-scalar-evolution.h"
|
||||
#include "tree-ssa-propagate.h"
|
||||
|
@ -46,6 +47,7 @@ static sbitmap found_in_subgraph;
|
|||
static int compare_values (tree val1, tree val2);
|
||||
static int compare_values_warnv (tree val1, tree val2, bool *);
|
||||
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
|
||||
structure describes an ASSERT_EXPR for an SSA name. Since a single
|
||||
|
@ -543,6 +545,32 @@ overflow_infinity_range_p (value_range_t *vr)
|
|||
|| 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
|
||||
ranges obtained so far. */
|
||||
|
||||
|
@ -783,9 +811,8 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
|
|||
infinities. */
|
||||
if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2))
|
||||
{
|
||||
if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1)))
|
||||
return -2;
|
||||
|
||||
if (strict_overflow_p != NULL)
|
||||
*strict_overflow_p = true;
|
||||
if (is_negative_overflow_infinity (val1))
|
||||
return is_negative_overflow_infinity (val2) ? 0 : -1;
|
||||
else if (is_negative_overflow_infinity (val2))
|
||||
|
@ -831,8 +858,8 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
|
|||
}
|
||||
}
|
||||
|
||||
/* Compare values like compare_values_warnv, but treat comparisons
|
||||
which rely on undefined overflow as incomparable. */
|
||||
/* Compare values like compare_values_warnv, but treat comparisons of
|
||||
nonconstants which rely on undefined overflow as incomparable. */
|
||||
|
||||
static int
|
||||
compare_values (tree val1, tree val2)
|
||||
|
@ -842,7 +869,8 @@ compare_values (tree val1, tree val2)
|
|||
|
||||
sop = false;
|
||||
ret = compare_values_warnv (val1, val2, &sop);
|
||||
if (sop)
|
||||
if (sop
|
||||
&& (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2)))
|
||||
ret = -2;
|
||||
return ret;
|
||||
}
|
||||
|
@ -2359,7 +2387,7 @@ static void
|
|||
extract_range_from_comparison (value_range_t *vr, tree expr)
|
||||
{
|
||||
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
|
||||
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,
|
|||
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
|
||||
operands around and change the comparison code. */
|
||||
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,
|
|||
return NULL_TREE;
|
||||
}
|
||||
|
||||
if (!usable_range_p (vr, strict_overflow_p))
|
||||
return NULL_TREE;
|
||||
|
||||
if (comp == EQ_EXPR)
|
||||
{
|
||||
/* EQ_EXPR may only be computed if VR represents exactly
|
||||
|
@ -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
|
||||
infinity to produce the result. */
|
||||
|
||||
tree
|
||||
vrp_evaluate_conditional (tree cond, bool use_equiv_p, bool *strict_overflow_p)
|
||||
static tree
|
||||
vrp_evaluate_conditional_warnv (tree cond, bool use_equiv_p,
|
||||
bool *strict_overflow_p)
|
||||
{
|
||||
gcc_assert (TREE_CODE (cond) == SSA_NAME
|
||||
|| 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)
|
|||
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
|
||||
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)
|
|||
MICO, TRAMP3D and SPEC2000) showed that doing this results in
|
||||
4 more predicates folded in SPEC. */
|
||||
sop = false;
|
||||
val = vrp_evaluate_conditional (cond, false, &sop);
|
||||
val = vrp_evaluate_conditional_warnv (cond, false, &sop);
|
||||
if (val)
|
||||
{
|
||||
if (!sop)
|
||||
|
@ -5071,6 +5156,23 @@ simplify_div_or_mod_using_ranges (tree stmt, tree rhs, enum tree_code rhs_code)
|
|||
bool sop = false;
|
||||
|
||||
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))
|
||||
|
@ -5138,6 +5240,20 @@ simplify_abs_using_ranges (tree stmt, tree rhs)
|
|||
{
|
||||
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))
|
||||
t = build1 (NEGATE_EXPR, TREE_TYPE (op), op);
|
||||
else
|
||||
|
@ -5330,21 +5446,21 @@ simplify_stmt_using_ranges (tree stmt)
|
|||
restored. */
|
||||
static VEC(tree,heap) *stack;
|
||||
|
||||
/* A trivial wrapper so that we can present the generic jump
|
||||
threading code with a simple API for simplifying statements. */
|
||||
static tree
|
||||
simplify_stmt_for_jump_threading (tree stmt)
|
||||
{
|
||||
bool sop;
|
||||
/* A trivial wrapper so that we can present the generic jump threading
|
||||
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
|
||||
simplify_stmt_for_jump_threading (tree stmt, tree within_stmt)
|
||||
{
|
||||
/* We only use VRP information to simplify conditionals. This is
|
||||
overly conservative, but it's unclear if doing more would be
|
||||
worth the compile time cost. */
|
||||
if (TREE_CODE (stmt) != COND_EXPR)
|
||||
return NULL;
|
||||
|
||||
sop = false;
|
||||
return vrp_evaluate_conditional (COND_EXPR_COND (stmt), true, &sop);
|
||||
return vrp_evaluate_conditional (COND_EXPR_COND (stmt), within_stmt);
|
||||
}
|
||||
|
||||
/* Blocks which have more than one predecessor and more than
|
||||
|
|
Loading…
Add table
Reference in a new issue