View Issue Details

IDProjectCategoryView StatusLast Update
0036427FPCCompilerpublic2019-12-12 20:24
ReporterNoNameAssigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Product Version3.3.1Product Build3.2.0-beta-r43619 
Target VersionFixed in Version 
Summary0036427: Unneccessary movl after compile time evaluation and wrong output lines for asm register allocation
DescriptionI've seen that optloadmodifystore.pas was mentioned in the mailing list, so I had a look at its code.
https://github.com/graemeg/freepascal/blob/master/compiler/optloadmodifystore.pas#L82
            { replace i:=i+k by inc(i,k)
                      i:=i-k by dec(i,k)
                      i:=i and/or/xor k by in_[and/or/xor]_assign_x_y(i,k)

https://github.com/graemeg/freepascal/blob/master/compiler/optloadmodifystore.pas#L182
            { replace i:=k+i by inc(i,k)
                      i:=k and/or/xor i by in_[and/or/xor]_assign_x_y(i,k)

1. Why doesn't the second one convert i:=k-i by dec(i,k) and then negate it? Or would that be slower?
2. Compile the code below with -al and notice:
# Var x located in register eax
# Var y located in register eax
# [14] y := 4;
    movl $4,%eax
# Var res1 located in register r12d
# [15] res1 := x-y;
    movl $3,%r12d
# [16] writeln(res1);

            - says x is located in register but it isn't (never used anyway so wrong #line output)
            - locates y in same register as x (y also never used, see below)
            - x and y are not needed anywhere as FPC uses compile time evaluation?!
            -> movl of $4 is unnecessary
Steps To Reproduceprogram x;

{$mode Delphi}

uses
  SysUtils;

var
  x, y: Integer;
  res1, res2: Integer;

begin
  x := 7;
  y := 4;
  res1 := x-y;
  writeln(res1);

  x := 7;
  y := 4;
  Dec(x,y);
  writeln(x);

  x := 7;
  y := 4;
  res2 := y-x;
  writeln(res2);

  x := 7;
  y := 4;
  Dec(y,x);
  writeln(y);
end.
Additional Informationcompiled with -O3:

    .file "y.pas"
# Begin asmlist al_procedures

.section .text.n_main
    .balign 16,0x90
.globl PASCALMAIN
    .type PASCALMAIN,@function
PASCALMAIN:
.globl main
    .type main,@function
main:
.Lc1:
# [y.pas]
# [12] begin
    pushq %rbx
    pushq %r12
    leaq -8(%rsp),%rsp
.Lc3:
# Var x located in register eax
# Var y located in register eax
# Var res1 located in register eax
# Var res2 located in register eax
    call fpc_initializeunits
# Var x located in register eax
# Var y located in register eax
# [14] y := 4;
    movl $4,%eax
# Var res1 located in register r12d
# [15] res1 := x-y;
    movl $3,%r12d
# [16] writeln(res1);
    call fpc_get_output
    movq %rax,%rbx
    movslq %r12d,%rdx
    movq %rbx,%rsi
    xorl %edi,%edi
    call fpc_write_text_sint
    call fpc_iocheck
    movq %rbx,%rdi
    call fpc_writeln_end
    call fpc_iocheck
# Var x located in register eax
# Var y located in register eax
# [19] y := 4;
    movl $4,%eax
# Var x located in register r12d
    movl $3,%r12d
# [21] writeln(x);
    call fpc_get_output
    movq %rax,%rbx
    movslq %r12d,%rdx
    movq %rbx,%rsi
    xorl %edi,%edi
    call fpc_write_text_sint
    call fpc_iocheck
    movq %rbx,%rdi
    call fpc_writeln_end
    call fpc_iocheck
# Var x located in register eax
# Var y located in register eax
# [24] y := 4;
    movl $4,%eax
# Var res2 located in register r12d
# [25] res2 := y-x;
    movl $-3,%r12d
# [26] writeln(res2);
    call fpc_get_output
    movq %rax,%rbx
    movslq %r12d,%rdx
    movq %rbx,%rsi
    xorl %edi,%edi
    call fpc_write_text_sint
    call fpc_iocheck
    movq %rbx,%rdi
    call fpc_writeln_end
    call fpc_iocheck
# Var x located in register eax
# Var y located in register eax
# [29] y := 4;
    movl $4,%eax
# Var y located in register r12d
    movl $-3,%r12d
# [31] writeln(y);
    call fpc_get_output
    movq %rax,%rbx
    movslq %r12d,%rdx
    movq %rbx,%rsi
    xorl %edi,%edi
    call fpc_write_text_sint
    call fpc_iocheck
    movq %rbx,%rdi
    call fpc_writeln_end
    call fpc_iocheck
# [32] end.
    call fpc_do_exit
    leaq 8(%rsp),%rsp
    popq %r12
    popq %rbx
    ret
.Lc2:
.Le0:
    .size main, .Le0 - main
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget-
Attached Files

Activities

Jonas Maebe

2019-12-12 20:24

manager   ~0119803

> 1. Why doesn't the second one convert i:=k-i by dec(i,k) and then negate it? Or would that be slower?

Please ask questions on the mailing lists or on the fora.

> - says x is located in register but it isn't (never used anyway so wrong #line output)

The information only shows the physical register corresponding to the virtual register to which the variable is initially assigned. That virtual (and hence physical) register can change over the course of the procedure, and that information is not written to the assembler file.

> - locates y in same register as x (y also never used, see below)

That's fine.

> - x and y are not needed anywhere as FPC uses compile time evaluation?!
> -> movl of $4 is unnecessary

Yes, there's a minor inefficiency.

Issue History

Date Modified Username Field Change
2019-12-12 10:15 NoName New Issue
2019-12-12 20:24 Jonas Maebe Note Added: 0119803
2019-12-12 20:24 Jonas Maebe Additional Information Updated View Revisions
2019-12-12 20:24 Jonas Maebe FPCTarget => -