diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-11-28 20:15:51 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-11-28 20:15:51 +0100 |
commit | d057004733e8e4893cab758d51121b6750a9b438 (patch) | |
tree | e5ee8b087a141ae20a31c9baa3a55ea3434bb42b /gcc | |
parent | 82979abd860fb54c2d0ab0a1001d86ec69f71ae2 (diff) | |
download | gcc-d057004733e8e4893cab758d51121b6750a9b438.zip gcc-d057004733e8e4893cab758d51121b6750a9b438.tar.gz gcc-d057004733e8e4893cab758d51121b6750a9b438.tar.bz2 |
re PR rtl-optimization/78546 (wrong code at -O2 and above)
PR rtl-optimization/78546
* simplify-rtx.c (neg_const_int): When negating most negative
number in mode wider than HOST_BITS_PER_WIDE_INT, use
simplify_const_unary_operation to produce CONST_DOUBLE or
CONST_WIDE_INT.
(simplify_plus_minus): Hanlde the case where neg_const_int
doesn't return a CONST_INT.
* gcc.dg/torture/pr78546-1.c: New test.
* gcc.dg/torture/pr78546-2.c: New test.
From-SVN: r242929
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/simplify-rtx.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr78546-1.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr78546-2.c | 16 |
5 files changed, 66 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 41dcb5d..40ef344 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-11-28 Jakub Jelinek <jakub@redhat.com> + + PR rtl-optimization/78546 + * simplify-rtx.c (neg_const_int): When negating most negative + number in mode wider than HOST_BITS_PER_WIDE_INT, use + simplify_const_unary_operation to produce CONST_DOUBLE or + CONST_WIDE_INT. + (simplify_plus_minus): Hanlde the case where neg_const_int + doesn't return a CONST_INT. + 2016-11-28 Markus Trippelsdorf <markus@trippelsdorf.de> PR target/78556 diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index f6131d4..83fb37d 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -56,12 +56,17 @@ static rtx simplify_unary_operation_1 (enum rtx_code, machine_mode, rtx); static rtx simplify_binary_operation_1 (enum rtx_code, machine_mode, rtx, rtx, rtx, rtx); -/* Negate a CONST_INT rtx, truncating (because a conversion from a - maximally negative number can overflow). */ +/* Negate a CONST_INT rtx. */ static rtx neg_const_int (machine_mode mode, const_rtx i) { - return gen_int_mode (-(unsigned HOST_WIDE_INT) INTVAL (i), mode); + unsigned HOST_WIDE_INT val = -UINTVAL (i); + + if (GET_MODE_PRECISION (mode) > HOST_BITS_PER_WIDE_INT + && val == UINTVAL (i)) + return simplify_const_unary_operation (NEG, mode, CONST_CAST_RTX (i), + mode); + return gen_int_mode (val, mode); } /* Test whether expression, X, is an immediate constant that represents @@ -4507,9 +4512,12 @@ simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0, rtx value = ops[n_ops - 1].op; if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg) value = neg_const_int (mode, value); - ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op, - INTVAL (value)); - n_ops--; + if (CONST_INT_P (value)) + { + ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op, + INTVAL (value)); + n_ops--; + } } /* Put a non-negated operand first, if possible. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 48ccdd9..04a6840 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2016-11-28 Jakub Jelinek <jakub@redhat.com> + PR rtl-optimization/78546 + * gcc.dg/torture/pr78546-1.c: New test. + * gcc.dg/torture/pr78546-2.c: New test. + PR fortran/78298 * gfortran.dg/gomp/pr78298.f90: New test. diff --git a/gcc/testsuite/gcc.dg/torture/pr78546-1.c b/gcc/testsuite/gcc.dg/torture/pr78546-1.c new file mode 100644 index 0000000..9cae5b1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr78546-1.c @@ -0,0 +1,22 @@ +/* PR rtl-optimization/78546 */ +/* { dg-do run { target int128 } } */ + +typedef unsigned __int128 u128; +u128 b; + +static inline u128 +foo (u128 p1) +{ + p1 += ~b; + return -p1; +} + +int +main () +{ + asm volatile ("" : : : "memory"); + u128 x = foo (~0x7fffffffffffffffLL); + if (x != 0x8000000000000001ULL) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr78546-2.c b/gcc/testsuite/gcc.dg/torture/pr78546-2.c new file mode 100644 index 0000000..afec5b5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr78546-2.c @@ -0,0 +1,16 @@ +/* PR rtl-optimization/78546 */ +/* { dg-do run { target int128 } } */ + +typedef unsigned __int128 u128; +u128 b; + +int +main () +{ + asm volatile ("" : : : "memory"); + u128 x = ((u128) ~0x7fffffffffffffffLL) - b; + u128 y = 1 - x; + if (y != 0x8000000000000001ULL) + __builtin_abort (); + return 0; +} |