This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix PR rtl-optimization/23454


We have screwed up a little with one.  This is a regression which was reported 
by the Debian folks against 4.0.2, a reduced testcase was distilled and a fix 
applied on the then mainline and 4.0 branch... but it didn't fix the original 
problem on the 4.0 branch.  Now the latter had already been fixed on the 
mainline a few months before!

Bootstrapped and regtested on sparc-sun-solaris2.8, applied to 4.0 branch.
Testcase also applied and comment updated on mainline and 4.1 branch.


2006-08-11  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR rtl-optimization/23454
	Backport from mainline
	2005-03-07  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* reorg.c (relax_delay_slots): Check that the jump is
	conditional before trying to invert it.


2006-08-11  Eric Botcazou  <ebotcazou@libertysurf.fr>

	* g++.dg/opt/pr23454-2.C: New test.


-- 
Eric Botcazou
Index: reorg.c
===================================================================
--- reorg.c	(revision 116012)
+++ reorg.c	(working copy)
@@ -3374,12 +3374,13 @@ relax_delay_slots (rtx first)
 	  continue;
 	}
 
-      /* See if this jump (with its delay slots) branches around another
-	 jump (without delay slots).  If so, invert this jump and point
-	 it to the target of the second jump.  We cannot do this for
-	 annulled jumps, though.  Again, don't convert a jump to a RETURN
-	 here.  */
+      /* See if this jump (with its delay slots) conditionally branches
+	 around an unconditional jump (without delay slots).  If so, invert
+	 this jump and point it to the target of the second jump.  We cannot
+	 do this for annulled jumps, though.  Again, don't convert a jump to
+	 a RETURN here.  */
       if (! INSN_ANNULLED_BRANCH_P (delay_insn)
+	  && any_condjump_p (delay_insn)
 	  && next && JUMP_P (next)
 	  && (simplejump_p (next) || GET_CODE (PATTERN (next)) == RETURN)
 	  && next_active_insn (target_label) == next_active_insn (next)
/* PR rtl-optimization/23454 */
/* Submitted by Matthias Klose <doko@debian.org> */

/* { dg-do compile } */
/* { dg-options "-O3" } */

typedef unsigned long long int ulonglong;
typedef long long int longlong;
typedef unsigned int uint32;
typedef unsigned int uint;
typedef unsigned long int ulong;

class Item {
public:
  bool null_value;
  virtual longlong val_int()=0;
};

typedef struct st_tree_element {
  struct st_tree_element *left,*right;
  uint32 count;
} TREE_ELEMENT;

typedef struct st_tree {
  uint offset_to_key,elements_in_tree,size_of_element,memory_limit,allocated;
  void *custom_arg;
  bool with_delete;
  uint flag;
} TREE;

class field_info
{
public:
  ulong treemem, tree_elements, empty, nulls, min_length, max_length;
  uint room_in_tree;
  bool found;
  TREE tree;
  Item *item;
};

class field_ulonglong: public field_info
{
  ulonglong min_arg, max_arg;
  ulonglong sum, sum_sqr;
  void add();
};

extern char *longlong10_to_str(longlong val,char *dst,int radix);
extern void delete_tree(TREE*);
extern TREE_ELEMENT *tree_insert(TREE *tree,void *custom_arg);

static int compare_ulonglong(const ulonglong *s, const ulonglong *t)
{
  return ((*s < *t) ? -1 : *s > *t ? 1 : 0);
}

void field_ulonglong::add()
{
  char buff[(255*3 +1)];
  longlong num = item->val_int();
  uint length = (uint) (longlong10_to_str(num, buff, 10) - buff);
  TREE_ELEMENT *element;

  if (item->null_value)
  {
    nulls++;
    return;
  }
  if (num == 0)
    empty++;

  if (room_in_tree)
  {
    if (!(element = tree_insert(&tree, tree.custom_arg)))
    {
      room_in_tree = 0;
      delete_tree(&tree);
    }
    else if (element->count == 1)
    {
      room_in_tree = 0;
      delete_tree(&tree);
    }
  }

  if (!found)
  {
    found = 1;
    min_arg = max_arg = sum = num;
    sum_sqr = num * num;
    min_length = max_length = length;
  }
  else if (num != 0)
  {
    sum += num;
    sum_sqr += num * num;
    if (length < min_length)
      min_length = length;
    if (length > max_length)
      max_length = length;
    if (compare_ulonglong((ulonglong*) &num, &min_arg) < 0)
      min_arg = num;
    if (compare_ulonglong((ulonglong*) &num, &max_arg) > 0)
      max_arg = num;
  }
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]