re PR rtl-optimization/69535 (wrong code with -O -fno-tree-bit-ccp -fno-tree-reassoc due to use of uninitialised value)

PR rtl-opt/69535

  * combine.c (make_compound_operation): When looking through a
  subreg, make sure to re-extend to the width of the outer mode.

From-SVN: r233032
This commit is contained in:
Richard Henderson 2016-01-31 23:32:01 -08:00 committed by Richard Henderson
parent 2c00553806
commit e6c0c44b5b
4 changed files with 65 additions and 5 deletions

View File

@ -1,3 +1,9 @@
2016-02-01 Richard Henderson <rth@redhat.com>
PR rtl-opt/69535
* combine.c (make_compound_operation): When looking through a
subreg, make sure to re-extend to the width of the outer mode.
2016-01-30 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/69546

View File

@ -7887,11 +7887,25 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& GET_CODE (SUBREG_REG (XEXP (x, 0))) == LSHIFTRT
&& (i = exact_log2 (UINTVAL (XEXP (x, 1)) + 1)) >= 0)
{
new_rtx = make_compound_operation (XEXP (SUBREG_REG (XEXP (x, 0)), 0),
next_code);
new_rtx = make_extraction (GET_MODE (SUBREG_REG (XEXP (x, 0))), new_rtx, 0,
XEXP (SUBREG_REG (XEXP (x, 0)), 1), i, 1,
0, in_code == COMPARE);
rtx inner_x0 = SUBREG_REG (XEXP (x, 0));
machine_mode inner_mode = GET_MODE (inner_x0);
new_rtx = make_compound_operation (XEXP (inner_x0, 0), next_code);
new_rtx = make_extraction (inner_mode, new_rtx, 0,
XEXP (inner_x0, 1),
i, 1, 0, in_code == COMPARE);
if (new_rtx)
{
/* If we narrowed the mode when dropping the subreg, then
we must zero-extend to keep the semantics of the AND. */
if (GET_MODE_SIZE (inner_mode) >= GET_MODE_SIZE (mode))
;
else if (SCALAR_INT_MODE_P (inner_mode))
new_rtx = simplify_gen_unary (ZERO_EXTEND, mode,
new_rtx, inner_mode);
else
new_rtx = NULL;
}
/* If that didn't give anything, see if the AND simplifies on
its own. */

View File

@ -1,3 +1,7 @@
2016-02-01 Richard Henderson <rth@redhat.com>
* gcc.dg/pr69535.c: New test.
2016-01-31 John David Anglin <danglin@gcc.gnu.org>
PR testsuite/69584

View File

@ -0,0 +1,36 @@
/* { dg-do run { target int128 } } */
/* { dg-options "-O -fno-tree-bit-ccp -fno-tree-reassoc" } */
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef unsigned __int128 u128;
void __attribute__((noinline, noclone))
dirtify_stack(void)
{
volatile char a[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
}
u128 __attribute__ ((noinline, noclone))
foo(u32 u32_1, u64 u64_1, u128 u128_1, u8 u8_2, u16 u16_2, u32 u32_2, u8 u8_3)
{
u128_1 /= ~u128_1 | 1;
u8_3 = ((u8_3 << 2) >> 1) << 7;
u32_2 >>= u8_3;
return u128_1 + u32_2 + u8_3;
}
int
main ()
{
dirtify_stack();
u128 x = foo(1, 1, 1, 1, 1, 1, 0);
if (x != 1)
__builtin_abort();
return 0;
}