Recent

Author Topic: Another L2 optimizer bug  (Read 6945 times)

Nitorami

  • Sr. Member
  • ****
  • Posts: 481
Another L2 optimizer bug
« on: July 14, 2021, 10:18:19 pm »
I made a minor modification to my rather old and well tested FFT unit, and suddenly got an error 216 at runtime, when having compiled with optimisation level 2. Range Check ON makes the issue disappear, so this is NOT an issue related to violation of array bounds or similar.

I stripped the code down into a small compilable program, and am fairly certain this is a bug in the L2 optimiser. The behaviour is strange, the error happens in line 42 but disappears when making trivial changes almost anywhere in procedure FFT. I did not manage to reduce the code any further without the issue diappearing.

Can someone please confirm before I file a bug report. I used the textmode IDE under  windows, FPC 3.2.0, i386-win32. Settings which matter are optimizer level 2, range checks OFF, generate smaller code OFF, integer overflow checking OFF.

Or just compile with fpc -O2 crashme, and run.

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}
  2. type  float   = double;
  3.       complex = record re, im: float; end;
  4.       TRealVec    = array of float;
  5.       TComplexVec = array of complex;
  6.  
  7.  
  8. var  TwiTab: TComplexVec;
  9.  
  10. procedure CalcTable (len: longint);
  11. begin
  12.   SetLength (TwiTab, len);
  13.   writeln ('TwiTab set to size ',len);
  14. end;
  15.  
  16. function WindowVec (len: longint): TRealVec;
  17. begin
  18.   SetLength (result, len);
  19.   writeln ('Result set to size ',len);
  20. end;
  21.  
  22.  
  23. procedure FFT (const Z: TRealVec; var OutVec: TComplexVec);
  24. var j, i, M, Half_M: longint;
  25.     V1, V2, W1, W2 : complex;
  26.     scale: float;
  27.     WinVec: TRealVec;
  28.     BufVec: TComplexVec;
  29. begin
  30.   M   := length (Z);
  31.   if (M <= 1) or (M and (M-1) <> 0) then halt;
  32.  
  33.   Half_M := M div 2;
  34.   SetLength (OutVec, M);
  35.   SetLength (BufVec, Half_M);
  36.  
  37.   scale :=  sqrt(2)/Half_M/4;
  38.   WinVec := WindowVec (M);
  39.   for i := 0 to Half_M-1 do begin
  40.     Bufvec[i].Re := Z[2*i  ] * WinVec[2*i]   * scale; // runtime error 216 here
  41.     Bufvec[i].Im := Z[2*i+1] * WinVec[2*i+1] * scale;
  42.   end;
  43.   CalcTable (Half_M);
  44.   writeln ('We never arrive at this point ');
  45.   //we never arrive here, but nonetheless changes to the code further down solve the issue
  46.  
  47.  
  48.   SetLength (BufVec, Half_M+1);
  49.   BufVec[Half_M] := BufVec[0];
  50.   for i := 0 to Half_M -1 do begin
  51.     j := Half_M-i;
  52.     V1.re :=  BufVec[i].re + BufVec[j].re;
  53.     V1.im :=  BufVec[i].im - BufVec[j].im;
  54.     V2.re :=  BufVec[i].im + BufVec[j].im;
  55.     V2.im := -BufVec[i].re + BufVec[j].re;
  56.     with TwiTab[i] do begin
  57.       OutVec[i].re := V1.re + V2.re * re + V2.im * im;
  58.       OutVec[i].im := V1.im + V2.im * re - V2.re * im;
  59.     end;
  60.   end;
  61.   for i := 1 to Half_M -1 do begin
  62. //    writeln (i:4,Half_M-i:4);  // dummy code here solves the issue in line 42
  63.     OutVec[M-i].re :=  OutVec[i].re;
  64.     OutVec[M-i].im := -OutVec[i].im;
  65.   end;
  66. end;
  67.  
  68. var Z: TRealVec;
  69.     C: TComplexVec;
  70.  
  71. begin
  72.    SetLength (Z,32);
  73.    FFT (Z, C);
  74. end.
  75.  

Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: Another L2 optimizer bug
« Reply #1 on: July 14, 2021, 10:49:17 pm »
I cannot make it crash with 3.2.2, or with trunk.
It does however crash with 3.2.0.

I compiled form commandline with -O2 -Cr-i-o-t-O-

