re PR middle-end/15825 (if-cvt optimisation patch noce_try_sign_mask breaks apple...
authorRoger Sayle <roger@eyesopen.com>
Fri, 25 Jun 2004 18:40:07 +0000 (18:40 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Fri, 25 Jun 2004 18:40:07 +0000 (18:40 +0000)
PR middle-end/15825
* ifcvt.c (unshare_ifcvt_sequence): Rename to end_ifcvt_sequence.
Use get_isns and end_sequence instead of accepting a seq argument.
Scan the instruction sequence for unrecognizable or jump insns.
(noce_try_move, noce_try_store_flag, noce_try_store_flag_constants,
noce_try_addcc, noce_try_store_flag_mask, noce_try_cmove,
noce_try_cmove_arith, noce_try_minmax, noce_try_abs,
noce_try_sign_mask): Use end_ifcvt_sequence to factor common code.

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

From-SVN: r83671

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

index 8866356f536b2b84e241c04aa5b6b47da770d5f3..59d2771faf2548ce6dc70f3d8e8231a15c12592c 100644 (file)
@@ -1,3 +1,14 @@
+2004-06-25  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/15825
+       * ifcvt.c (unshare_ifcvt_sequence): Rename to end_ifcvt_sequence.
+       Use get_isns and end_sequence instead of accepting a seq argument.
+       Scan the instruction sequence for unrecognizable or jump insns.
+       (noce_try_move, noce_try_store_flag, noce_try_store_flag_constants,
+       noce_try_addcc, noce_try_store_flag_mask, noce_try_cmove,
+       noce_try_cmove_arith, noce_try_minmax, noce_try_abs,
+       noce_try_sign_mask): Use end_ifcvt_sequence to factor common code.
+
 2004-06-24  Jeff Law  <law@redhat.com>
 
        * gimplify.c (gimplify_compound_lval): Reset TREE_SIDE_EFFECTS
index 79774adc90a14267bf95642dad4e43eda5b83e8d..9de5961a29e02253eb7ca57d90303a3612960ac1 100644 (file)
@@ -699,14 +699,32 @@ noce_emit_move_insn (rtx x, rtx y)
                   GET_MODE_BITSIZE (inmode));
 }
 
-/* Unshare sequence SEQ produced by if conversion.  We care to mark
-   all arguments that may be shared with outer instruction stream.  */
-static void
-unshare_ifcvt_sequence (struct noce_if_info *if_info, rtx seq)
+/* Return sequence of instructions generated by if conversion.  This
+   function calls end_sequence() to end the current stream, ensures
+   that are instructions are unshared, recognizable non-jump insns.
+   On failure, this function returns a NULL_RTX.  */
+
+static rtx
+end_ifcvt_sequence (struct noce_if_info *if_info)
 {
+  rtx y;
+  rtx seq = get_insns ();
+
   set_used_flags (if_info->x);
   set_used_flags (if_info->cond);
   unshare_all_rtl_in_chain (seq);
+  end_sequence ();
+
+  if (seq_contains_jump (seq))
+    return NULL_RTX;
+
+  /* Make sure that all of the instructions emitted are recognizable.
+     As an excersise for the reader, build a general mechanism that
+     allows proper placement of required clobbers.  */
+  for (y = seq; y ; y = NEXT_INSN (y))
+    if (recog_memoized (y) == -1)
+      return NULL_RTX;
+  return seq;
 }
 
 /* Convert "if (a != b) x = a; else x = b" into "x = a" and
@@ -742,17 +760,9 @@ noce_try_move (struct noce_if_info *if_info)
        {
          start_sequence ();
          noce_emit_move_insn (if_info->x, y);
-         seq = get_insns ();
-         unshare_ifcvt_sequence (if_info, seq);
-         end_sequence ();
-
-         /* Make sure that all of the instructions emitted are
-            recognizable.  As an excersise for the reader, build
-            a general mechanism that allows proper placement of
-            required clobbers.  */
-         for (y = seq; y ; y = NEXT_INSN (y))
-           if (recog_memoized (y) == -1)
-             return FALSE;
+         seq = end_ifcvt_sequence (if_info);
+         if (!seq)
+           return FALSE;
 
          emit_insn_before_setloc (seq, if_info->jump,
                                   INSN_LOCATOR (if_info->insn_a));
@@ -795,11 +805,12 @@ noce_try_store_flag (struct noce_if_info *if_info)
       if (target != if_info->x)
        noce_emit_move_insn (if_info->x, target);
 
-      seq = get_insns ();
-      unshare_ifcvt_sequence (if_info, seq);
-      end_sequence ();
-      emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
+      seq = end_ifcvt_sequence (if_info);
+      if (! seq)
+       return FALSE;
 
+      emit_insn_before_setloc (seq, if_info->jump,
+                              INSN_LOCATOR (if_info->insn_a));
       return TRUE;
     }
   else
@@ -926,15 +937,12 @@ noce_try_store_flag_constants (struct noce_if_info *if_info)
       if (target != if_info->x)
        noce_emit_move_insn (if_info->x, target);
 
-      seq = get_insns ();
-      unshare_ifcvt_sequence (if_info, seq);
-      end_sequence ();
-
-      if (seq_contains_jump (seq))
+      seq = end_ifcvt_sequence (if_info);
+      if (!seq)
        return FALSE;
 
-      emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
-
+      emit_insn_before_setloc (seq, if_info->jump,
+                              INSN_LOCATOR (if_info->insn_a));
       return TRUE;
     }
 
