re PR rtl-optimization/47337 (Wrong RTL dce of calls)

PR rtl-optimization/47337
	* dce.c (check_argument_store): New function.
	(find_call_stack_args): Ignore debug insns.  Use check_argument_store.

	* gcc.c-torture/execute/pr47337.c: New test.

From-SVN: r168997
This commit is contained in:
Jakub Jelinek 2011-01-19 16:13:01 +01:00 committed by Jakub Jelinek
parent 46e7483cba
commit 2e0642cde2
4 changed files with 121 additions and 12 deletions

View File

@ -1,5 +1,9 @@
2011-01-19 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/47337
* dce.c (check_argument_store): New function.
(find_call_stack_args): Ignore debug insns. Use check_argument_store.
PR tree-optimization/47290
* tree-eh.c (infinite_empty_loop_p): New function.
(cleanup_empty_eh): Use it.

View File

@ -1,5 +1,5 @@
/* RTL dead code elimination.
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GCC.
@ -220,6 +220,26 @@ mark_nonreg_stores (rtx body, rtx insn, bool fast)
}
/* Return true if store to MEM, starting OFF bytes from stack pointer,
is a call argument store, and clear corresponding bits from SP_BYTES
bitmap if it is. */
static bool
check_argument_store (rtx mem, HOST_WIDE_INT off, HOST_WIDE_INT min_sp_off,
HOST_WIDE_INT max_sp_off, bitmap sp_bytes)
{
HOST_WIDE_INT byte;
for (byte = off; byte < off + GET_MODE_SIZE (GET_MODE (mem)); byte++)
{
if (byte < min_sp_off
|| byte >= max_sp_off
|| !bitmap_clear_bit (sp_bytes, byte - min_sp_off))
return false;
}
return true;
}
/* Try to find all stack stores of CALL_INSN arguments if
ACCUMULATE_OUTGOING_ARGS. If all stack stores have been found
and it is therefore safe to eliminate the call, return true,
@ -364,7 +384,7 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast,
for (insn = PREV_INSN (call_insn); insn; insn = prev_insn)
{
rtx set, mem, addr;
HOST_WIDE_INT off, byte;
HOST_WIDE_INT off;
if (insn == BB_HEAD (BLOCK_FOR_INSN (call_insn)))
prev_insn = NULL_RTX;
@ -374,7 +394,7 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast,
if (CALL_P (insn))
break;
if (!INSN_P (insn))
if (!NONDEBUG_INSN_P (insn))
continue;
set = single_set (insn);
@ -433,17 +453,11 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast,
break;
}
if (GET_MODE_SIZE (GET_MODE (mem)) == 0)
if (GET_MODE_SIZE (GET_MODE (mem)) == 0
|| !check_argument_store (mem, off, min_sp_off,
max_sp_off, sp_bytes))
break;
for (byte = off; byte < off + GET_MODE_SIZE (GET_MODE (mem)); byte++)
{
if (byte < min_sp_off
|| byte >= max_sp_off
|| !bitmap_clear_bit (sp_bytes, byte - min_sp_off))
break;
}
if (!deletable_insn_p (insn, fast, NULL))
break;

View File

@ -1,3 +1,8 @@
2011-01-19 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/47337
* gcc.c-torture/execute/pr47337.c: New test.
2011-01-19 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
PR testsuite/45342

View File

@ -0,0 +1,86 @@
/* PR rtl-optimization/47337 */
static unsigned int a[256], b = 0;
static char c = 0;
static int d = 0, *f = &d;
static long long e = 0;
static short
foo (long long x, long long y)
{
return x / y;
}
static char
bar (char x, char y)
{
return x - y;
}
static int
baz (int x, int y)
{
*f = (y != (short) (y * 3));
for (c = 0; c < 2; c++)
{
lab:
if (d)
{
if (e)
e = 1;
else
return x;
}
else
{
d = 1;
goto lab;
}
f = &d;
}
return x;
}
static void
fnx (unsigned long long x, int y)
{
if (!y)
{
b = a[b & 1];
b = a[b & 1];
b = a[(b ^ (x & 1)) & 1];
b = a[(b ^ (x & 1)) & 1];
}
}
char *volatile w = "2";
int
main ()
{
int h = 0;
unsigned int k = 0;
int l[8];
int i, j;
if (__builtin_strcmp (w, "1") == 0)
h = 1;
for (i = 0; i < 256; i++)
{
for (j = 8; j > 0; j--)
k = 1;
a[i] = k;
}
for (i = 0; i < 8; i++)
l[i] = 0;
d = bar (c, c);
d = baz (c, 1 | foo (l[0], 10));
fnx (d, h);
fnx (e, h);
if (d != 0)
__builtin_abort ();
return 0;
}