re PR tree-optimization/64006 (__builtin_mul_overflow fails to signal overflow)

PR tree-optimization/64006
	* tree-vrp.c (stmt_interesting_for_vrp): Return true
	for {ADD,SUB,MUL}_OVERFLOW internal calls.
	(vrp_visit_assignment_or_call): For {ADD,SUB,MUL}_OVERFLOW
	internal calls, check if any REALPART_EXPR/IMAGPART_EXPR
	immediate uses would change their value ranges and return
	SSA_PROP_INTERESTING if so, or SSA_PROP_NOT_INTERESTING
	if there are some REALPART_EXPR/IMAGPART_EXPR immediate uses
	interesting for vrp.

	* gcc.c-torture/execute/pr64006.c: New test.

From-SVN: r217945
This commit is contained in:
Jakub Jelinek 2014-11-21 21:41:37 +01:00 committed by Jakub Jelinek
parent eb23df5964
commit 09877e133f
4 changed files with 125 additions and 0 deletions

View File

@ -1,3 +1,15 @@
2014-11-21 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/64006
* tree-vrp.c (stmt_interesting_for_vrp): Return true
for {ADD,SUB,MUL}_OVERFLOW internal calls.
(vrp_visit_assignment_or_call): For {ADD,SUB,MUL}_OVERFLOW
internal calls, check if any REALPART_EXPR/IMAGPART_EXPR
immediate uses would change their value ranges and return
SSA_PROP_INTERESTING if so, or SSA_PROP_NOT_INTERESTING
if there are some REALPART_EXPR/IMAGPART_EXPR immediate uses
interesting for vrp.
2014-11-21 Michael Meissner <meissner@linux.vnet.ibm.com>
PR target/63965

View File

@ -1,3 +1,8 @@
2014-11-21 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/64006
* gcc.c-torture/execute/pr64006.c: New test.
2014-11-21 Lynn Boger <laboger@linux.vnet.ibm.com>
* go.test/go-test.exp (go-set-goarch): Add case for ppc64le goarch

View File

@ -0,0 +1,26 @@
/* PR tree-optimization/64006 */
int v;
long __attribute__ ((noinline, noclone))
test (long *x, int y)
{
int i;
long s = 1;
for (i = 0; i < y; i++)
if (__builtin_mul_overflow (s, x[i], &s))
v++;
return s;
}
int
main ()
{
long d[7] = { 975, 975, 975, 975, 975, 975, 975 };
long r = test (d, 7);
if (sizeof (long) * __CHAR_BIT__ == 64 && v != 1)
__builtin_abort ();
else if (sizeof (long) * __CHAR_BIT__ == 32 && v != 4)
__builtin_abort ();
return 0;
}

View File

@ -6949,6 +6949,20 @@ stmt_interesting_for_vrp (gimple stmt)
&& (is_gimple_call (stmt)
|| !gimple_vuse (stmt)))
return true;
else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
switch (gimple_call_internal_fn (stmt))
{
case IFN_ADD_OVERFLOW:
case IFN_SUB_OVERFLOW:
case IFN_MUL_OVERFLOW:
/* These internal calls return _Complex integer type,
but are interesting to VRP nevertheless. */
if (lhs && TREE_CODE (lhs) == SSA_NAME)
return true;
break;
default:
break;
}
}
else if (gimple_code (stmt) == GIMPLE_COND
|| gimple_code (stmt) == GIMPLE_SWITCH)
@ -7101,6 +7115,74 @@ vrp_visit_assignment_or_call (gimple stmt, tree *output_p)
return SSA_PROP_NOT_INTERESTING;
}
else if (is_gimple_call (stmt) && gimple_call_internal_p (stmt))
switch (gimple_call_internal_fn (stmt))
{
case IFN_ADD_OVERFLOW:
case IFN_SUB_OVERFLOW:
case IFN_MUL_OVERFLOW:
/* These internal calls return _Complex integer type,
which VRP does not track, but the immediate uses
thereof might be interesting. */
if (lhs && TREE_CODE (lhs) == SSA_NAME)
{
imm_use_iterator iter;
use_operand_p use_p;
enum ssa_prop_result res = SSA_PROP_VARYING;
set_value_range_to_varying (get_value_range (lhs));
FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
{
gimple use_stmt = USE_STMT (use_p);
if (!is_gimple_assign (use_stmt))
continue;
enum tree_code rhs_code = gimple_assign_rhs_code (use_stmt);
if (rhs_code != REALPART_EXPR && rhs_code != IMAGPART_EXPR)
continue;
tree rhs1 = gimple_assign_rhs1 (use_stmt);
tree use_lhs = gimple_assign_lhs (use_stmt);
if (TREE_CODE (rhs1) != rhs_code
|| TREE_OPERAND (rhs1, 0) != lhs
|| TREE_CODE (use_lhs) != SSA_NAME
|| !stmt_interesting_for_vrp (use_stmt)
|| (!INTEGRAL_TYPE_P (TREE_TYPE (use_lhs))
|| !TYPE_MIN_VALUE (TREE_TYPE (use_lhs))
|| !TYPE_MAX_VALUE (TREE_TYPE (use_lhs))))
continue;
/* If there is a change in the value range for any of the
REALPART_EXPR/IMAGPART_EXPR immediate uses, return
SSA_PROP_INTERESTING. If there are any REALPART_EXPR
or IMAGPART_EXPR immediate uses, but none of them have
a change in their value ranges, return
SSA_PROP_NOT_INTERESTING. If there are no
{REAL,IMAG}PART_EXPR uses at all,
return SSA_PROP_VARYING. */
value_range_t new_vr = VR_INITIALIZER;
extract_range_basic (&new_vr, use_stmt);
value_range_t *old_vr = get_value_range (use_lhs);
if (old_vr->type != new_vr.type
|| !vrp_operand_equal_p (old_vr->min, new_vr.min)
|| !vrp_operand_equal_p (old_vr->max, new_vr.max)
|| !vrp_bitmap_equal_p (old_vr->equiv, new_vr.equiv))
res = SSA_PROP_INTERESTING;
else
res = SSA_PROP_NOT_INTERESTING;
BITMAP_FREE (new_vr.equiv);
if (res == SSA_PROP_INTERESTING)
{
*output_p = lhs;
return res;
}
}
return res;
}
break;
default:
break;
}
/* Every other statement produces no useful ranges. */
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)