+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
static rtx simplify_binary_operation_1 (enum rtx_code, machine_mode,
rtx, rtx, rtx, rtx);
\f
-/* 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
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. */
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.
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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;
+}