OSDN Git Service

* ifcvt.c: Include except.h.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 18 Apr 2002 20:02:18 +0000 (20:02 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 18 Apr 2002 20:02:18 +0000 (20:02 +0000)
        (block_has_only_trap): Break out from find_cond_trap.
        (find_cond_trap): Use it.  Always delete the trap block.
        (merge_if_block): Allow then block null.  Be less simplistic about
        what insns can end a block.
        * Makefile.in (ifcvt.o): Depend on except.h.

        * gcc.c-torture/compile/iftrap-1.c: New.
        * gcc.dg/iftrap-1.c: Adjust for ia64.
        * gcc.dg/iftrap-2.c: New.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52489 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/Makefile.in
gcc/ifcvt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/iftrap-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/iftrap-1.c
gcc/testsuite/gcc.dg/iftrap-2.c [new file with mode: 0644]

index 05a5f09..137640d 100644 (file)
@@ -1,5 +1,12 @@
 2002-04-18  Richard Henderson  <rth@redhat.com>
 
+        * ifcvt.c: Include except.h.
+        (block_has_only_trap): Break out from find_cond_trap.
+        (find_cond_trap): Use it.  Always delete the trap block.
+        (merge_if_block): Allow then block null.  Be less simplistic about
+        what insns can end a block.
+        * Makefile.in (ifcvt.o): Depend on except.h.
+
        * config/ia64/ia64.md (trap, conditional_trap): New.
 
 2002-04-18  Jakub Jelinek  <jakub@redhat.com>
index 1f7ad81..5a386ea 100644 (file)
@@ -1589,7 +1589,7 @@ regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) insn-config.h \
    resource.h $(OBSTACK_H) flags.h $(TM_P_H)
 ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(REGS_H) toplev.h \
    flags.h insn-config.h function.h $(RECOG_H) $(BASIC_BLOCK_H) $(EXPR_H) \
-   output.h $(TM_P_H)
+   output.h except.h $(TM_P_H)
 dependence.o : dependence.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) \
    $(C_COMMON_H) flags.h varray.h $(EXPR_H)
 params.o : params.c $(CONFIG_H) $(SYSTEM_H) $(PARAMS_H) toplev.h
index 207ff5c..880f94a 100644 (file)
@@ -27,6 +27,7 @@
 #include "flags.h"
 #include "insn-config.h"
 #include "recog.h"
+#include "except.h"
 #include "hard-reg-set.h"
 #include "basic-block.h"
 #include "expr.h"
@@ -104,6 +105,7 @@ static int find_if_block            PARAMS ((basic_block, edge, edge));
 static int find_if_case_1              PARAMS ((basic_block, edge, edge));
 static int find_if_case_2              PARAMS ((basic_block, edge, edge));
 static int find_cond_trap              PARAMS ((basic_block, edge, edge));
+static rtx block_has_only_trap         PARAMS ((basic_block));
 static int find_memory                 PARAMS ((rtx *, void *));
 static int dead_or_predicable          PARAMS ((basic_block, basic_block,
                                                 basic_block, basic_block, int));
@@ -1812,11 +1814,14 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
 
   /* First merge TEST block into THEN block.  This is a no-brainer since
      the THEN block did not have a code label to begin with.  */
-
-  if (combo_bb->global_live_at_end)
-    COPY_REG_SET (combo_bb->global_live_at_end, then_bb->global_live_at_end);
-  merge_blocks_nomove (combo_bb, then_bb);
-  num_removed_blocks++;
+  if (then_bb)
+    {
+      if (combo_bb->global_live_at_end)
+       COPY_REG_SET (combo_bb->global_live_at_end,
+                     then_bb->global_live_at_end);
+      merge_blocks_nomove (combo_bb, then_bb);
+      num_removed_blocks++;
+    }
 
   /* The ELSE block, if it existed, had a label.  That label count
      will almost always be zero, but odd things can happen when labels
@@ -1832,14 +1837,34 @@ merge_if_block (test_bb, then_bb, else_bb, join_bb)
 
   if (! join_bb)
     {
+      rtx last = combo_bb->end;
+
       /* The outgoing edge for the current COMBO block should already
         be correct.  Verify this.  */
       if (combo_bb->succ == NULL_EDGE)
