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]

[patch] Fix PR middle-end/38981


Hi,

this is a regression present on the mainline for Solaris 8 hosts.  The 
comparator function compare_pairs in tree-ssa-coalesce.c is invoked on 
out-of-bounds addresses by the libc qsort.  This is a known Solaris issue 
which arises when the comparator fails to impose a total order on the array.

The problem is that the costs (supposed to be positive) can overflow at -O0:

(gdb) p cl->sorted[0].cost
$29 = 2147483646
(gdb) p cl->sorted[1].cost
$30 = -2147483644
(gdb) p cl->sorted[2].cost
$31 = -2147483648
(gdb) p cl->sorted[3].cost
$32 = 2
(gdb) p cl->sorted[4].cost
$33 = -2147483648
(gdb) p cl->sorted[5].cost
$34 = 2
(gdb) p cl->sorted[6].cost
$35 = 2147483646
(gdb) p cl->sorted[7].cost
$36 = 2147483646

because of the (MUST_COALESCE_COST - 1) in

  /* We need to coalesce all names originating same SSA_NAME_VAR
     so debug info remains undisturbed.  */
  if (!optimize)
    {
      ssa_name_hash = htab_create (10, hash_ssa_name_by_var,
      				   eq_ssa_name_by_var, NULL);
      for (i = 1; i < num_ssa_names; i++)
	{
	  tree a = ssa_name (i);

	  if (a && SSA_NAME_VAR (a) && !DECL_ARTIFICIAL (SSA_NAME_VAR (a)))
	    {
	      tree *slot = (tree *) htab_find_slot (ssa_name_hash, a, INSERT);

	      if (!*slot)
		*slot = a;
	      else
		{
		  add_coalesce (cl, SSA_NAME_VERSION (a), SSA_NAME_VERSION (*slot),
				MUST_COALESCE_COST - 1);


The proposed fix is to cap the costs at MUST_COALESCE_COST-1 in add_coalesce.
Tested on x86-64_suse-linux, OK for mainline?


2009-02-08  Eric Botcazou  <ebotcazou@adacore.com>

	PR middle-end/38981
	* tree-ssa-coalesce.c (add_coalesce): Cap the costs of coalesce pairs
	at MUST_COALESCE_COST-1 instead of MUST_COALESCE_COST.


2009-02-08  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc.c-torture/compile/20090208-1.c: New test.


-- 
Eric Botcazou
/* PR middle-end/38981 */
/* Reporter: Kamaraju Kusumanchi <kamaraju@gmail.com> */

struct d_info
{
  int **subs;
};

static int *
d_substitution (struct d_info *di, int prefix)
{
  char c;

	c='_';

  if (c == '_')
    {
      unsigned int id;

      if (c != '_')
	{
	  do
	    {
	      unsigned int new_id;

	      if (new_id < id)
		return 0;
	      id = new_id;
	    }
	  while (c != '_');
	}



      return di->subs[id];
    }
  else
    {
      int verbose;
      int code;
      int simple_len;

	code=0;
	simple_len=0;
	verbose=0;
      if (! code && prefix)
	{
	  char peek;
		peek='A';

	  if (peek == 'C' || peek == 'D')
	    verbose = 1;
	}

	      if (verbose)
		{
		  code = simple_len;
		}

    }
}
Index: tree-ssa-coalesce.c
===================================================================
--- tree-ssa-coalesce.c	(revision 143923)
+++ tree-ssa-coalesce.c	(working copy)
@@ -284,8 +284,7 @@ add_cost_one_coalesce (coalesce_list_p c
 /* Add a coalesce between P1 and P2 in list CL with a cost of VALUE.  */
 
 static inline void 
-add_coalesce (coalesce_list_p cl, int p1, int p2,
-	      int value)
+add_coalesce (coalesce_list_p cl, int p1, int p2, int value)
 {
   coalesce_pair_p node;
 
@@ -295,13 +294,13 @@ add_coalesce (coalesce_list_p cl, int p1
 
   node = find_coalesce_pair (cl, p1, p2, true);
 
-  /* Once the value is MUST_COALESCE_COST, leave it that way.  */
-  if (node->cost != MUST_COALESCE_COST)
+  /* Once the value is at least MUST_COALESCE_COST - 1, leave it that way.  */
+  if (node->cost < MUST_COALESCE_COST - 1)
     {
-      if (value == MUST_COALESCE_COST)
-	node->cost = value;
-      else
+      if (value < MUST_COALESCE_COST - 1)
 	node->cost += value;
+      else
+	node->cost = value;
     }
 }
 

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