aboutsummaryrefslogtreecommitdiff
path: root/gcc
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
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')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/simplify-rtx.c20
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr78546-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr78546-2.c16
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;
+}