re PR rtl-optimization/7520 (internal compiler error in verify_local_live_at_start)
authorRichard Henderson <rth@redhat.com>
Fri, 27 Sep 2002 21:39:11 +0000 (14:39 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 27 Sep 2002 21:39:11 +0000 (14:39 -0700)
        PR optimization/7520
        * cfganal.c (flow_active_insn_p): New.
        (forwarder_block_p): Use it.

From-SVN: r57593

gcc/ChangeLog
gcc/cfganal.c
gcc/testsuite/gcc.c-torture/compile/20020927-1.c [new file with mode: 0644]

index 30a220d8f215df42c9ad171f9a8d9d71848a070c..ebf0d324635afa8d60ed18b01782cb09ac62b091 100644 (file)
@@ -1,3 +1,9 @@
+2002-09-27  Richard Henderson  <rth@redhat.com>
+
+       PR optimization/7520
+       * cfganal.c (flow_active_insn_p): New.
+       (forwarder_block_p): Use it.
+
 2002-09-27  Richard Henderson  <rth@redhat.com>
 
        * emit-rtl.c (active_insn_p): Revert last change.
index bc8fff2510b1fb026a49d1286c10055cb46949eb..10c6bcf2922c5eb7dd505ebaee6c6d63a5bf17d9 100644 (file)
@@ -54,7 +54,31 @@ static void flow_dfs_compute_reverse_finish
   PARAMS ((depth_first_search_ds));
 static void remove_fake_successors     PARAMS ((basic_block));
 static bool need_fake_edge_p           PARAMS ((rtx));
+static bool flow_active_insn_p         PARAMS ((rtx));
 \f
+/* Like active_insn_p, except keep the return value clobber around
+   even after reload.  */
+
+static bool
+flow_active_insn_p (insn)
+     rtx insn;
+{
+  if (active_insn_p (insn))
+    return true;
+
+  /* A clobber of the function return value exists for buggy 
+     programs that fail to return a value.  It's effect is to
+     keep the return value from being live across the entire
+     function.  If we allow it to be skipped, we introduce the
+     possibility for register livetime aborts.  */
+  if (GET_CODE (PATTERN (insn)) == CLOBBER
+      && GET_CODE (XEXP (PATTERN (insn), 0)) == REG
+      && REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))
+    return true;
+
+  return false;
+}
+
 /* Return true if the block has no effect and only forwards control flow to
    its single destination.  */
 
@@ -69,12 +93,12 @@ forwarder_block_p (bb)
     return false;
 
   for (insn = bb->head; insn != bb->end; insn = NEXT_INSN (insn))
-    if (INSN_P (insn) && active_insn_p (insn))
+    if (INSN_P (insn) && flow_active_insn_p (insn))
       return false;
 
   return (!INSN_P (insn)
          || (GET_CODE (insn) == JUMP_INSN && simplejump_p (insn))
-         || !active_insn_p (insn));
+         || !flow_active_insn_p (insn));
 }
 
 /* Return nonzero if we can reach target from src by falling through.  */
diff --git a/gcc/testsuite/gcc.c-torture/compile/20020927-1.c b/gcc/testsuite/gcc.c-torture/compile/20020927-1.c
new file mode 100644 (file)
index 0000000..b93d8a1
--- /dev/null
@@ -0,0 +1,26 @@
+/* PR optimization/7520 */
+/* ICE at -O3 on x86 due to register life problems caused by
+   the return-without-value in bar.  */
+
+int
+foo ()
+{
+  int i;
+  long long int j;
+
+  while (1)
+    {
+      if (j & 1)
+       ++i;
+      j >>= 1;
+      if (j)
+       return i;
+    }
+}
+
+int
+bar ()
+{
+  if (foo ())
+    return;
+}