aboutsummaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-11-28 20:15:51 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2016-11-28 20:15:51 +0100
commitd057004733e8e4893cab758d51121b6750a9b438 (patch)
treee5ee8b087a141ae20a31c9baa3a55ea3434bb42b /gcc/simplify-rtx.c
parent82979abd860fb54c2d0ab0a1001d86ec69f71ae2 (diff)
downloadgcc-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.c20
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. */