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
This commit is contained in:
parent
82979abd86
commit
d057004733
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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.
|
||||
|
||||
|
22
gcc/testsuite/gcc.dg/torture/pr78546-1.c
Normal file
22
gcc/testsuite/gcc.dg/torture/pr78546-1.c
Normal file
@ -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;
|
||||
}
|
16
gcc/testsuite/gcc.dg/torture/pr78546-2.c
Normal file
16
gcc/testsuite/gcc.dg/torture/pr78546-2.c
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user