* loop.c (insert_bct): Ensure loop_iteration_var non-zero before use.
[gcc.git] / gcc / loop.c
index f9a7d2e0a47cb1b0859bb704bf493902ed9414dc..556877feff9dfb5351a3f29219a03f97e2afb8d4 100644 (file)
@@ -291,6 +291,8 @@ static int reg_in_basic_block_p PROTO((rtx, rtx));
 static int consec_sets_invariant_p PROTO((rtx, int, rtx));
 static rtx libcall_other_reg PROTO((rtx, rtx));
 static int labels_in_range_p PROTO((rtx, int));
+static void count_one_set PROTO((rtx, rtx, varray_type, rtx *));
+
 static void count_loop_regs_set PROTO((rtx, rtx, varray_type, varray_type,
                                       int *, int)); 
 static void note_addr_stored PROTO((rtx, rtx));
@@ -7763,7 +7765,14 @@ get_condition (jump, earliest)
             like Alpha that have an IEEE compliant EQ instruction, and
             a non-IEEE compliant BEQ instruction.  The use of CCmode is
             actually artificial, simply to prevent the combination, but
-            should not affect other platforms.  */
+            should not affect other platforms.
+
+            However, we must allow VOIDmode comparisons to match either
+            CCmode or non-CCmode comparison, because some ports have
+            modeless comparisons inside branch patterns.
+
+            ??? This mode check should perhaps look more like the mode check
+            in simplify_comparison in combine.  */
 
          if ((GET_CODE (SET_SRC (set)) == COMPARE
               || (((code == NE
@@ -7781,8 +7790,9 @@ get_condition (jump, earliest)
 #endif
                     ))
                   && GET_RTX_CLASS (GET_CODE (SET_SRC (set))) == '<'))
-             && ((GET_MODE_CLASS (mode) == MODE_CC)
-                 == (GET_MODE_CLASS (inner_mode) == MODE_CC)))
+             && (((GET_MODE_CLASS (mode) == MODE_CC)
+                  == (GET_MODE_CLASS (inner_mode) == MODE_CC))
+                 || mode == VOIDmode || inner_mode == VOIDmode))
            x = SET_SRC (set);
          else if (((code == EQ
                     || (code == GE
@@ -7799,8 +7809,10 @@ get_condition (jump, earliest)
 #endif
                     ))
                   && GET_RTX_CLASS (GET_CODE (SET_SRC (set))) == '<'
-                  && ((GET_MODE_CLASS (mode) == MODE_CC)
-                      == (GET_MODE_CLASS (inner_mode) == MODE_CC)))
+                  && (((GET_MODE_CLASS (mode) == MODE_CC)
+                       == (GET_MODE_CLASS (inner_mode) == MODE_CC))
+                      || mode == VOIDmode || inner_mode == VOIDmode))
+
            {
              /* We might have reversed a LT to get a GE here.  But this wasn't
                 actually the comparison of data, so we don't flag that we
@@ -8042,12 +8054,21 @@ insert_bct (loop_start, loop_end)
      at compile time.  In this case we generate run_time calculation
      of the number of iterations.  */
 
+  if (loop_iteration_var == 0)
+    {
+      if (loop_dump_stream)
+       fprintf (loop_dump_stream,
+                "insert_bct %d: BCT Runtime Instrumentation failed: no loop iteration variable found\n",
+                loop_num);
+      return;
+    }
+
   if (GET_MODE_CLASS (GET_MODE (loop_iteration_var)) != MODE_INT
       || GET_MODE_SIZE (GET_MODE (loop_iteration_var)) != UNITS_PER_WORD)
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
-                "insert_bct %d: BCT Instrumentation failed: loop variable not integer\n",
+                "insert_bct %d: BCT Runtime Instrumentation failed: loop variable not integer\n",
                 loop_num);
       return;
     }
@@ -8057,7 +8078,7 @@ insert_bct (loop_start, loop_end)
     {
       if (loop_dump_stream)
        fprintf (loop_dump_stream,
-                "insert_bct %d: runtime bounds with != comparison\n",
+                "insert_bct %d: BCT Runtime Instrumentation failed: runtime bounds with != comparison\n",
                 loop_num);
       return;
     }