From 2e0642cde2ace61ba98145609d5f62796666cbfa Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 19 Jan 2011 16:13:01 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 4 + gcc/dce.c | 38 +++++--- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.c-torture/execute/pr47337.c | 86 +++++++++++++++++++ 4 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr47337.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c456fb34f5b..b799162f70b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2011-01-19 Jakub Jelinek + 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. diff --git a/gcc/dce.c b/gcc/dce.c index e6e98365005..f63d09e4164 100644 --- a/gcc/dce.c +++ b/gcc/dce.c @@ -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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3e60bc320cd..ef62c3c9b02 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-01-19 Jakub Jelinek + + PR rtl-optimization/47337 + * gcc.c-torture/execute/pr47337.c: New test. + 2011-01-19 Ulrich Weigand PR testsuite/45342 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr47337.c b/gcc/testsuite/gcc.c-torture/execute/pr47337.c new file mode 100644 index 00000000000..ea88484a246 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr47337.c @@ -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; +}