Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2022-03

Broken code with PEEPHOLE & REGVAR

17 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Peter

I've been working with a fork of C-evo for a while now. Its been very stable for at least a year.
However, recently a game locked up in a (wide) cpu loop. The broken code is in the shared library, built with FPC 3.2.2, its nothing to do with Lazarus, except that Lazarus code calls the library.

I compiled a debug version to investigate and the problem went away. It seemed likely that the issue was optimisations, and sure enough, O1 is fine but O2 broken. Trying the optimisations individually I found that PEEPHOLE + REGVAR alone caused the problem. The code actually works fine at O4, providing either PEEPHOLE or REGVAR is disabled.

This is with x64 on Debian Linux, but the problem is also on Arch Linux, so nothing specific with the Debian build. Other options like Ct, Ci, Co, CR, Cr make no difference. I tried FPC versions back to 3.0.4, and the issue is still there, so its not a recent regression.

Its unlikely that I can reproduce this problem with a small program, but compiling the offending code to assembler, the problem seems rather obvious.

Its in a method function,

[500]  function TBarbarina.DoAttack(uix, AttackLoc: integer): boolean;

It seems that parameter AttackLoc is corrupted halfway through the routine, just after being used in an assignment,

[587]      TestLoc := AttackLoc;

If the parameter AttackLoc is used immediately after this statement, for example in a Writeln, its OK. But if not, its corrupted when used later.

The problem looks like the register allocator,
as at line 587 the assembler comment says that AttackLoc is now in r13d, but r13d has not been initialised. AttackLoc was in 83288(%rsp) up to this point.

Here is an extract of the assembler showing statements where AttackLoc is used (to around the point where the problem occurs)

.....

# Var uix located in register eax
    movl    %edx,%eax
    movq    %rax,83288(%rsp)
# Var AttackLoc located in register eax
# [503] var

.....

# [514] IsBombardment := AttackLoc = maNextCity;
    movl    83288(%rsp),%eax
    cmpl    $-1,%eax

.....

# [531] if (TestTime >= $800) or (AttackLoc = maNextCity) and (TestTime > $800 - 100) then     cmpl    $2048,%edx
    jge    .Lj281
    movl    83288(%rsp),%eax
    cmpl    $-1,%eax
    jne    .Lj284
    cmpl    $1948,%edx
    jg    .Lj281
.Lj284:

.....

# [548] AttackLoc := NextLoc;
    movl    %ebx,%eax
    movq    %rax,83288(%rsp)
.Lj298:
.Lj294:
# [550] if (NextLoc = AttackLoc) and ((MyModel[mix].Domain dSea) or     movl    83288(%rsp),%eax
    cmpl    %ebx,%eax
    jne    .Lj301
    movq    83272(%rsp),%rax
    movq    48(%rax),%rcx
    movq    83280(%rsp),%rax
    movzwl    14(%rax),%edx
    imulq    $68,%rdx,%rax
    cmpb    $1,17(%rcx,%rax)
    jne    .Lj302

.....

# [587] TestLoc := AttackLoc;
    movl    83288(%rsp),%eax
# Var AttackLoc located in register r13d        ****************** !!!!     movl    %eax,24(%rsp)

.....

# [605] until (NextLoc = AttackLoc) or (MoveResult and rExecuted = 0) or     cmpl    %r12d,%r13d
    je    .Lj332
    movl    %ebx,%eax
    andl    $1073741824,%eax
    je    .Lj332

.....

# [607] Result := (NextLoc = AttackLoc) and (MoveResult and rExecuted 0);     cmpl    %r12d,%r13d
    jne    .Lj338
    movl    %ebx,%eax
    andl    $1073741824,%eax
    je    .Lj338
    movb    $1,83240(%rsp)
    jmp    .Lj340
.Lj338:
    movb    $0,83240(%rsp)

.....

There are four source files, around 250k, to compile this library. I can supply them if anyone wants to investigate. Is this sufficient for a bug report?  Does anyone know of any existing bugs like this? Maybe already fixed?

I'll attach the source and assembler for this routine in a follow up mail.

Cheers,
Peter

Reply by email

Sven Barth
to Peter: I've been working with a fork of C-evo for a while now. Its been very stable for at least…

Peter via fpc-pascal schrieb am Do., 10.
März 2022, 23:39:

