mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-21 20:04:02 +08:00
widening_mul: Fix up ICE caused by my signed multiplication overflow pattern recognition changes [PR98629]
As the testcase shows, my latest changes caused ICE on that testcase. The problem is that arith_overflow_check_p now can change the use_stmt argument (has a reference), so that if it succeeds (returns non-zero), it points it to the GIMPLE_COND or EQ/NE or COND_EXPR assignment from the TRUNC_DIV_EXPR assignment. The problem was that it would change use_stmt also if it returned 0 in some cases, such as multiple imm uses of the division, and in one of the callers if arith_overflow_check_p returns 0 it looks at use_stmt again and performs other checks, which of course assumes that use_stmt is the one passed to arith_overflow_check_p and not e.g. NULL instead or some other unrelated stmt. The following patch fixes that by only changing use_stmt when we are about to return non-zero (for the MULT_EXPR case, which is the only one with the need to use different use_stmt). 2021-01-12 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/98629 * tree-ssa-math-opts.c (arith_overflow_check_p): Don't update use_stmt unless returning non-zero. * gcc.c-torture/compile/pr98629.c: New test.
This commit is contained in:
parent
13d47c37a2
commit
24ea113f75
11
gcc/testsuite/gcc.c-torture/compile/pr98629.c
Normal file
11
gcc/testsuite/gcc.c-torture/compile/pr98629.c
Normal file
@ -0,0 +1,11 @@
|
||||
/* PR tree-optimization/98629 */
|
||||
|
||||
unsigned int a;
|
||||
int b, c;
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
unsigned int *e = &a;
|
||||
(a /= a |= b) - (0 <= (*e += *e)) * (c *= *e);
|
||||
}
|
@ -3667,6 +3667,7 @@ arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt,
|
||||
tree rhs1 = gimple_assign_rhs1 (stmt);
|
||||
tree rhs2 = gimple_assign_rhs2 (stmt);
|
||||
tree multop = NULL_TREE, divlhs = NULL_TREE;
|
||||
gimple *cur_use_stmt = use_stmt;
|
||||
|
||||
if (code == MULT_EXPR)
|
||||
{
|
||||
@ -3697,26 +3698,26 @@ arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt,
|
||||
if (!divlhs)
|
||||
return 0;
|
||||
use_operand_p use;
|
||||
if (!single_imm_use (divlhs, &use, &use_stmt))
|
||||
if (!single_imm_use (divlhs, &use, &cur_use_stmt))
|
||||
return 0;
|
||||
}
|
||||
if (gimple_code (use_stmt) == GIMPLE_COND)
|
||||
if (gimple_code (cur_use_stmt) == GIMPLE_COND)
|
||||
{
|
||||
ccode = gimple_cond_code (use_stmt);
|
||||
crhs1 = gimple_cond_lhs (use_stmt);
|
||||
crhs2 = gimple_cond_rhs (use_stmt);
|
||||
ccode = gimple_cond_code (cur_use_stmt);
|
||||
crhs1 = gimple_cond_lhs (cur_use_stmt);
|
||||
crhs2 = gimple_cond_rhs (cur_use_stmt);
|
||||
}
|
||||
else if (is_gimple_assign (use_stmt))
|
||||
else if (is_gimple_assign (cur_use_stmt))
|
||||
{
|
||||
if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
|
||||
if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS)
|
||||
{
|
||||
ccode = gimple_assign_rhs_code (use_stmt);
|
||||
crhs1 = gimple_assign_rhs1 (use_stmt);
|
||||
crhs2 = gimple_assign_rhs2 (use_stmt);
|
||||
ccode = gimple_assign_rhs_code (cur_use_stmt);
|
||||
crhs1 = gimple_assign_rhs1 (cur_use_stmt);
|
||||
crhs2 = gimple_assign_rhs2 (cur_use_stmt);
|
||||
}
|
||||
else if (gimple_assign_rhs_code (use_stmt) == COND_EXPR)
|
||||
else if (gimple_assign_rhs_code (cur_use_stmt) == COND_EXPR)
|
||||
{
|
||||
tree cond = gimple_assign_rhs1 (use_stmt);
|
||||
tree cond = gimple_assign_rhs1 (cur_use_stmt);
|
||||
if (COMPARISON_CLASS_P (cond))
|
||||
{
|
||||
ccode = TREE_CODE (cond);
|
||||
@ -3792,11 +3793,17 @@ arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt,
|
||||
{
|
||||
if ((crhs1 == divlhs && arith_cast_equal_p (crhs2, multop))
|
||||
|| (crhs2 == divlhs && arith_cast_equal_p (crhs1, multop)))
|
||||
return ccode == NE_EXPR ? 1 : -1;
|
||||
{
|
||||
use_stmt = cur_use_stmt;
|
||||
return ccode == NE_EXPR ? 1 : -1;
|
||||
}
|
||||
}
|
||||
else if ((crhs1 == divlhs && operand_equal_p (crhs2, multop, 0))
|
||||
|| (crhs2 == divlhs && crhs1 == multop))
|
||||
return ccode == NE_EXPR ? 1 : -1;
|
||||
{
|
||||
use_stmt = cur_use_stmt;
|
||||
return ccode == NE_EXPR ? 1 : -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user