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.