Show quoted text 5 lines
There are four source files, around 250k, to compile this library. I can supply them if anyone wants to investigate. Is this sufficient for a bug report? Does anyone know of any existing bugs like this? Maybe already fixed?

Would you please check whether it also occurs with 3.2.3 (which will become the next release soon) or 3.3.1 (the development version)?

Regards,
Sven

Reply by email

Peter
to Sven Barth
Sven Barth wrote 16 lines
Peter via fpc-pascal schrieb am Do., 10. März 2022, 23:39: There are four source files, around 250k, to compile this library. I can supply them if anyone wants to investigate. Is this sufficient for a bug report?  Does anyone know of any existing bugs like this? Maybe already fixed? Would you please check whether it also occurs with 3.2.3 (which will become the next release soon) or 3.3.1 (the development version)? Regards, Sven _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Hi Sven,

Pleased to report that with version
"Free Pascal Compiler version 3.3.1-10685-gf6ac49a139-unpushed-dirty [2022/03/08] for x86_64"

it seems fine.

Is there a prebuild Linux binary for 3.2.3/4 anywhere?

Cheers,
Peter

Reply by email

Sven Barth
to Peter

Peter via fpc-pascal schrieb am Fr., 11.
März 2022, 00:48:

Show quoted text 6 lines
Pleased to report that with version "Free Pascal Compiler version 3.3.1-10685-gf6ac49a139-unpushed-dirty [2022/03/08] for x86_64" it seems fine.

So it seems it was fixed in the interesting question is 3.2.3...

Is there a prebuild Linux binary for 3.2.3/4 anywhere?

No. But FPC isn't that hard to build: simply do a checkout of the repo and switch to fixes_3_2 (or download a repo of that branch). In there do a "make all FPMAKEOPT="-T <N>" OPT=-O2" and then "make install INSTALL_PREFIX=/where/you/want/it".
You then also need to adjust your fpc.cfg so that the compiler can find its units. Do a hello world test program to check whether everything works and then test your code.

Regards,
Sven

Reply by email

Peter
to Sven Barth
So it seems it was fixed in the interesting question is 3.2.3...

Hi Sven,

I found a 3.2.3 in ftp://ftp.freepascal.org/pub/fpc/snapshot/v32/x86_64-linux

Testing with version Free Pascal Compiler version 3.2.3 [2022/03/05] for x86_64

the problem is still there I'm afraid.

Regards,
Peter

Reply by email

Peter
to Peter

I had a look at the assembler generated by 3.3.1

.....

# Var uix located in stack [rsp+83240]
    movl    %edx,%eax
    movq    %rax,83280(%rsp)
# Var AttackLoc *located in stack [rsp+83280]*
# [503] var

.....

# [587] TestLoc := AttackLoc;
*movl    83280(%rsp),%r14d*                 # <<--------------******** # Var AttackLoc *located in register r14d*
    movl    %r14d,24(%rsp)
.....

AttackLoc location is changed to a register as before, but here it is actually moved with a movl. It seems the bug is caused by the absence of this movl instruction.

Cheers,
Peter

Reply by email

Sven Barth
to Peter

Peter via fpc-pascal schrieb am Fr., 11.
März 2022, 13:47:

Show quoted text 23 lines
I had a look at the assembler generated by 3.3.1 ..... # Var uix located in stack [rsp+83240] movl %edx,%eax movq %rax,83280(%rsp) # Var AttackLoc *located in stack [rsp+83280]* # [503] var ..... # [587] TestLoc := AttackLoc; *movl 83280(%rsp),%r14d* # <<--------------******** # Var AttackLoc *located in register r14d* movl %r14d,24(%rsp) ..... AttackLoc location is changed to a register as before, but here it is actually moved with a movl. It seems the bug is caused by the absence of this movl instruction.

If we could find out which revision fixed it we could merge that to 3.2.3 as well...

Regards,
Sven

Reply by email

Peter
to Florian Klämpfl
Florian Klämpfl wrote 12 lines
> Am 12.03.2022 um 12:05 schrieb Peter via fpc-pascal : > > Its looking like it was fixed in main somewhere between > > 31cd3df7 24 Jan, 2021 > & > 837b433a 28 Apr, 2021 Can you bisect it by any chance? See https://wiki.freepascal.org/FPC_git#bisect.27ing _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Hi Florian,

