For the i386 stack probing feature there is a non-standard argument register
%eax used for internal __chkstk call. If the code is translate with gcc with
optimization level one or less, code is fine. For -O2 and higher, the argument
%eax for __chkstk is optimized out.

The following source is a short test-case for this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

void foo(char *str)
{
  int len = strlen ("ABCDE");
  int len2 = len + strlen (str);
  char *a = (char *) alloca(len);
  char *b = (char *) alloca(len2*3);

  memset (a,'x',len-1); a[len-1]=0;
  memset (b,'y',len2*3-1); b [len2*3-1]=0;
  printf ("%s %s\n", a, b);
}

For optimization -O2 the following assembler is produced (I mark the bad code
by  !):

        .file   ""
        .section .rdata,"dr"
LC0:
        .ascii "%s %s\12\0"
        .text
        .p2align 4,,15
.globl _foo
        .def    _foo;   .scl    2;      .type   32;     .endef
_foo:
        pushq   %rbp
        movq    %rsp, %rbp
        movq    %rsi, -16(%rbp)
        movq    %rdi, -8(%rbp)
        movq    %rbx, -24(%rbp)
        subq    $64, %rsp
        call    _strlen
        subq    $32, %rsp
!       leal    15(%rax,%rax,2), %ecx
        leaq    32(%rsp), %rsi
        movslq  %ecx,%rdi
        call    ___chkstk
        movl    $121, %edx
        leaq    32(%rsp), %rbx
        leal    -1(%rcx), %eax
        movl    $2021161080, (%rsi)
        movb    $0, 4(%rsi)
        movq    %rbx, %rcx
        movslq  %eax,%r8
        call    _memset
        leaq    LC0(%rip), %rcx
        movq    %rbx, %r8
        movq    %rsi, %rdx
        movb    $0, -1(%rbx,%rdi)
        call    _printf
        movq    -24(%rbp), %rbx
        movq    -16(%rbp), %rsi
        movq    -8(%rbp), %rdi
        leave
        ret
        .def    _strlen;        .scl    2;      .type   32;     .endef
        .def    _memset;        .scl    2;      .type   32;     .endef
        .def    _printf;        .scl    2;      .type   32;     .endef

For optimization -O1 correct assembly is produced:
        .file   ""
        .section .rdata,"dr"
LC0:
        .ascii "%s %s\12\0"
        .text
.globl _foo
        .def    _foo;   .scl    2;      .type   32;     .endef
_foo:
        pushq   %rbp
        movq    %rsp, %rbp
        movq    %rbx, -24(%rbp)
        movq    %rsi, -16(%rbp)
        movq    %rdi, -8(%rbp)
        subq    $96, %rsp
        movq    %rcx, %rdi
        movl    $0, %eax
        movq    $-1, %rcx
        repne scasb
        notq    %rcx
        leaq    32(%rsp), %rsi
        leal    12(%rcx,%rcx,2), %ecx
        movslq  %ecx,%rdi
        leaq    30(%rdi), %rax
        andq    $-16, %rax
        call    ___chkstk
        leaq    32(%rsp), %rbx
        movl    $2021161080, (%rsi)
        movb    $0, 4(%rsi)
        subl    $1, %ecx
        movslq  %ecx,%r8
        movl    $121, %edx
        movq    %rbx, %rcx
        call    _memset
        movb    $0, -1(%rbx,%rdi)
        movq    %rbx, %r8
        movq    %rsi, %rdx
        leaq    LC0(%rip), %rcx
        call    _printf
        movq    -24(%rbp), %rbx
        movq    -16(%rbp), %rsi
        movq    -8(%rbp), %rdi
        leave
        ret
        .def    _memset;        .scl    2;      .type   32;     .endef
        .def    _printf;        .scl    2;      .type   32;     .endef


-- 
           Summary: Optimization higher or eqaul to -O2 produce wrong code
           Product: gcc
           Version: 4.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: ktietz at gcc dot gnu dot org
GCC target triplet: 86_64-pc-mingw32


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36321

Reply via email to