@@ -978,11 +986,12 @@ noce_try_addcc (struct noce_if_info *if_info)
              if (target != if_info->x)
                noce_emit_move_insn (if_info->x, target);
 
-             seq = get_insns ();
-             unshare_ifcvt_sequence (if_info, seq);
-             end_sequence ();
+             seq = end_ifcvt_sequence (if_info);
+             if (!seq)
+               return FALSE;
+
              emit_insn_before_setloc (seq, if_info->jump,
-                                     INSN_LOCATOR (if_info->insn_a));
+                                      INSN_LOCATOR (if_info->insn_a));
              return TRUE;
            }
          end_sequence ();
@@ -1017,16 +1026,12 @@ noce_try_addcc (struct noce_if_info *if_info)
              if (target != if_info->x)
                noce_emit_move_insn (if_info->x, target);
 
-             seq = get_insns ();
-             unshare_ifcvt_sequence (if_info, seq);
-             end_sequence ();
-
-             if (seq_contains_jump (seq))
+             seq = end_ifcvt_sequence (if_info);
+             if (!seq)
                return FALSE;
 
              emit_insn_before_setloc (seq, if_info->jump,
-                                     INSN_LOCATOR (if_info->insn_a));
-
+                                      INSN_LOCATOR (if_info->insn_a));
              return TRUE;
            }
          end_sequence ();
@@ -1071,16 +1076,12 @@ noce_try_store_flag_mask (struct noce_if_info *if_info)
          if (target != if_info->x)
            noce_emit_move_insn (if_info->x, target);
 
-         seq = get_insns ();
-         unshare_ifcvt_sequence (if_info, seq);
-         end_sequence ();
-
-         if (seq_contains_jump (seq))
+         seq = end_ifcvt_sequence (if_info);
+         if (!seq)
            return FALSE;
 
          emit_insn_before_setloc (seq, if_info->jump,
-                                 INSN_LOCATOR (if_info->insn_a));
-
+                                  INSN_LOCATOR (if_info->insn_a));
          return TRUE;
        }
 
@@ -1169,11 +1170,12 @@ noce_try_cmove (struct noce_if_info *if_info)
          if (target != if_info->x)
            noce_emit_move_insn (if_info->x, target);
 
-         seq = get_insns ();
-         unshare_ifcvt_sequence (if_info, seq);
-         end_sequence ();
+         seq = end_ifcvt_sequence (if_info);
+         if (!seq)
+           return FALSE;
+
          emit_insn_before_setloc (seq, if_info->jump,
-                                 INSN_LOCATOR (if_info->insn_a));
+                                  INSN_LOCATOR (if_info->insn_a));
          return TRUE;
        }
       else
@@ -1334,9 +1336,10 @@ noce_try_cmove_arith (struct noce_if_info *if_info)
   else if (target != x)
     noce_emit_move_insn (x, target);
 
-  tmp = get_insns ();
-  unshare_ifcvt_sequence (if_info, tmp);
-  end_sequence ();
+  tmp = end_ifcvt_sequence (if_info);
+  if (!tmp)
+    return FALSE;
+
   emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR (if_info->insn_a));
   return TRUE;
 
@@ -1580,11 +1583,8 @@ noce_try_minmax (struct noce_if_info *if_info)
   if (target != if_info->x)
     noce_emit_move_insn (if_info->x, target);
 
-  seq = get_insns ();
-  unshare_ifcvt_sequence (if_info, seq);
-  end_sequence ();
-
-  if (seq_contains_jump (seq))
+  seq = end_ifcvt_sequence (if_info);
+  if (!seq)
     return FALSE;
 
   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
@@ -1698,11 +1698,8 @@ noce_try_abs (struct noce_if_info *if_info)
   if (target != if_info->x)
     noce_emit_move_insn (if_info->x, target);
 
-  seq = get_insns ();
-  unshare_ifcvt_sequence (if_info, seq);
-  end_sequence ();
-
-  if (seq_contains_jump (seq))
+  seq = end_ifcvt_sequence (if_info);
+  if (!seq)
     return FALSE;
 
   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
@@ -1768,11 +1765,12 @@ noce_try_sign_mask (struct noce_if_info *if_info)
     }
 
   noce_emit_move_insn (if_info->x, t);
-  seq = get_insns ();
-  unshare_ifcvt_sequence (if_info, seq);
-  end_sequence ();
-  emit_insn_before_setloc (seq, if_info->jump,
-                          INSN_LOCATOR (if_info->insn_a));
+
+  seq = end_ifcvt_sequence (if_info);
+  if (!seq)
+    return FALSE;
+
+  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
   return TRUE;
 }
 
index 49646705a99ad6cd81353511e8ada90ddbc1b944..048a30898060d064440381793ac6b301f8de61a1 100644 (file)
@@ -1,3 +1,8 @@
+2004-06-25  Roger Sayle  <roger@eyesopen.com>
+
+       PR middle-end/15825
+       * gcc.dg/pr15825-1.c: New test case.
+
 2004-06-25  Richard Sandiford  <rsandifo@redhat.com>
 
        * gcc.c-torture/execute/20040625-1.c: New test.
diff --git a/gcc/testsuite/gcc.dg/pr15825-1.c b/gcc/testsuite/gcc.dg/pr15825-1.c
new file mode 100644 (file)
index 0000000..a4b46d4
--- /dev/null
@@ -0,0 +1,18 @@
+/* PR middle-end/15825 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+unsigned int foo(long long high, int unsigned_p)
+{
+  int i;
+  if (high < 0)
+    if (!unsigned_p)
+    {
+      i = 1;
+      goto t;
+    }
+  i = 0;
+t:
+  return i;
+}
+