Bart

Nitorami

  • Sr. Member
  • ****
  • Posts: 481
Re: Another L2 optimizer bug
« Reply #2 on: July 14, 2021, 10:58:10 pm »
It neither seems to crash with 3.0.4. I don't think therefore this is solved, the code may just happen to hit a rare problem in the compiler. Should I issue a bug report ?

Bart

  • Hero Member
  • *****
  • Posts: 5265
    • Bart en Mariska's Webstek
Re: Another L2 optimizer bug
« Reply #3 on: July 14, 2021, 11:59:16 pm »
If you cannot reproduce in 3.2.2 or trunk you should not file a bugreport IMO.

Bart

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Another L2 optimizer bug
« Reply #4 on: July 15, 2021, 03:09:38 am »
You seem to have a perfect sample for:
https://www.mail-archive.com/fpc-devel@lists.freepascal.org/msg40857.html
The title is wrong.  He obviously meant "3.2.0"

Please notify Gareth

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: Another L2 optimizer bug
« Reply #5 on: July 15, 2021, 08:54:48 am »
Yes, but that also happens in 3.2.2. Still, having a look could be worthwhile

PascalDragon

  • Hero Member
  • *****
  • Posts: 5444
  • Compiler Developer
Re: Another L2 optimizer bug
« Reply #6 on: July 15, 2021, 09:11:21 am »
Please notify Gareth

If it does not fail with 3.2.2, then not, cause what Gareth is chasing is something that fails in both 3.2.0 and 3.2.2, but not in trunk.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Another L2 optimizer bug
« Reply #7 on: July 15, 2021, 11:22:44 am »
Yes, but that also happens in 3.2.2. Still, having a look could be worthwhile

Yes, definitely.


Please notify Gareth

If it does not fail with 3.2.2, then not, cause what Gareth is chasing is something that fails in both 3.2.0 and 3.2.2, but not in trunk.

Considering the type of the bug and how small this sample is I think it should be checked. Why would you object? Two versions of the compiler are expected to emit different assembly. The optimization would be different and the bug could manifest itself in one version, but not the other, specially in such a small project.

Nitorami

  • Sr. Member
  • ****
  • Posts: 481
Re: Another L2 optimizer bug
« Reply #8 on: July 17, 2021, 10:31:25 pm »
It only seems to be an issue with the 32bit L2 optimizer, and probably does not exist in 64 bit. But who knows ? The issue is rather delicate to reproduce, this was a random finding and the error goes away when doing minor modifications to the code. It might indicate a deeper problem with the L2 optimizer.

As to the array initalisation, the error initially popped up in a larger code where the arrays are properly filled and used; I just stripped the code down to a small and comprehensive sample. I agree the arrays may contain garbage but that does not matter.

I will try to contact Gareth. Maybe he can use it.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: Another L2 optimizer bug
« Reply #9 on: July 17, 2021, 10:41:09 pm »
I will try to contact Gareth. Maybe he can use it.

I already mailed him a link to this discussion on thursday.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9754
  • Debugger - SynEdit - and more
    • wiki
Re: Another L2 optimizer bug
« Reply #10 on: July 17, 2021, 11:35:52 pm »
I get an access violation, not a run time error.

It goes away with
{$ImplicitExceptions off}
or
-OoNOREGVAR

This may be random off course, since any small change might affect it.

But I had a similar issue with 3.2.2 64bit.

Nitorami

  • Sr. Member
  • ****
  • Posts: 481
Re: Another L2 optimizer bug
« Reply #11 on: July 18, 2021, 02:58:55 pm »
@marcov: thanks

@martin_fr:
Precisely, I get "runtime error 216". This is an access violation (general protection fault).
Indeed it goes away with {$ImplicitExceptions off} and with -OoNOREGVAR but, interestingly, NOT when compiling from the textmode IDE with "Use register variables" unticked.

Thus, "Use register variables" does not seem to be the same as OoNOREGVAR, or maybe it is overridden by other IDE tickboxes. But that is a different issue.



marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11351
  • FPC developer.
Re: Another L2 optimizer bug
« Reply #12 on: July 18, 2021, 03:05:16 pm »
Probably "Use Register variables" adds -Or, and without it, it doesn't add anything.

But you want -Oonoregvar (the opposite of -Or) to disable regvar turned on by -O2.

 

TinyPortal © 2005-2018