View Issue Details

IDProjectCategoryView StatusLast Update
0036139FPCCompilerpublic2019-10-12 23:40
ReporterAlexanderAssigned ToJonas Maebe 
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Platformx86_64OSUbuntuOS Version18.04.3
Product Version3.0.4Product Build 
Target VersionFixed in Version3.3.1 
Summary0036139: Too aggressive optimization
DescriptionOptimizer drops branches and break down code flow.
This happens in some situations, looks as template "while <expr> do <action>;", while optimization is enabled.
Steps To Reproduceprogram test:
var v:longword;
begin
   if v=2 then while true do ;
end.

> fpc -a -al -Os test.pas
correct:
# [4] if v=2 then while true do ;
        cmpl $2,U_$P$PROGRAM_$$_V
        je .Lj3
        jmp .Lj4
.Lj3:
        jmp .Lj6
.Lj5:
.Lj6:
        jmp .Lj5
.Lj4:
# [5] end.

> fpc -a -al -Os -O1 test.pas
incorrect:
# [4] if v=2 then while true do ;
        cmpl $2,U_$P$PROGRAM_$$_V
        je .Lj5
.Lj5:
# [5] end.

> fpc -a -al -Os -O3 test.pas
more incorrect:
# [4] if v=2 then while true do ;
        cmpl $2,%eax
# [5] end.
TagsNo tags attached.
Fixed in Revision43175
FPCOldBugId
FPCTarget-
Attached Files

Activities

Akira1364

2019-10-10 23:13

reporter   ~0118484

Last edited: 2019-10-10 23:31

View 7 revisions

How is that incorrect, exactly?

At any optimization level, even -O4, if you put something after the while statement, it will be executed just as it should be, because "v" is not equal to 2, so the loop exits immediately.

If anything, FPC doesn't currently optimize aggressively *enough* here, because it doesn't recognize that it can just completely eliminate the entire pointless while loop from the assembler output.

Here's a Compiler Explorer link that compares FPC's output to a similar bit of code in C++, for example: https://godbolt.org/z/jJ0Zuz

Also, a runnable Wandbox link that shows even with an ancient version of FPC like 2.6.2, the while loop is passed over as it should be: https://wandbox.org/permlink/uTJHC9DwVC6sk6Qp

Alexander

2019-10-11 03:51

reporter   ~0118488

An example is just an example.
In my real project, I often use constructs:
if p <> nil then while func (p) do p:=p^.next; // linked list
if p <> nil then while func (p) do; // function call, function change pointer p
and so on.
The result was strange, so this optimization was found.

Also, loop "while ... do ;" used in embedded and/or multithreaded applications for event waiting. "While not flag, do nothing".

One more example, "-O3 -Os":
        if v = 2 then ;
        while true do ;
code is correct:
        cmpl $2,%eax
.Lj7:
        jmp .Lj7

Akira1364

2019-10-11 15:05

reporter   ~0118494

Last edited: 2019-10-11 17:24

View 3 revisions

What I'm saying is you haven't given a real, full example of code that actually *behaves* incorrectly when compiled and run.

You've just posted tiny snippets of assembler and arbitrarily deemed them "correct" or "incorrect".

Here's another couple of perfectly valid practical examples, doing a more complex version of the kind of thing you were describing at high optimization levels:

Showing the assembler output: https://godbolt.org/z/n0f_am
Runnable: https://wandbox.org/permlink/VZlPaXO4wbXcxZAg

Issue History

Date Modified Username Field Change
2019-10-05 16:18 Alexander New Issue
2019-10-10 23:13 Akira1364 Note Added: 0118484
2019-10-10 23:14 Akira1364 Note Edited: 0118484 View Revisions
2019-10-10 23:14 Akira1364 Note Edited: 0118484 View Revisions
2019-10-10 23:29 Akira1364 Note Edited: 0118484 View Revisions
2019-10-10 23:30 Akira1364 Note Edited: 0118484 View Revisions
2019-10-10 23:30 Akira1364 Note Edited: 0118484 View Revisions
2019-10-10 23:31 Akira1364 Note Edited: 0118484 View Revisions
2019-10-11 03:51 Alexander Note Added: 0118488
2019-10-11 15:05 Akira1364 Note Added: 0118494
2019-10-11 15:28 Akira1364 Note Edited: 0118494 View Revisions
2019-10-11 17:24 Akira1364 Note Edited: 0118494 View Revisions
2019-10-12 23:40 Jonas Maebe Assigned To => Jonas Maebe
2019-10-12 23:40 Jonas Maebe Status new => resolved
2019-10-12 23:40 Jonas Maebe Resolution open => fixed
2019-10-12 23:40 Jonas Maebe Fixed in Version => 3.3.1
2019-10-12 23:40 Jonas Maebe Fixed in Revision => 43175
2019-10-12 23:40 Jonas Maebe FPCTarget => -