This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR middle-end/38981
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 9 Feb 2009 00:27:55 +0100
- Subject: [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;
}
}