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.


fpc-devel maillist  -  fpc-devel@lists.freepascal.org

Reply via email to