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/simplify-rtx.c | |
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/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 20 |
1 files changed, 14 insertions, 6 deletions
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. */ |