This is the mail archive of the gcc@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]

extract_muldiv bug


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


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