[fpc-devel] Debugging Loop Unroll Optimization

Martok listbox at martoks-place.de
Thu May 17 18:01:26 CEST 2018

I think I found something, see below. Answering the question first ;-)

Am 16.05.2018 um 19:20 schrieb Florian Klämpfl:
> How big is the project? Normally, the number of unrolled loops is reasonable small so comparing the
> generated assembler with and without unrolling should be feasible.According to cloc, 40kLOC, 10kLOC of which are DSP code, not counting packages
that are not in the source repo. With the very spurious crashes, not the best
test case...

I did, however, do the insane thing and diff Lazarus (or rather, IDAs output).
There are a lot of unrolled loops in the LCL alone, but the code reordering for
the first 15% or so that I checked looks fine. {Off-Topic: could parts of that
variable rewriting be used for more aggressive inlining?}

Some more testing with Lazarus and -gt has shown that at some variables are
uninitialized with -Ooloopunroll. There is a fairly common case where removing
the variable is not good:
for Result:= alow to ahigh do
  if Something(Result) then exit;
If that gets unrolled, Result is undefined, and whatever it gets assigned to
receives the random content of r/eax.

I'm 90% sure that global variables and the Result variable are *not* supposed to
be undefined after the loop (in contrast to Delphi-compatible locals), but can't
seem to find a reference for that. This pattern is used all over the place, so
somebody else must have thought so too? Grepping for "for result:=" over the FPC
source tree gives 10 matches, Lazarus has over 100 results.

Test case:
{$Optimization LOOPUNROLL}

  i : integer;
  s : single;

function tfun: integer;
  for Result:=1 to 10 do

  for i:=1 to 2 do
  if i <> 2 then
  i:= tfun();
  if i <> 10 then
  if s <> 12 then

I would very much expect that to be the main cause of the observed crashes.


More information about the fpc-devel mailing list