/* Support routines for Value Range Propagation (VRP).
- Copyright (C) 2005-2015 Free Software Foundation, Inc.
+ Copyright (C) 2005-2016 Free Software Foundation, Inc.
Contributed by Diego Novillo <dnovillo@redhat.com>.
This file is part of GCC.
#include "tree-ssa-threadedge.h"
#include "omp-low.h"
#include "target.h"
+#include "case-cfn-macros.h"
/* Range of values that can be associated with an SSA_NAME after VRP
has executed. */
if (vr1.type == VR_RANGE
&& !symbolic_range_p (&vr0)
&& !symbolic_range_p (&vr1)
- && !compare_values (vr1.min, zero))
+ && compare_values (vr1.min, zero) != 0)
max = int_const_binop (code, vr0.max, vr1.min);
else
max = zero;
return;
}
}
- else
+ else if (!symbolic_range_p (&vr0) && !symbolic_range_p (&vr1))
{
extract_range_from_multiplicative_op_1 (vr, code, &vr0, &vr1);
return;
bool sop = false;
tree type = gimple_expr_type (stmt);
- if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
+ if (is_gimple_call (stmt))
{
- tree fndecl = gimple_call_fndecl (stmt), arg;
+ tree arg;
int mini, maxi, zerov = 0, prec;
+ enum tree_code subcode = ERROR_MARK;
+ combined_fn cfn = gimple_call_combined_fn (stmt);
- switch (DECL_FUNCTION_CODE (fndecl))
+ switch (cfn)
{
- case BUILT_IN_CONSTANT_P:
+ case CFN_BUILT_IN_CONSTANT_P:
/* If the call is __builtin_constant_p and the argument is a
function parameter resolve it to false. This avoids bogus
array bound warnings.
break;
/* Both __builtin_ffs* and __builtin_popcount return
[0, prec]. */
- CASE_INT_FN (BUILT_IN_FFS):
- CASE_INT_FN (BUILT_IN_POPCOUNT):
+ CASE_CFN_FFS:
+ CASE_CFN_POPCOUNT:
arg = gimple_call_arg (stmt, 0);
prec = TYPE_PRECISION (TREE_TYPE (arg));
mini = 0;
}
goto bitop_builtin;
/* __builtin_parity* returns [0, 1]. */
- CASE_INT_FN (BUILT_IN_PARITY):
+ CASE_CFN_PARITY:
mini = 0;
maxi = 1;
goto bitop_builtin;
On many targets where the CLZ RTL or optab value is defined
for 0 the value is prec, so include that in the range
by default. */
- CASE_INT_FN (BUILT_IN_CLZ):
+ CASE_CFN_CLZ:
arg = gimple_call_arg (stmt, 0);
prec = TYPE_PRECISION (TREE_TYPE (arg));
mini = 0;
If there is a ctz optab for this mode and
CTZ_DEFINED_VALUE_AT_ZERO, include that in the range,
otherwise just assume 0 won't be seen. */
- CASE_INT_FN (BUILT_IN_CTZ):
+ CASE_CFN_CTZ:
arg = gimple_call_arg (stmt, 0);
prec = TYPE_PRECISION (TREE_TYPE (arg));
mini = 0;
break;
goto bitop_builtin;
/* __builtin_clrsb* returns [0, prec-1]. */
- CASE_INT_FN (BUILT_IN_CLRSB):
+ CASE_CFN_CLRSB:
arg = gimple_call_arg (stmt, 0);
prec = TYPE_PRECISION (TREE_TYPE (arg));
mini = 0;
set_value_range (vr, VR_RANGE, build_int_cst (type, mini),
build_int_cst (type, maxi), NULL);
return;
- default:
- break;
- }
- }
- else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
- {
- enum tree_code subcode = ERROR_MARK;
- unsigned ifn_code = gimple_call_internal_fn (stmt);
-
- switch (ifn_code)
- {
- case IFN_UBSAN_CHECK_ADD:
+ case CFN_UBSAN_CHECK_ADD:
subcode = PLUS_EXPR;
break;
- case IFN_UBSAN_CHECK_SUB:
+ case CFN_UBSAN_CHECK_SUB:
subcode = MINUS_EXPR;
break;
- case IFN_UBSAN_CHECK_MUL:
+ case CFN_UBSAN_CHECK_MUL:
subcode = MULT_EXPR;
break;
- case IFN_GOACC_DIM_SIZE:
- case IFN_GOACC_DIM_POS:
+ case CFN_GOACC_DIM_SIZE:
+ case CFN_GOACC_DIM_POS:
/* Optimizing these two internal functions helps the loop
optimizer eliminate outer comparisons. Size is [1,N]
and pos is [0,N-1]. */
{
- bool is_pos = ifn_code == IFN_GOACC_DIM_POS;
+ bool is_pos = cfn == CFN_GOACC_DIM_POS;
int axis = get_oacc_ifn_dim_arg (stmt);
int size = get_oacc_fn_dim_size (current_function_decl, axis);
&& is_positive_overflow_infinity (max)))
return;
+ /* Even for valid range info, sometimes overflow flag will leak in.
+ As GIMPLE IL should have no constants with TREE_OVERFLOW set, we
+ drop them except for +-overflow_infinity which still need special
+ handling in vrp pass. */
+ if (TREE_OVERFLOW_P (min)
+ && ! is_negative_overflow_infinity (min))
+ min = drop_tree_overflow (min);
+ if (TREE_OVERFLOW_P (max)
+ && ! is_positive_overflow_infinity (max))
+ max = drop_tree_overflow (max);
+
set_value_range (vr, VR_RANGE, min, max, vr->equiv);
}
modulo. */
static bool
-simplify_div_or_mod_using_ranges (gimple *stmt)
+simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
{
enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
tree val = NULL;
}
if (!integer_pow2p (op1))
- return false;
-
- if (TYPE_UNSIGNED (TREE_TYPE (op0)))
{
- val = integer_one_node;
+ /* X % -Y can be only optimized into X % Y either if
+ X is not INT_MIN, or Y is not -1. Fold it now, as after
+ remove_range_assertions the range info might be not available
+ anymore. */
+ if (rhs_code == TRUNC_MOD_EXPR
+ && fold_stmt (gsi, follow_single_use_edges))
+ return true;
+ return false;
}
+
+ if (TYPE_UNSIGNED (TREE_TYPE (op0)))
+ val = integer_one_node;
else
{
bool sop = false;
innerop = gimple_assign_rhs1 (def_stmt);
if (TREE_CODE (innerop) == SSA_NAME
- && !POINTER_TYPE_P (TREE_TYPE (innerop)))
+ && !POINTER_TYPE_P (TREE_TYPE (innerop))
+ && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
+ && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
{
value_range *vr = get_value_range (innerop);
else
location = gimple_location (stmt);
warning_at (location, OPT_Wstrict_overflow,
- "assuming signed overflow does not occur when "
- "simplifying conditional");
+ "assuming signed overflow does not occur when "
+ "simplifying conditional");
}
tree newconst = fold_convert (TREE_TYPE (innerop), op1);
case TRUNC_MOD_EXPR:
if (TREE_CODE (rhs1) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
- return simplify_div_or_mod_using_ranges (stmt);
+ return simplify_div_or_mod_using_ranges (gsi, stmt);
break;
/* Transform ABS (X) into X or -X as appropriate. */
fprintf (dump_file, "\n");
}
- substitute_and_fold (op_with_constant_singleton_value_range,
- vrp_fold_stmt, false);
-
- if (warn_array_bounds && warn_array_bounds_p)
- check_all_array_refs ();
-
- /* We must identify jump threading opportunities before we release
- the datastructures built by VRP. */
- identify_jump_threads ();
-
/* Set value range to non pointer SSA_NAMEs. */
for (i = 0; i < num_vr_values; i++)
if (vr_value[i])
vr_value[i]->max);
}
+ substitute_and_fold (op_with_constant_singleton_value_range,
+ vrp_fold_stmt, false);
+
+ if (warn_array_bounds && warn_array_bounds_p)
+ check_all_array_refs ();
+
+ /* We must identify jump threading opportunities before we release
+ the datastructures built by VRP. */
+ identify_jump_threads ();
+
/* Free allocated memory. */
for (i = 0; i < num_vr_values; i++)
if (vr_value[i])