diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-03-31 11:06:43 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-03-31 11:06:43 +0200 |
commit | 1dcffc8ddc48f0b45d3d0d2f763ef5870560eb9a (patch) | |
tree | b000d2ce959c64e6d7afc16c63c7c9a73d918008 /gcc | |
parent | 5ea39b2412269d208bb6ebd78303815957bd4f70 (diff) | |
download | gcc-1dcffc8ddc48f0b45d3d0d2f763ef5870560eb9a.zip gcc-1dcffc8ddc48f0b45d3d0d2f763ef5870560eb9a.tar.gz gcc-1dcffc8ddc48f0b45d3d0d2f763ef5870560eb9a.tar.bz2 |
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>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fold-const.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr94412.c | 28 |
4 files changed, 42 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e7ff913..4686c59 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +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-03-31 Jakub Jelinek <jakub@redhat.com> PR tree-optimization/94403 diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 9267914..b79d059 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -11148,11 +11148,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"), @@ -11162,11 +11162,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"), diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3f21cb3..32d5309 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2020-03-31 Jakub Jelinek <jakub@redhat.com> + PR middle-end/94412 + * gcc.c-torture/execute/pr94412.c: New test. + PR tree-optimization/94403 * g++.dg/tree-ssa/pr94403.C: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr94412.c b/gcc/testsuite/gcc.c-torture/execute/pr94412.c new file mode 100644 index 0000000..6c806bb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr94412.c @@ -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; +} |