-       abort ();
+       {
+         if (find_reg_note (last, REG_NORETURN, NULL))
+           ;
+         else if (GET_CODE (last) == INSN
+                  && GET_CODE (PATTERN (last)) == TRAP_IF
+                  && TRAP_CONDITION (PATTERN (last)) == const_true_rtx)
+           ;
+         else
+           abort ();
+       }
 
-      /* There should still be a branch at the end of the THEN or ELSE
+      /* There should still be something at the end of the THEN or ELSE
          blocks taking us to our final destination.  */
-      if (GET_CODE (combo_bb->end) != JUMP_INSN)
+      else if (GET_CODE (last) == JUMP_INSN)
+       ;
+      else if (combo_bb->succ->dest == EXIT_BLOCK_PTR
+              && GET_CODE (last) == CALL_INSN
+              && SIBLING_CALL_P (last))
+       ;
+      else if ((combo_bb->succ->flags & EDGE_EH)
+              && can_throw_internal (last))
+       ;
+      else
        abort ();
     }
 
@@ -2069,7 +2094,7 @@ find_cond_trap (test_bb, then_edge, else_edge)
   /* ??? We can't currently handle merging the blocks if they are not
      already adjacent.  Prevent losage in merge_if_block by detecting
      this now.  */
-  if (then_bb->succ == NULL)
+  if ((trap = block_has_only_trap (then_bb)) != NULL)
     {
       trap_bb = then_bb;
       if (else_bb->index != then_bb->index + 1)
@@ -2077,7 +2102,7 @@ find_cond_trap (test_bb, then_edge, else_edge)
       join_bb = else_bb;
       else_bb = NULL;
     }
