re PR rtl-optimization/11741 (internal compiler error at gcse.c:5318)
authorRoger Sayle <sayle@gcc.gnu.org>
Fri, 26 Sep 2003 18:23:33 +0000 (18:23 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Fri, 26 Sep 2003 18:23:33 +0000 (18:23 +0000)
PR optimization/11741
* gcse.c (pre_insert_copy_insn): Tweak the logic for finding the
appropriate set to match that in hash_scan_insn.  Fall back to
the original copy method, if we can't validate changing insn.
(pre_delete): Only delete instructions that have a single_set,
instead of aborting when we encounter an PARALLEL insn with more
then one SET.

* gcc.dg/20030926-1.c: New test case.

From-SVN: r71827

gcc/ChangeLog
gcc/gcse.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20030926-1.c [new file with mode: 0644]

index 7cafd7098c27ba7d6cd819d5b21349c8b549d657..22bfb29e87646f49ceada4b8dd4ef5d64d4447c6 100644 (file)
@@ -1,3 +1,14 @@
+2003-09-26  Roger Sayle  <roger@eyesopen.com>
+           Richard Henderson  <rth@redhat.com>
+
+       PR optimization/11741
+       * gcse.c (pre_insert_copy_insn): Tweak the logic for finding the
+       appropriate set to match that in hash_scan_insn.  Fall back to
+       the original copy method, if we can't validate changing insn.
+       (pre_delete): Only delete instructions that have a single_set,
+       instead of aborting when we encounter an PARALLEL insn with more
+       then one SET.
+
 2003-09-26  Andreas Krebbel  <krebbel1@de.ibm.com>
 
        * config/s390/s390.md ("builtin_setjmp_setup"): Insn deleted.
index f50c2d9a01e402d57902c413021035bda7713c92..8e78e5b08e64783da833bf7b501ba45c49d8820d 100644 (file)
@@ -5353,14 +5353,14 @@ pre_edge_insert (struct edge_list *edge_list, struct expr **index_map)
   return did_insert;
 }
 
-/* Copy the result of INSN to REG.  INDX is the expression number.
+/* Copy the result of EXPR->EXPR generated by INSN to EXPR->REACHING_REG.
    Given "old_reg <- expr" (INSN), instead of adding after it
      reaching_reg <- old_reg
    it's better to do the following:
      reaching_reg <- expr
      old_reg      <- reaching_reg
    because this way copy propagation can discover additional PRE
-   opportunuties.  */
+   opportunuties.  But if this fails, we try the old way.  */
 
 static void
 pre_insert_copy_insn (struct expr *expr, rtx insn)
@@ -5368,27 +5368,53 @@ pre_insert_copy_insn (struct expr *expr, rtx insn)
   rtx reg = expr->reaching_reg;
   int regno = REGNO (reg);
   int indx = expr->bitmap_index;
-  rtx set = single_set (insn);
-  rtx new_insn;
-  rtx new_set;
+  rtx pat = PATTERN (insn);
+  rtx set, new_insn;
   rtx old_reg;
+  int i;
 
-  if (!set)
+  /* This block matches the logic in hash_scan_insn.  */
+  if (GET_CODE (pat) == SET)
+    set = pat;
+  else if (GET_CODE (pat) == PARALLEL)
+    {
+      /* Search through the parallel looking for the set whose
+        source was the expression that we're interested in.  */
+      set = NULL_RTX;
+      for (i = 0; i < XVECLEN (pat, 0); i++)
+       {
+         rtx x = XVECEXP (pat, 0, i);
+         if (GET_CODE (x) == SET
+             && expr_equiv_p (SET_SRC (x), expr->expr))
+           {
+             set = x;
+             break;
+           }
+       }
+    }
+  else
     abort ();
 
   old_reg = SET_DEST (set);
-  new_insn = emit_insn_after (gen_move_insn (old_reg,
-                                             reg),
-                              insn);
-  new_set = single_set (new_insn);
 
-  if (!new_set)
-    abort();
-  SET_DEST (set) = reg;
+  /* Check if we can modify the set destination in the original insn.  */
+  if (validate_change (insn, &SET_DEST (set), reg, 0))
+    {
+      new_insn = gen_move_insn (old_reg, reg);
+      new_insn = emit_insn_after (new_insn, insn);
+
+      /* Keep register set table up to date.  */
+      replace_one_set (REGNO (old_reg), insn, new_insn);
+      record_one_set (regno, insn);
+    }
+  else
+    {
+      new_insn = gen_move_insn (reg, old_reg);
+      new_insn = emit_insn_after (new_insn, insn);
 
-  /* Keep register set table up to date.  */
-  replace_one_set (REGNO (old_reg), insn, new_insn);
-  record_one_set (regno, insn);
+      /* Keep register set table up to date.  */
+      record_one_set (regno, new_insn);
+    }
 
   gcse_create_count++;
 
@@ -5505,7 +5531,9 @@ pre_delete (void)
 
   changed = 0;
   for (i = 0; i < expr_hash_table.size; i++)
