Recent

Author Topic: Array enumeration bug with opmisation level 2 for target 80386 ?  (Read 1008 times)

Nitorami

  • Sr. Member
  • ****
  • Posts: 346
I have tracked down an obstinate bug in my program, and isolated it in a small piece of code, see below. Can someone please confirm with FPC3.0.4, win32, and the parameters -O2 -Op80386 -Mdelphi (or -Mobjfpc)

Procedure TMyClass.TestModes runs a loop over the 4 array elements of fOutputs and prints their length. The correct result should be
Quote
10
10
10
10

But with optimization level 2, and optimization target processor 80386, I get this
Quote
10
10
0
Runtime error 204 at $004034A0
  $004034A0
  $00401651

The issue is rather sensitive to small changes elsewhere in the code, and may be somewhat random. I did not manage to reproduce it with optimization off, nor when optimising for a different target processor than 80386, so I guess it is a compiler bug.

Code: Pascal  [Select]
  1. type TPoint = record x,y: integer; end;
  2.  
  3. type
  4.   TOutput = object
  5.     OName: Ansistring;
  6.     OConns  : integer;
  7.     TargetList    : array of TPoint;
  8.     procedure Init;
  9.   end;
  10.  
  11.   TMyClass = Class
  12.      fOutputs: array [0..3] of TOutput;
  13.      procedure TestModes;
  14.     constructor create;
  15.   end;
  16.  
  17. //-------------------------------
  18. procedure TOutput.Init;
  19. begin
  20.   OName := '';
  21.   OConns := 0;
  22.   SetLength (TargetList,10);
  23. end;
  24.  
  25. //-------------------------------
  26. constructor TMyClass.Create;
  27. var n: integer;
  28. begin
  29.   for n := 0 to high (fOutputs) do fOutputs[n].Init;
  30. end;
  31.  
  32. procedure TMyClass.TestModes;
  33. var  OP: TOutput;
  34. begin
  35.   for OP in fOutputs do begin  //Enumeration seems to go wrong
  36.     writeln (length(OP.Targetlist));
  37.   end;
  38. end;
  39.  
  40. //-------------------------------
  41. var C1: TMyClass;
  42. begin
  43.   C1 := TMyClass.Create;
  44.   C1.TestModes;
  45.   C1.Free;
  46. end.
  47.  

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 6608
Re: Array enumeration bug with opmisation level 2 for target 80386 ?
« Reply #1 on: July 29, 2018, 02:46:31 pm »
Yes. Trunk seems to have it also, please file it as bug on bugs.freepascal.org

ASerge

  • Hero Member
  • *****
  • Posts: 997
Re: Array enumeration bug with opmisation level 2 for target 80386 ?
« Reply #2 on: July 29, 2018, 03:13:34 pm »
Confirm. Win32. Found the difference

No optimization, without -Op80386. OK
Code: ASM  [Select]
  1. No optimization, without -Op80386:
  2. # [31] for n := 0 to high (fOutputs) do fOutputs[n].Init;
  3.         movl    $0,-12(%ebp)
  4.         subl    $1,-12(%ebp)
  5.         .balign 4,0x90
  6. .Lj40:
  7.         addl    $1,-12(%ebp)
  8.         movl    -8(%ebp),%edx
  9.         movl    -12(%ebp),%eax ; This OK
  10.         imull   $12,%eax,%eax
  11.         leal    4(%edx,%eax),%eax
  12.         call    P$PROGRAM$_$TOUTPUT_$__$$_INIT

No optimization, with -Op80386. OK
Code: ASM  [Select]
  1. # [31] for n := 0 to high (fOutputs) do fOutputs[n].Init;
  2.         movl    $0,-12(%ebp)
  3.         subl    $1,-12(%ebp)
  4.         .balign 4,0x90
  5. .Lj40:
  6.         addl    $1,-12(%ebp)
  7.         movl    -8(%ebp),%edx
  8.         movl    -12(%ebp),%eax
  9.         imull   $12,%eax,%eax  ; This OK
  10.         leal    4(%edx,%eax),%eax
  11.         call    P$PROGRAM$_$TOUTPUT_$__$$_INIT

Optimization, without -Op80386. OK
Code: ASM  [Select]
  1. # [31] for n := 0 to high (fOutputs) do fOutputs[n].Init;
  2.         movl    $0,-12(%ebp)
  3.         subl    $1,-12(%ebp)
  4.         .balign 4,0x90
  5. .Lj40:
  6.         addl    $1,-12(%ebp)
  7.         movl    -8(%ebp),%edx
  8.         movl    -12(%ebp),%eax
  9.         imull   $12,%eax,%eax  ; This OK
  10.         leal    4(%edx,%eax),%eax
  11.         call    P$PROGRAM$_$TOUTPUT_$__$$_INIT

Optimization, -Op80386. Error
Code: ASM  [Select]
  1. # [31] for n := 0 to high (fOutputs) do fOutputs[n].Init;
  2.         movl    $0,-12(%ebp)
  3.         subl    $1,-12(%ebp)
  4.         .balign 4,0x90
  5. .Lj40:
  6.         addl    $1,-12(%ebp)
  7.         movl    -8(%ebp),%edx
  8.         movl    -12(%ebp),%eax
  9.         leal    (,%eax,4),%eax  ; This eax*4
  10.         leal    (%eax,%eax,8),%eax; This eax*4 + (eax*4)*8 = eax*36
  11.         leal    4(%edx,%eax),%eax
  12.         call    P$PROGRAM$_$TOUTPUT_$__$$_INIT

With optimization and -Op80386 line 9,10 do multiplication by 36, not by 12.

Nitorami

  • Sr. Member
  • ****
  • Posts: 346
Re: Array enumeration bug with opmisation level 2 for target 80386 ?
« Reply #3 on: July 29, 2018, 03:23:04 pm »
Thanks. I'll file a bug report.

https://bugs.freepascal.org/view.php?id=34051
« Last Edit: July 29, 2018, 03:33:57 pm by Nitorami »