This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
extract_muldiv bug
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc at gcc dot gnu dot org
- Date: Mon, 7 Jul 2003 21:52:12 +0200
- Subject: extract_muldiv bug
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
Following testcase ICEs at -O2/-O3 on any 64-bit architecture I've tried,
on 3.2 branch/3.3 branch/trunk.
int x, *y, z, *p;
void
foo (void)
{
p = y + (8 * (x == 1 || x == 3) + z);
}
The problem seems to be in extract_muldiv, but before fixing it I'd like to
know whether convert()/extract_muldiv()/fold() etc. functions are allowed to
destroy its arguments if returning non-NULL or not, ie. if one does:
t1 = convert (sometype, t);
and t1 is != NULL, can t1 be thrown away and returned original t or not?
In the above testcase, the problem is extract_muldiv_1 <case PLUS_EXPR>:
4208 t1 = extract_muldiv (op0, c, code, wide_type);
4209 t2 = extract_muldiv (op1, c, code, wide_type);
4210 if (t1 != 0 && t2 != 0
&& SOMEFURTHERTESTS)
4216 return fold (build (tcode, ctype, convert (ctype, t1),
4217 convert (ctype, t2)));
normally use op0 and op1
op0 is <mult_expr[SI] <truth_orif_expr[SI] > <const_int[SI] 8>>
The first call to extract_muldiv returns
<mult_expr[DI] <truth_orif_expr[DI] > <const_int[DI] 8>>
but destroys its argument op0, which is now invalid
<mult_expr[SI] <truth_orif_expr[DI] > <const_int[DI] 8>>
(for MULT_EXPR new tree node has been created while the arguments
have been modified in situ somewhere deep in c_convert).
Now, second extract_muldiv returns NULL and t1 is thrown away,
but op0 is invalid and we later on die in explow.c trying to emit
the bogus tree into RTL.
So, either convert()/extract_muldiv()/fold() are supposed to be
non-destructive and then they needs to be fixed where they actually
destroy its arguments, or they are destructive and then I'm afraid
either above code needs to do a recursive tree copy before calling
extract_muldiv (as e.g. extract_muldiv calls fold() when returning
just about everything it means the tree can be modified even in big
depths) or there needs to be a code which performs an undo of the
operation (converts things back) or extract_muldiv needs to be done
in two phases, in first phase checking whether the topmost extract_muldiv
will use the modified tree or original tree and only if it will use modified
tree perform a second pass which would do what the function does ATM.
Jakub