The problem was fixed with commit 503fc85d
  2021-04-06 florian  * patch by J. Gareth Moreton: handle register allocations correctly in MovMov2Mov 3, resolves #38703

https://gitlab.com/freepascal.org/fpc/source/-/issues/38703

Assembler for line 587 and surrounding comments from previous commit

# Peephole Optimization: MovMov2Mov 3 done
# Peephole Optimization: MovMovMov2MovMov 1 done
# [587] TestLoc := AttackLoc;
    movl    83288(%rsp),%eax
# Var AttackLoc located in register r13d
    movl    %eax,24(%rsp)
# Peephole Optimization: MovxMov2Movx

From commit 503fc85d 2021-04-06

# Peephole Optimization: MovMov2Mov 3 done
# [587] TestLoc := AttackLoc;
    movl    83288(%rsp),%r13d
# Var AttackLoc located in register r13d
# Peephole Optimization: MovMov2MovMov1 done
    movl    %r13d,24(%rsp)

In this example, although the compiler intends to use r13d for the parameter AttackLoc from line 587 onwards, it does not actually load that register, prior to fix for #38703

Cheers,
Peter

Reply by email

Florian Klämpfl
to Peter
Show quoted text 24 lines
Am 13.03.2022 um 16:26 schrieb Peter via fpc-pascal : On 12/03/2022 11:33, Florian Klämpfl via fpc-pascal wrote: > >> Am 12.03.2022 um 12:05 schrieb Peter via fpc-pascal : >> >> Its looking like it was fixed in main somewhere between >> >> 31cd3df7 24 Jan, 2021 >> & >> 837b433a 28 Apr, 2021 > Can you bisect it by any chance? See https://wiki.freepascal.org/FPC_git#bisect.27ing > _______________________________________________ > fpc-pascal maillist - > https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal Hi Florian, The problem was fixed with commit 503fc85d 2021-04-06 florian * patch by J. Gareth Moreton: handle register allocations correctly in MovMov2Mov 3, resolves #38703 https://gitlab.com/freepascal.org/fpc/source/-/issues/38703

Thanks for tracking this down! I have cherry picked the commit to fixes.

Reply by email

Sven Barth
to Peter

Peter via fpc-pascal schrieb am So., 13.
März 2022, 22:58:

Show quoted text 5 lines
On 13/03/2022 18:19, Florian Klämpfl via fpc-pascal wrote: > Thanks for tracking this down! I have cherry picked the commit to fixes. Great! It was a nasty bug. Good to see it fixed for the next release.

Would you please check whether it's indeed fixed with 3.2.3 now? Just in case the fix relied on something else...

Regards,
Sven

Reply by email

Peter
to Sven Barth
Sven Barth wrote 17 lines
Peter via fpc-pascal schrieb am So., 13. März 2022, 22:58: On 13/03/2022 18:19, Florian Klämpfl via fpc-pascal wrote: > Thanks for tracking this down! I have cherry picked the commit to fixes. Great! It was a nasty bug. Good to see it fixed for the next release. Would you please check whether it's indeed fixed with 3.2.3 now? Just in case the fix relied on something else... Regards, Sven _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Hi Sven,

I have checked with 3.2.3 and its fixed.

Cheers,
Peter

Reply by email

Peter
to Peter

Testing 3.2.3 on Arch Linux

# [584] if not AttackPositionReached then
    testb    %r15b,%r15b
    je    .Lj270
# [587] TestLoc := AttackLoc;
    movl    83288(%rsp),%r13d                # <----- *************** # Var AttackLoc located in register r13d
    movl    %r13d,24(%rsp)
# [591] NextLoc := PreLoc[TestLoc];

Reply by email

Sven Barth

Peter B schrieb am Di., 4. März 2025, 22:48:

Show quoted text 6 lines
Back in 2022, I did expect that the release 3.2.4, including this fix, would have been out by now. Is it possible, that this fix could be applied as a patch to 3.2.2 (which is what all the Linux distributions are still using). i.e. is the fix self contained, or mixed in with other 3.2.3/4 changes?

There won't be any patches for a release that is already released.

Also 3.2.4 is shortly before its first (and hopefully only) Release Candidate.

Regards,
Sven

Reply by email