This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Committed] GCC 4.1 loop.c: Remove REG_EQUAL when hoisting cond invariant insn
- From: Andreas Krebbel <Andreas dot Krebbel at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 8 May 2007 15:01:03 +0200
- Subject: [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;
+ }