Another L2 optimizer bug lazarus / 62-General ---------------------------------------------------------------------- Nitorami · 2021-07-14 20:18 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$mode objfpc}type  float   = double;      complex = record re, im: float; end;      TRealVec    = array of float;      TComplexVec = array of complex;  var  TwiTab: TComplexVec; procedure CalcTable (len: longint);begin  SetLength (TwiTab, len);  writeln ('TwiTab set to size ',len);end; function WindowVec (len: longint): TRealVec;begin  SetLength (result, len);  writeln ('Result set to size ',len);end;  procedure FFT (const Z: TRealVec; var OutVec: TComplexVec);var j, i, M, Half_M: longint;    V1, V2, W1, W2 : complex;    scale: float;    WinVec: TRealVec;    BufVec: TComplexVec;begin  M   := length (Z);  if (M <= 1) or (M and (M-1) <> 0) then halt;   Half_M := M div 2;  SetLength (OutVec, M);  SetLength (BufVec, Half_M);   scale :=  sqrt(2)/Half_M/4;  WinVec := WindowVec (M);  for i := 0 to Half_M-1 do begin    Bufvec[i].Re := Z[2*i  ] * WinVec[2*i]   * scale; // runtime error 216 here    Bufvec[i].Im := Z[2*i+1] * WinVec[2*i+1] * scale;  end;  CalcTable (Half_M);  writeln ('We never arrive at this point ');  //we never arrive here, but nonetheless changes to the code further down solve the issue    SetLength (BufVec, Half_M+1);  BufVec[Half_M] := BufVec[0];  for i := 0 to Half_M -1 do begin    j := Half_M-i;    V1.re :=  BufVec[i].re + BufVec[j].re;    V1.im :=  BufVec[i].im - BufVec[j].im;    V2.re :=  BufVec[i].im + BufVec[j].im;    V2.im := -BufVec[i].re + BufVec[j].re;    with TwiTab[i] do begin      OutVec[i].re := V1.re + V2.re * re + V2.im * im;      OutVec[i].im := V1.im + V2.im * re - V2.re * im;    end;  end;  for i := 1 to Half_M -1 do begin//    writeln (i:4,Half_M-i:4);  // dummy code here solves the issue in line 42    OutVec[M-i].re :=  OutVec[i].re;    OutVec[M-i].im := -OutVec[i].im;  end;end; var Z: TRealVec;    C: TComplexVec; begin   SetLength (Z,32);   FFT (Z, C);end. ---------------------------------------------------------------------- Bart · 2021-07-14 20:49 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 · 2021-07-14 20:58 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 · 2021-07-14 21:59 If you cannot reproduce in 3.2.2 or trunk you should not file a bugreport IMO. Bart ---------------------------------------------------------------------- engkin · 2021-07-15 01:09 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 · 2021-07-15 06:54 Yes, but that also happens in 3.2.2. Still, having a look could be worthwhile ---------------------------------------------------------------------- PascalDragon · 2021-07-15 07:11 Quote from: engkin on July 15, 2021, 03:09:38 amPlease 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 · 2021-07-15 09:22 Quote from: marcov on July 15, 2021, 08:54:48 amYes, but that also happens in 3.2.2. Still, having a look could be worthwhile Yes, definitely. Quote from: PascalDragon on July 15, 2021, 09:11:21 amQuote from: engkin on July 15, 2021, 03:09:38 amPlease 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 · 2021-07-17 20:31 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 · 2021-07-17 20:41 Quote from: Nitorami on July 17, 2021, 10:31:25 pmI will try to contact Gareth. Maybe he can use it. I already mailed him a link to this discussion on thursday. ---------------------------------------------------------------------- Martin_fr · 2021-07-17 21:35 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 · 2021-07-18 12:58 @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 · 2021-07-18 13:05 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.