fold-const: Fix division folding with vector operands [PR94412]

The following testcase is miscompiled since 4.9, we treat unsigned
vector types as if they were signed and "optimize" negations across it.

2020-03-31  Marc Glisse  <marc.glisse@inria.fr>
	    Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/94412
	* fold-const.c (fold_binary_loc) <case TRUNC_DIV_EXPR>: Use
	ANY_INTEGRAL_TYPE_P instead of INTEGRAL_TYPE_P.

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

Co-authored-by: Marc Glisse <marc.glisse@inria.fr>
This commit is contained in:
Jakub Jelinek 2020-03-31 11:06:43 +02:00
parent a6bf0e5fb1
commit 8f99f9e6cc
4 changed files with 46 additions and 4 deletions

View File

@ -1,6 +1,15 @@
2020-04-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2020-03-31 Marc Glisse <marc.glisse@inria.fr>
Jakub Jelinek <jakub@redhat.com>
PR middle-end/94412
* fold-const.c (fold_binary_loc) <case TRUNC_DIV_EXPR>: Use
ANY_INTEGRAL_TYPE_P instead of INTEGRAL_TYPE_P.
2020-04-07 Jakub Jelinek <jakub@redhat.com>
2020-03-30 Jakub Jelinek <jakub@redhat.com>
PR target/93069

View File

@ -10376,11 +10376,11 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
/* Convert -A / -B to A / B when the type is signed and overflow is
undefined. */
if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
&& TREE_CODE (op0) == NEGATE_EXPR
&& negate_expr_p (op1))
{
if (INTEGRAL_TYPE_P (type))
if (ANY_INTEGRAL_TYPE_P (type))
fold_overflow_warning (("assuming signed overflow does not occur "
"when distributing negation across "
"division"),
@ -10390,11 +10390,11 @@ fold_binary_loc (location_t loc, enum tree_code code, tree type,
TREE_OPERAND (arg0, 0)),
negate_expr (op1));
}
if ((!INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
if ((!ANY_INTEGRAL_TYPE_P (type) || TYPE_OVERFLOW_UNDEFINED (type))
&& TREE_CODE (arg1) == NEGATE_EXPR
&& negate_expr_p (op0))
{
if (INTEGRAL_TYPE_P (type))
if (ANY_INTEGRAL_TYPE_P (type))
fold_overflow_warning (("assuming signed overflow does not occur "
"when distributing negation across "
"division"),

View File

@ -1,6 +1,11 @@
2020-04-07 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
2020-03-31 Jakub Jelinek <jakub@redhat.com>
PR middle-end/94412
* gcc.c-torture/execute/pr94412.c: New test.
2020-03-30 Jakub Jelinek <jakub@redhat.com>
PR c++/94385

View File

@ -0,0 +1,28 @@
/* PR middle-end/94412 */
typedef unsigned V __attribute__ ((__vector_size__ (sizeof (unsigned) * 2)));
void
foo (V *v, V *w)
{
*w = -*v / 11;
}
void
bar (V *v, V *w)
{
*w = -18 / -*v;
}
int
main ()
{
V a = (V) { 1, 0 };
V b = (V) { 3, __INT_MAX__ };
V c, d;
foo (&a, &c);
bar (&b, &d);
if (c[0] != -1U / 11 || c[1] != 0 || d[0] != 0 || d[1] != -18U / -__INT_MAX__)
__builtin_abort ();
return 0;
}