-    for (expr = expr_hash_table.table[i]; expr != NULL; expr = expr->next_same_hash)
+    for (expr = expr_hash_table.table[i];
+        expr != NULL;
+        expr = expr->next_same_hash)
       {
        int indx = expr->bitmap_index;
 
@@ -5518,12 +5546,10 @@ pre_delete (void)
            rtx set;
            basic_block bb = BLOCK_FOR_INSN (insn);
 
-           if (TEST_BIT (pre_delete_map[bb->index], indx))
+           /* We only delete insns that have a single_set.  */
+           if (TEST_BIT (pre_delete_map[bb->index], indx)
+               && (set = single_set (insn)) != 0)
              {
-               set = single_set (insn);
-               if (! set)
-                 abort ();
-
                /* Create a pseudo-reg to store the result of reaching
                   expressions into.  Get the mode for the new pseudo from
                   the mode of the original destination pseudo.  */
index d9600501bfaf2ba85250ff4bfbd8a438d85ea700..ae27c3533120d2798e54a98e96ed1c7576387306 100644 (file)
@@ -1,3 +1,8 @@
+2003-09-26  Roger Sayle  <roger@eyesopen.com>
+
+       PR optimization/11741
+       * gcc.dg/20030926-1.c: New test case.
+
 2003-09-25  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
        PR c++/5655
        * lib/objc.exp (objc_target_compile): Do not point at libobjc headers
        if libobjc has not been built.
        * objc/execute/IMP.m, objc/execute/_cmd.m, objc/execute/bf-common.h,
-       objc/execute/bycopy-3.m, objc/execute/class-{1-14}.m, objc/execute/class-self-2.m,
-       objc/execute/many_args_method.m, objc/execute/nested-3.m, objc/execute/np-2.m,
+       objc/execute/bycopy-3.m, objc/execute/class-{1-14}.m,
+       objc/execute/class-self-2.m, objc/execute/many_args_method.m,
+       objc/execute/nested-3.m, objc/execute/np-2.m,
        objc/execute/object_is_class.m, objc/execute/object_is_meta_class.m,
        objc/execute/redefining_self.m, objc/execute/root_methods.m,
-       objc/execute/static-{1-2}.m, objc/execute/string-{1-4}.m, objc/execute/va_method.m,
-       objc.dg/comp-types-4.m, objc.dg/headers.m, objc.dg/special/unclaimed-category-1.h,
-       objc.dg/special/unclaimed-category-1.m: Make usable with NeXT as well as GNU runtime.
+       objc/execute/static-{1-2}.m, objc/execute/string-{1-4}.m,
+       objc/execute/va_method.m, objc.dg/comp-types-4.m, objc.dg/headers.m,
+       objc.dg/special/unclaimed-category-1.h,
+       objc.dg/special/unclaimed-category-1.m: Make usable with NeXT as
+       well as GNU runtime.
        * execute/next_mapping.h: New header, for GNU->NeXT impedance matching.
-       * execute/cascading-1.m, execute/function-message-1.m, objc.dg/anon-1.m,
-       objc.dg/bitfield-{3-4}.m, objc.dg/call-super-{1-3}.m, objc.dg/category-1.m,
-       objc.dg/const-str-{3-6}.m, objc.dg/encode-{1-4}.m, objc.dg/func-ptr-1.m,
-       objc.dg/gnu-runtime-1.m, objc.dg/image-info.m, objc.dg/method-{3-12}.m,
-       objc.dg/missing-proto-{1-3}.m, objc.dg/nested-func-1.m, objc.dg/proto-lossage-2.m,
-       objc.dg/proto-qual-1.m, objc.dg/sizeof-1.m, objc.dg/static-1.m, objc.dg/symtab-1.m,
-       objc.dg/try-catch-{1-4}.m, objc.dg/type-size-{1-2}.m, objc.dg/zero-link-{1-2}.m:
-       New test cases.
+       * execute/cascading-1.m, execute/function-message-1.m,
+       objc.dg/anon-1.m, objc.dg/bitfield-{3-4}.m,
+       objc.dg/call-super-{1-3}.m, objc.dg/category-1.m,
+       objc.dg/const-str-{3-6}.m, objc.dg/encode-{1-4}.m,
+       objc.dg/func-ptr-1.m, objc.dg/gnu-runtime-1.m, objc.dg/image-info.m,
+       objc.dg/method-{3-12}.m, objc.dg/missing-proto-{1-3}.m,
+       objc.dg/nested-func-1.m, objc.dg/proto-lossage-2.m,
+       objc.dg/proto-qual-1.m, objc.dg/sizeof-1.m, objc.dg/static-1.m,
+       objc.dg/symtab-1.m, objc.dg/try-catch-{1-4}.m,
+       objc.dg/type-size-{1-2}.m, objc.dg/zero-link-{1-2}.m: New test cases.
        * objc.dg/bitfield-2.m: Run only on Darwin.
        * objc.dg/class-2.m, objc.dg/comp-types-1.m, objc.dg/desig-init-1.m,
-       objc.dg/method-{1-2}.m, objc.dg/proto-hier-1.m, objc.dg/proto-lossage-1.m:
-       Adjust for message wording changes.
+       objc.dg/method-{1-2}.m, objc.dg/proto-hier-1.m,
+       objc.dg/proto-lossage-1.m: Adjust for message wording changes.
        * objc.dg/const-str-1.m: Fix constant string layout.
  
 2003-09-24  Alexandre Oliva  <aoliva@redhat.com>
diff --git a/gcc/testsuite/gcc.dg/20030926-1.c b/gcc/testsuite/gcc.dg/20030926-1.c
new file mode 100644 (file)
index 0000000..085cb9b
--- /dev/null
@@ -0,0 +1,14 @@
+/* PR optimization/11741  */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -minline-all-stringops -march=pentium4" } */
+
+void
+foo (char *p)
+{
+  for (;;)
+    {
+      memcpy (p, p + 1, strlen (p));
+      p++;
+    }
+}
+