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

            Bug ID: 70038
           Summary: [5.3.0 and 4.9.1]Wrong optimization with -O2
           Product: gcc
           Version: 5.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: 366899789 at qq dot com
  Target Milestone: ---

Compile the following code with -O2 -fdump-tree-optimized:

-------------------------
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>


void create_link(char *pfilename,
                const char *linkname, mode_t linktype,
                const char *prevlinkname)
{
        struct stat     stat_buf;

        if (stat(prevlinkname, &stat_buf) == 0)
        {
                unlink(prevlinkname);
        }
        printf("%p %s\n",prevlinkname,(prevlinkname ? "TRUE":"NULL"));
        if (stat(linkname, &stat_buf) == 0)
        {
                if (prevlinkname) {
                        rename(linkname, prevlinkname);
                        printf("%p %s\n",prevlinkname,(prevlinkname ?
"TRUE":"NULL"));
                }
                else {
                        unlink(linkname);
                }
        }
        if (linktype == S_IFLNK)
        {
                symlink(pfilename, linkname);
        }
        else
        {
                link(pfilename, linkname);
        }
}

int main(int argc,char *argv[])
{
        if(argc > 1) {
                create_link(argv[1], "link", S_IFLNK, NULL);
        }
        return 0;
}

-------------------------

~~~~~

Start binary with "./a.out test.sh"
test.sh is a exist file.
It will print: 
(nil) TRUE
(nil) TRUE, 
but expected output is:
(nil) NULL.

the assembly code is:
--------------------------
        .file   "test.c"
        .section        .rodata.str1.1,"aMS",@progbits,1
.LC0:
        .string "TRUE"
.LC1:
        .string "%p %s\n"
        .section        .text.unlikely,"ax",@progbits
.LCOLDB2:
        .text
.LHOTB2:
        .p2align 4,,15
        .globl  create_link
        .type   create_link, @function
create_link:
.LFB20:
        .cfi_startproc
        pushq   %r13
        .cfi_def_cfa_offset 16
        .cfi_offset 13, -16
        pushq   %r12
        .cfi_def_cfa_offset 24
        .cfi_offset 12, -24
        movq    %rdi, %r13
        pushq   %rbp
        .cfi_def_cfa_offset 32
        .cfi_offset 6, -32
        pushq   %rbx
        .cfi_def_cfa_offset 40
        .cfi_offset 3, -40
        movq    %rsi, %rbp
        movl    %edx, %r12d
        movq    %rcx, %rsi
        movl    $1, %edi
        subq    $152, %rsp
        .cfi_def_cfa_offset 192
        movq    %rcx, %rbx
        movq    %rsp, %rdx
        call    __xstat
        testl   %eax, %eax
        je      .L8
.L2:
        movl    $.LC0, %edx
        movq    %rbx, %rsi
        movl    $.LC1, %edi
        xorl    %eax, %eax
        call    printf
        movq    %rsp, %rdx
        movq    %rbp, %rsi
        movl    $1, %edi
        call    __xstat
        testl   %eax, %eax
        jne     .L3
        movq    %rbx, %rsi
        movq    %rbp, %rdi
        call    rename
        movl    $.LC0, %edx
        movq    %rbx, %rsi
        movl    $.LC1, %edi
        xorl    %eax, %eax
        call    printf
.L3:
        cmpl    $40960, %r12d
        movq    %rbp, %rsi
        movq    %r13, %rdi
        je      .L9
        call    link
        addq    $152, %rsp
        .cfi_remember_state
        .cfi_def_cfa_offset 40
        popq    %rbx
        .cfi_def_cfa_offset 32
        popq    %rbp
        .cfi_def_cfa_offset 24
        popq    %r12
        .cfi_def_cfa_offset 16
        popq    %r13
        .cfi_def_cfa_offset 8
        ret
        .p2align 4,,10
        .p2align 3
.L8:
        .cfi_restore_state
        movq    %rbx, %rdi
        call    unlink
        jmp     .L2
        .p2align 4,,10
        .p2align 3
.L9:
        call    symlink
        addq    $152, %rsp
        .cfi_def_cfa_offset 40
        popq    %rbx
        .cfi_def_cfa_offset 32
        popq    %rbp
        .cfi_def_cfa_offset 24
        popq    %r12
        .cfi_def_cfa_offset 16
        popq    %r13
        .cfi_def_cfa_offset 8
        ret
        .cfi_endproc
.LFE20:
        .size   create_link, .-create_link
        .section        .text.unlikely
.LCOLDE2:
        .text
.LHOTE2:
        .section        .rodata.str1.1
.LC3:
        .string "link"
        .section        .text.unlikely
.LCOLDB4:
        .section        .text.startup,"ax",@progbits
.LHOTB4:
        .p2align 4,,15
        .globl  main
        .type   main, @function
main:
.LFB21:
        .cfi_startproc
        cmpl    $1, %edi
        jle     .L13
        pushq   %rax
        .cfi_def_cfa_offset 16
        movq    8(%rsi), %rdi
        movl    $40960, %edx
        xorl    %ecx, %ecx
        movl    $.LC3, %esi
        call    create_link
        xorl    %eax, %eax
        popq    %rdx
        .cfi_def_cfa_offset 8
        ret
.L13:
        xorl    %eax, %eax
        ret
        .cfi_endproc
.LFE21:
        .size   main, .-main
        .section        .text.unlikely
.LCOLDE4:
        .section        .text.startup
.LHOTE4:
        .ident  "GCC: (GNU) 5.3.0"
        .section        .note.GNU-stack,"",@progbits
--------------------

and the optimized code is:
---------------------

;; Function create_link (create_link, funcdef_no=20, decl_uid=3254,
cgraph_uid=20, symbol_order=20)

Removing basic block 10
Removing basic block 11
create_link (char * pfilename, const char * linkname, mode_t linktype, const
char * prevlinkname)
{
  struct stat stat_buf;
  int _21;
  int _25;

  <bb 2>:
  _21 = __xstat (1, prevlinkname_7(D), &stat_buf);
  if (_21 == 0)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  unlink (prevlinkname_7(D));

  <bb 4>:
  printf ("%p %s\n", prevlinkname_7(D), "TRUE");
  _25 = __xstat (1, linkname_11(D), &stat_buf);
  if (_25 == 0)
    goto <bb 5>;
  else
    goto <bb 6>;

  <bb 5>:
  rename (linkname_11(D), prevlinkname_7(D));
  printf ("%p %s\n", prevlinkname_7(D), "TRUE");

  <bb 6>:
  if (linktype_16(D) == 40960)
    goto <bb 7>;
  else
    goto <bb 8>;

  <bb 7>:
  symlink (pfilename_17(D), linkname_11(D));
  goto <bb 9>;

  <bb 8>:
  link (pfilename_17(D), linkname_11(D));

  <bb 9>:
  stat_buf ={v} {CLOBBER};
  return;

}



;; Function main (main, funcdef_no=21, decl_uid=3259, cgraph_uid=21,
symbol_order=21) (executed once)

Removing basic block 5
main (int argc, char * * argv)
{
  char * _5;

  <bb 2>:
  if (argc_2(D) > 1)
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  _5 = MEM[(char * *)argv_4(D) + 8B];
  create_link (_5, "link", 40960, 0B);

  <bb 4>:
  return 0;

}
-----------------------

I tried it with "gcc 4.4.7" and it is correct.

Reply via email to