Age | Commit message (Collapse) | Author |
|
|
|
|
|
|
|
This also provides a violent fix to a bug causing an invalid
addressing to be generated when indexing into a global variable.
The fix is not satisfactory, though, as bad code is generated
(instead of invalid code before).
|
|
|
|
The assertion was invalid, I was assuming il->blk was
b when writing it. The new assertion should be right:
If the loop level were to decrease we would get out of
a cycle in cfg, this should not be possible unless we
go through a block with more than 1 predecessor.
|
|
|
|
The assertion fails incorrectly on a block right
after the end of a loop.
|
|
|
|
|
|
|
|
|
|
|
|
This was not necessary as temporaries were never freed
and returned from an array zero initialized. But in the
coming load optimization, we sometimes free temporaries
by resetting fn->ntmp.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The casting to uint32_t made the code for comparing
two signed words invalid. Interestingly, this can
be fixed by casting to int32_t instead. Because
sign extension is monotonic, all the unsigned
comparisons remain valid.
CVC4 can even check that for us:
x, y : BITVECTOR(32);
QUERY BVLT(SX(x, 64), SX(y, 64)) <=> BVLT(x, y);
QUERY BVLE(SX(x, 64), SX(y, 64)) <=> BVLE(x, y);
QUERY BVGT(SX(x, 64), SX(y, 64)) <=> BVGT(x, y);
QUERY BVGE(SX(x, 64), SX(y, 64)) <=> BVGE(x, y);
|
|
The pass was not doing anything incorrect, but
it missed some opportunities to optimize. On
a copy heavy example I observed that, in the
output of the pass a phi of the following shape
remained:
%a =w phi @A %c, @B %a
Originally the phi for %a was:
%a =w phi @A %b, @B %a
Since %b was discovered a copy of %c, %a should
have been eliminated and replaced with %c.
I think the problem is that knowledge on the
first argument of the phi %a changes as the
algorithm progresses, a more detailed walk-
through follows.
In the first round of the algoritm, %a is
discovered to be a copy of its first argument
%b.
phi(%b, %a) -> %b
In the second round, %a is computed as the phi
of %c (since the first argument changed) and %b
(the result of the first iteration), in our
lattice, the glb of those two is bottom.
phi(%c, %b) -> %a (Bottom)
Finally, there is a third round in which we
compute %a as the phi of %a and %c, which again,
gives bottom.
phi(%c, %a) -> %a (Bottom)
The bug is not tied to a phi of a copy, for
example, if the first argument is speculated
to be a copy of 0 and then, this knowledge is
retracted; we will compute in sequence:
phi(0, %a) -> 0
phi(%b, 0) -> %a (Bottom)
phi(%b, %a) -> %a (Bottom)
The way I fixed this is by ignoring arguments
of the phi that were discovered to be copies of
the phi node itself. This will make the last
rounds above do the correct thing.
|
|
|
|
|
|
This happens to be needed for C. The standard mandates that a return
value is used if the caller uses it. Surprisingly, if the return
"value" is not used, the callee can use "return;".
A better solution is to add an "undef" value and return it, "undef"
would also have other use cases for compiling C.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The type sizes are important to get right because
the ABI relies on them when it emits memory blits
to pass/return structs.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AFL found this bug.
|
|
I thought it would be harder (and maybe it is).
My fear was that a call must be always followed by
a parallel move from machine registers (this is an
assumption in both spill and rega). This however
remains true, because the ABI code generates a
dummy "copy RAX" by accident!
|
|
|
|
|
|
|
|
|
|
|
|
AFL found that.
|