------- Comment #2 from ebotcazou at gcc dot gnu dot org  2008-09-09 19:17 
-------
Several files are miscompiled by the stage1 compiler, starting with c-decl.c.
Now if you take the preprocessed file c-decl.i and compile it with a cross on
Linux, the resulting code is OK (the differences are in offsets against FP).

The discrepancy comes from the second qsort in ira_sort_regnos_for_alter_reg:

  /* Sort regnos according the slot numbers.  */
  regno_max_ref_width = reg_max_ref_width;
  qsort (pseudo_regnos, n, sizeof (int), coalesced_pseudo_reg_slot_compare);

It is not stable and this is quite obvious by looking at the compare function:

/* Sort pseudos according their slot numbers (putting ones with
  smaller numbers first, or last when the frame pointer is not
  needed).  */
static int
coalesced_pseudo_reg_slot_compare (const void *v1p, const void *v2p)
{
  const int regno1 = *(const int *) v1p;
  const int regno2 = *(const int *) v2p;
  ira_allocno_t a1 = ira_regno_allocno_map[regno1];
  ira_allocno_t a2 = ira_regno_allocno_map[regno2];
  int diff, slot_num1, slot_num2;
  int total_size1, total_size2;

  if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
    {
      if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
        return (const int *) v1p - (const int *) v2p; /* Save the order. */
      return 1;
    }
  else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
    return -1;
  slot_num1 = -ALLOCNO_HARD_REGNO (a1);
  slot_num2 = -ALLOCNO_HARD_REGNO (a2);
  if ((diff = slot_num1 - slot_num2) != 0)
    return (frame_pointer_needed
            || !FRAME_GROWS_DOWNWARD == STACK_GROWS_DOWNWARD ? diff : -diff);
  total_size1 = MAX (PSEUDO_REGNO_BYTES (regno1), regno_max_ref_width[regno1]);
  total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2), regno_max_ref_width[regno2]);
  if ((diff = total_size2 - total_size1) != 0)
    return diff;
  return (const int *) v1p - (const int *) v2p; /* Save the order. */
}

The following patchlet stabilizes the sort:

Index: ira-color.c
===================================================================
--- ira-color.c (revision 140145)
+++ ira-color.c (working copy)
@@ -2169,7 +2169,7 @@ coalesced_pseudo_reg_slot_compare (const
   if (a1 == NULL || ALLOCNO_HARD_REGNO (a1) >= 0)
     {
       if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
-       return (const int *) v1p - (const int *) v2p; /* Save the order. */
+       return regno1 - regno2;
       return 1;
     }
   else if (a2 == NULL || ALLOCNO_HARD_REGNO (a2) >= 0)
@@ -2183,7 +2183,7 @@ coalesced_pseudo_reg_slot_compare (const
   total_size2 = MAX (PSEUDO_REGNO_BYTES (regno2),
regno_max_ref_width[regno2]);
   if ((diff = total_size2 - total_size1) != 0)
     return diff;
-  return (const int *) v1p - (const int *) v2p; /* Save the order. */
+  return regno1 - regno2;
 }

 /* Setup REGNO_COALESCED_ALLOCNO_COST and REGNO_COALESCED_ALLOCNO_NUM

and the resulting code is the same (and correct) on both Linux and Solaris.

Bootstrap is still running, we'll see how far it goes after that.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37424

Reply via email to