-  else if (else_bb->succ == NULL)
+  else if ((trap = block_has_only_trap (else_bb)) != NULL)
     {
       trap_bb = else_bb;
       if (else_bb->index != then_bb->index + 1)
@@ -2091,18 +2116,6 @@ find_cond_trap (test_bb, then_edge, else_edge)
   else
     return FALSE;
 
-  /* Don't confuse a conditional return with something we want to
-     optimize here.  */
-  if (trap_bb == EXIT_BLOCK_PTR)
-    return FALSE;
-
-  /* The only instruction in the THEN block must be the trap.  */
-  trap = first_active_insn (trap_bb);
-  if (! (trap == trap_bb->end
-        && GET_CODE (PATTERN (trap)) == TRAP_IF
-         && TRAP_CONDITION (PATTERN (trap)) == const_true_rtx))
-    return FALSE;
-
   if (rtl_dump_file)
     {
       if (trap_bb == then_bb)
@@ -2149,26 +2162,55 @@ find_cond_trap (test_bb, then_edge, else_edge)
   if (seq == NULL)
     return FALSE;
 
-  /* Emit the new insns before cond_earliest; delete the old jump
-     and trap insns.  */
-
+  /* Emit the new insns before cond_earliest; delete the old jump.  */
   emit_insn_before (seq, cond_earliest);
-
   delete_insn (jump);
 
-  delete_insn (trap);
+  /* Delete the trap block together with its insn.  */
+  if (trap_bb == then_bb)
+    then_bb = NULL;
+  else if (else_bb == NULL)
+    ;
+  else if (trap_bb == else_bb)
+    else_bb = NULL;
+  else
+    abort ();
+  flow_delete_block (trap_bb);
+  num_removed_blocks++;
 
-  /* Merge the blocks!  */
-  if (trap_bb != then_bb && ! else_bb)
-    {
-      flow_delete_block (trap_bb);
-      num_removed_blocks++;
-    }
+  /* Merge what's left.  */
   merge_if_block (test_bb, then_bb, else_bb, join_bb);
 
   return TRUE;
 }
 
+/* Subroutine of find_cond_trap: if BB contains only a trap insn, 
+   return it.  */
+
+static rtx
+block_has_only_trap (bb)
+     basic_block bb;
+{
+  rtx trap;
+
+  /* We're not the exit block.  */
+  if (bb == EXIT_BLOCK_PTR)
+    return NULL_RTX;
+
+  /* The block must have no successors.  */
+  if (bb->succ)
+    return NULL_RTX;
+
+  /* The only instruction in the THEN block must be the trap.  */
+  trap = first_active_insn (bb);
+  if (! (trap == bb->end
+        && GET_CODE (PATTERN (trap)) == TRAP_IF
+         && TRAP_CONDITION (PATTERN (trap)) == const_true_rtx))
+    return NULL_RTX;
+
+  return trap;
+}
+
 /* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
    transformable, but not necessarily the other.  There need be no
    JOIN block.
index 9c6bd86..2a2aeda 100644 (file)
@@ -1,3 +1,9 @@
+2002-04-18  Richard Henderson  <rth@redhat.com>
+
+        * gcc.c-torture/compile/iftrap-1.c: New.
+        * gcc.dg/iftrap-1.c: Adjust for ia64.
+        * gcc.dg/iftrap-2.c: New.
+
 2002-04-18  Jakub Jelinek  <jakub@redhat.com>
 
        * gcc.c-torture/compile/20020418-1.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/compile/iftrap-1.c b/gcc/testsuite/gcc.c-torture/compile/iftrap-1.c
new file mode 100644 (file)
index 0000000..a0adc78
--- /dev/null
@@ -0,0 +1,99 @@
+/* Verify that ifcvt doesn't crash under a number of interesting conditions. */
+
+void f1(int p)
+{
+  if (p)
+    __builtin_trap();
+}
+
+void f2(int p)
+{
+  if (p)
+    __builtin_trap();
+  else
+    bar();
+}
+
+void f3(int p)
+{
+  if (p)
+    bar();
+  else
+    __builtin_trap();
+}
+
+void f4(int p, int q)
+{
+  if (p)
+    {
+      bar();
+      if (q)
+       bar();
+    }
+  else
+    __builtin_trap();
+}
+
+void f5(int p)
+{
+  if (p)
+    __builtin_trap();
+  else
+    abort();
+}
+
+void f6(int p)
+{
+  if (p)
+    abort();
+  else
+    __builtin_trap();
+}
+
+void f7(int p)
+{
+  if (p)
+    __builtin_trap();
+  else
+    __builtin_trap();
+}
+
+void f8(int p)
+{
+  if (p)
+    __builtin_trap();
+  else
+    {
+      bar();
+      __builtin_trap();
+    }
+}
+
+void f9(int p)
+{
+  if (p)
+    {
+      bar();
+      __builtin_trap();
+    }
+  else
+    __builtin_trap();
+}
+
+void f10(int p)
+{
+  if (p)
+    __builtin_trap();
+  while (1)
+    bar();
+}
+
+void f11(int p)
+{
+  if (p)
+    __builtin_trap();
+  else
+    bar();
+  while (1)
+    baz();
+}
index b6abfc4..69d754d 100644 (file)
@@ -1,7 +1,7 @@
 /* Verify that we optimize to conditional traps.  */
 /* { dg-options "-O" } */
-/* { dg-do compile { target rs6000-*-* powerpc-*-* sparc*-*-* } } */
-/* { dg-final { scan-assembler-not "^\t(trap|ta)\[ \t\]" } } */
+/* { dg-do compile { target rs6000-*-* powerpc-*-* sparc*-*-* ia64-*-* } } */
+/* { dg-final { scan-assembler-not "^\t(trap|ta|break)\[ \t\]" } } */
 
 void f1(int p)
 {
diff --git a/gcc/testsuite/gcc.dg/iftrap-2.c b/gcc/testsuite/gcc.dg/iftrap-2.c
new file mode 100644 (file)
index 0000000..909a85f
--- /dev/null
@@ -0,0 +1,20 @@
+/* Verify that we optimize to conditional traps.  */
+/* { dg-options "-O" } */
+/* { dg-do compile { target rs6000-*-* powerpc-*-* sparc*-*-* ia64-*-* } } */
+/* { dg-final { scan-assembler-not "^\t(trap|ta|break)\[ \t\]" } } */
+
+void f1(int p)
+{
+  if (p)
+    __builtin_trap();
+  else
+    abort();
+}
+
+void f2(int p)
+{
+  if (p)
+    abort();
+  else
+    __builtin_trap();
+}