aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2005-01-14 11:50:18 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2005-01-14 11:50:18 +0100
commit08a0c536dffd810a5565d149bfd216df684c788e (patch)
treea1913e93e194d26049b54e754c3bab349f78f636
parenta0afbdb682e3ae83ae087a69f3a975ad23582069 (diff)
downloadgcc-08a0c536dffd810a5565d149bfd216df684c788e.zip
gcc-08a0c536dffd810a5565d149bfd216df684c788e.tar.gz
gcc-08a0c536dffd810a5565d149bfd216df684c788e.tar.bz2
re PR middle-end/19084 (ICE: internal consistency failure)
PR middle-end/19084 PR rtl-optimization/19348 * recog.c (peephole2_optimize): Do global life update if some peephole decides it doesn't need at least one of its inputs and that change influences liveness at the start of the basic block. * basic-block.h (EXECUTE_IF_AND_COMPL_IN_REG_SET): Needs 2 REGSET arguments instead of 1. * gcc.dg/20050111-1.c: New test. * gcc.c-torture/execute/20050111-1.c: New test. From-SVN: r93639
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/basic-block.h4
-rw-r--r--gcc/recog.c16
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20050111-1.c39
-rw-r--r--gcc/testsuite/gcc.dg/20050111-1.c24
6 files changed, 96 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9e73321..9179625 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2005-01-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/19084
+ PR rtl-optimization/19348
+ * recog.c (peephole2_optimize): Do global life update if some peephole
+ decides it doesn't need at least one of its inputs and that change
+ influences liveness at the start of the basic block.
+
+ * basic-block.h (EXECUTE_IF_AND_COMPL_IN_REG_SET): Needs 2 REGSET
+ arguments instead of 1.
+
2005-01-14 Eric Botcazou <ebotcazou@libertysurf.fr>
PR middle-end/18820
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 39ce774..bfeac26 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -98,8 +98,8 @@ typedef bitmap_iterator reg_set_iterator;
/* Loop over all registers in REGSET1 and REGSET2, starting with MIN, setting
REGNUM to the register number and executing CODE for all registers that are
set in the first regset and not set in the second. */
-#define EXECUTE_IF_AND_COMPL_IN_REG_SET(REGSET, MIN, REGNUM, RSI) \
- EXECUTE_IF_AND_COMPL_IN_BITMAP (REGSET, MIN, REGNUM, RSI)
+#define EXECUTE_IF_AND_COMPL_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, RSI) \
+ EXECUTE_IF_AND_COMPL_IN_BITMAP (REGSET1, REGSET2, MIN, REGNUM, RSI)
/* Loop over all registers in REGSET1 and REGSET2, starting with MIN, setting
REGNUM to the register number and executing CODE for all registers that are
diff --git a/gcc/recog.c b/gcc/recog.c
index 09a98f2..6fc3cf9 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -2968,6 +2968,7 @@ peephole2_optimize (FILE *dump_file ATTRIBUTE_UNUSED)
bool changed;
#endif
bool do_cleanup_cfg = false;
+ bool do_global_life_update = false;
bool do_rebuild_jump_labels = false;
/* Initialize the regsets we're going to use. */
@@ -2986,6 +2987,8 @@ peephole2_optimize (FILE *dump_file ATTRIBUTE_UNUSED)
FOR_EACH_BB_REVERSE (bb)
{
struct propagate_block_info *pbi;
+ reg_set_iterator rsi;
+ unsigned int j;
/* Indicate that all slots except the last holds invalid data. */
for (i = 0; i < MAX_INSNS_PER_PEEP2; ++i)
@@ -3207,6 +3210,15 @@ peephole2_optimize (FILE *dump_file ATTRIBUTE_UNUSED)
break;
}
+ /* Some peepholes can decide the don't need one or more of their
+ inputs. If this happens, local life update is not enough. */
+ EXECUTE_IF_AND_COMPL_IN_BITMAP (bb->global_live_at_start, live,
+ 0, j, rsi)
+ {
+ do_global_life_update = true;
+ break;
+ }
+
free_propagate_block_info (pbi);
}
@@ -3223,8 +3235,10 @@ peephole2_optimize (FILE *dump_file ATTRIBUTE_UNUSED)
if (do_cleanup_cfg)
{
cleanup_cfg (0);
- update_life_info (0, UPDATE_LIFE_GLOBAL_RM_NOTES, PROP_DEATH_NOTES);
+ do_global_life_update = true;
}
+ if (do_global_life_update)
+ update_life_info (0, UPDATE_LIFE_GLOBAL_RM_NOTES, PROP_DEATH_NOTES);
#ifdef HAVE_conditional_execution
else
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6d60691..2d14c7d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
2005-01-14 Jakub Jelinek <jakub@redhat.com>
+ PR middle-end/19084
+ PR rtl-optimization/19348
+ * gcc.dg/20050111-1.c: New test.
+ * gcc.c-torture/execute/20050111-1.c: New test.
+
* gcc.dg/i386-asm-4.c: New test.
2005-01-14 Eric Botcazou <ebotcazou@libertysurf.fr>
diff --git a/gcc/testsuite/gcc.c-torture/execute/20050111-1.c b/gcc/testsuite/gcc.c-torture/execute/20050111-1.c
new file mode 100644
index 0000000..d6089f1
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20050111-1.c
@@ -0,0 +1,39 @@
+/* PR middle-end/19084, rtl-optimization/19348 */
+
+unsigned int
+foo (unsigned long long x)
+{
+ unsigned int u;
+
+ if (x == 0)
+ return 0;
+ u = (unsigned int) (x >> 32);
+ return u;
+}
+
+unsigned long long
+bar (unsigned short x)
+{
+ return (unsigned long long) x << 32;
+}
+
+extern void abort (void);
+
+int
+main (void)
+{
+ if (sizeof (long long) != 8)
+ return 0;
+
+ if (foo (0) != 0)
+ abort ();
+ if (foo (0xffffffffULL) != 0)
+ abort ();
+ if (foo (0x25ff00ff00ULL) != 0x25)
+ abort ();
+ if (bar (0) != 0)
+ abort ();
+ if (bar (0x25) != 0x2500000000ULL)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/20050111-1.c b/gcc/testsuite/gcc.dg/20050111-1.c
new file mode 100644
index 0000000..0cc4b7e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/20050111-1.c
@@ -0,0 +1,24 @@
+/* PR middle-end/19084, rtl-optimization/19348 */
+/* { dg-do compile } */
+/* The following ensures that this test is compiled with -O2, unless
+ on i?86 or x86_64 with -m32 option. */
+/* { dg-options "-O2" } */
+/* { dg-options "-O2 -march=i686" { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2" { target lp64 } } */
+
+unsigned int
+foo (unsigned long long x)
+{
+ unsigned int u;
+
+ if (x == 0)
+ return 0;
+ u = (unsigned int) (x >> 32);
+ return u;
+}
+
+unsigned long long
+bar (unsigned short x)
+{
+ return (unsigned long long) x << 32;
+}