Patchwork Fix loop unswitching with irreducible loop edges (PR tree-optimization/46107)

login
register
mail settings
Submitter Jakub Jelinek
Date Nov. 2, 2010, 11:40 p.m.
Message ID <20101102234055.GM29412@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/69935/
State New
Headers show

Comments

Jakub Jelinek - Nov. 2, 2010, 11:40 p.m.
Hi!

As the testcase shows, if loop unswitching calls loop_version, it
temporarily removes EDGE_IRREDUCIBLE_LOOP bit from entry->flags.
If cfg_hook_duplicate_loop_to_header_edge fails, nothing restores it back
and thus we ICE in verify_loop_structure ().  Fixed thusly,
bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2010-11-02  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/46107
	* cfgloopmanip.c (loop_version): Set irred_flag back into entry->flags
	if cfg_hook_duplicate_loop_to_header_edge failed.

	* gcc.c-torture/compile/pr46107.c: New test.


	Jakub
Zdenek Dvorak - Nov. 3, 2010, 9:47 a.m.
Hi,

> As the testcase shows, if loop unswitching calls loop_version, it
> temporarily removes EDGE_IRREDUCIBLE_LOOP bit from entry->flags.
> If cfg_hook_duplicate_loop_to_header_edge fails, nothing restores it back
> and thus we ICE in verify_loop_structure ().  Fixed thusly,
> bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

yes.  Thanks,

Zdenek

Patch

--- gcc/cfgloopmanip.c.jj	2010-08-20 16:05:40.000000000 +0200
+++ gcc/cfgloopmanip.c	2010-11-02 20:03:11.000000000 +0100
@@ -1,6 +1,6 @@ 
 /* Loop manipulation code for GNU compiler.
-   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software
-   Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -1538,7 +1538,10 @@  loop_version (struct loop *loop,
   /* Duplicate loop.  */
   if (!cfg_hook_duplicate_loop_to_header_edge (loop, entry, 1,
 					       NULL, NULL, NULL, 0))
-    return NULL;
+    {
+      entry->flags |= irred_flag;
+      return NULL;
+    }
 
   /* After duplication entry edge now points to new loop head block.
      Note down new head as second_head.  */
--- gcc/testsuite/gcc.c-torture/compile/pr46107.c.jj	2010-11-02 20:11:54.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/pr46107.c	2010-11-02 20:11:35.000000000 +0100
@@ -0,0 +1,16 @@ 
+/* PR tree-optimization/46107 */
+
+int foo (void) __attribute__ ((noreturn));
+
+void
+bar (int x, int *y, int z)
+{
+  static void *j[] = { &&l1, &&l2 };
+l1:
+  if (*y)
+    goto *j[z];
+  foo ();
+l2:
+  *y ^= (x & 1) ? -1 : 0;
+  goto *j[x];
+}