https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62117

            Bug ID: 62117
           Summary: [4.9 regression] wrong code for passing small array
                    argument'Address, in generic
           Product: gcc
           Version: 4.9.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: ada
          Assignee: unassigned at gcc dot gnu.org
          Reporter: demoonlit at panathenaia dot halfmoon.jp

Created attachment 33306
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33306&action=edit
minimal bug triggering source code

When instantiating a generic function like below, with a small array type
placed in register, according to x86_64 System V calling convension,

   generic
      type Key_Type is limited private;
   function Compare (Left, Right : Key_Type) return Integer;

'Address attributes of arguments point wrong place.
The compiler probably has forgotten to store the arguments to memory.

For example, if the body calls memcmp,

   function Compare (Left, Right : Key_Type) return Integer is
   begin
      return memcmp (Left'Address, Right'Address, Key_Type'Size / 8);
   end Compare;

The generated code compiled with -S -Og:

==== gcc-4.9 ====
_inst__compare:
LFB1:
    subq    $40, %rsp
LCFI0:
    movq    %rsp, %rsi  # Left and Right are passed by %rdi and %rsi
    leaq    16(%rsp), %rdi # but this generated code overwrites them
    movl    $4, %edx
    call    _memcmp
    addq    $40, %rsp
LCFI1:
    ret

This bug has appeared from gcc-4.9. gcc-4.8 is ok.

=== gcc-4.8 ====
_inst__compare:
LFB1:
    subq    $40, %rsp
LCFI0:
    movl    %edi, 16(%rsp) # Left and Right are stored on the stack
    movl    %esi, (%rsp)
    movq    %rsp, %rsi
    leaq    16(%rsp), %rdi
    movl    $4, %edx
    call    _memcmp
    addq    $40, %rsp
LCFI1:
    ret

Reply via email to