This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Committed] GCC 4.1 loop.c: Remove REG_EQUAL when hoisting cond invariant insn


Hi,

the attached patch fixes a problem in the old loop optimizer
of GCC 4.1.  The problem is described here:
http://gcc.gnu.org/ml/gcc/2007-05/msg00081.html

Bootstrapped on i686, s390 and s390x.
The included testcase works on s390x compiled with GCC 3.4 and
fails on the same machine with GCC 4.1 head.
With the patch the testcase executes successfully on the 3
tested architectures.

Eric Botcazou pre-approved that change for GCC 4.1.

Bye,

-Andreas-

2007-05-08  Andreas Krebbel  <krebbel1@de.ibm.com>

	* loop.c (move_movables): Remove REG_EQUAL notes for conditional
	invariants as well.


2007-05-08  Andreas Krebbel  <krebbel1@de.ibm.com>

	* gcc.dg/20070507-1.c: New testcase.


Index: gcc/loop.c
===================================================================
*** gcc/loop.c.orig	2007-05-04 17:46:13.000000000 +0200
--- gcc/loop.c	2007-05-04 17:52:49.000000000 +0200
*************** move_movables (struct loop *loop, struct
*** 2561,2567 ****
  			     like this as a result of record_jump_cond.  */
  
  			  if ((temp = find_reg_note (i1, REG_EQUAL, NULL_RTX))
! 			      && ! loop_invariant_p (loop, XEXP (temp, 0)))
  			    remove_note (i1, temp);
  			}
  
--- 2561,2567 ----
  			     like this as a result of record_jump_cond.  */
  
  			  if ((temp = find_reg_note (i1, REG_EQUAL, NULL_RTX))
! 			      && loop_invariant_p (loop, XEXP (temp, 0)) != 1)
  			    remove_note (i1, temp);
  			}
  
Index: gcc/testsuite/gcc.dg/20070507-1.c
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/20070507-1.c	2007-05-08 12:47:34.000000000 +0200
***************
*** 0 ****
--- 1,103 ----
+ /* This failed on s390x due to bug in loop.c.
+    loop.c failed to remove a REG_EQUAL note when
+    hoisting an insn from a loop body.  */
+ 
+ /* { dg-options "-O3 -fPIC" } */
+ /* { dg-do run } */
+ 
+ typedef __SIZE_TYPE__ size_t;
+ int memcmp(const void *s1, const void *s2, size_t n);
+ 
+ typedef struct
+ {
+   char name[30];
+   int a;
+ } LOCAL;
+ 
+ int global = 0;
+ int sy = 1;
+ int subroutine_offset;
+ 
+ LOCAL local = { "local", 0 };
+ LOCAL keywords = { "keywords", 1 };
+ int local_table = 0;
+ int keywords_table = 0;
+ 
+ void __attribute__((noinline)) bar (char *p_buffer)
+ {
+   p_buffer[255] = 1;
+ }
+ 
+ int __attribute__((noinline)) foo (char *p_str1)
+ {
+   global = 1;
+   return 1;
+ }
+ 
+ int __attribute__((noinline)) loop_next (int *p_table, char *p_table_head)
+ {
+   static loop_next = 0;
+ 
+   if (loop_next == 1)
+     return 1;
+ 
+   loop_next = 1;
+   return 0;
+ }
+ 
+ int
+ main ()
+ {
+   char buffer[256];
+   int ende = 0;
+   int index;
+   int local_base = 2;
+ 
+   keywords.a = 1;
+   for (sy = 0;; sy++)
+     {
+       for (index = 1;;)
+ 	{
+ 	  bar (buffer);
+ 	  if (buffer[sy] != 0)
+ 	    {
+ 	      ende = 1;
+ 	      break;
+ 	    };
+ 	  if (foo (buffer))
+ 	    {
+ 	      keywords.a += index - 1;
+ 	      break;
+ 	    }
+ 	  index++;
+ 	}
+       if (ende)
+ 	break;
+     }
+ 
+   subroutine_offset = 0;
+ 
+   for (;;)
+     {
+       if (loop_next (&keywords_table, (char*)&keywords))
+ 	break;
+ 
+       if ((!memcmp (keywords.name, "+++", 3)))
+ 	local_base = 100;
+       else
+ 	local_base = 0;
+ 
+       if ((!memcmp (keywords.name, "+++", 3)))
+ 	subroutine_offset += local_table;
+ 
+       for (;;)
+ 	{
+ 	  if (loop_next (&local_table, (char*)&local))
+ 	    break;;
+ 	  if ((local.a == 0))
+ 	    continue;;
+ 	  foo (local.name);
+ 	}
+     }
+   return 0;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]