Hi, While investigating PR78529, I came across the following issue: For the test-case: char *f(char *dest, char *src) { if (__builtin_strcpy (dest + 5, src) != (dest + 5)) __builtin_abort (); } gcc -O2 generates following assembly: f: .LFB0: .cfi_startproc leaq 5(%rdi), %rdx subq $8, %rsp .cfi_def_cfa_offset 16 movq %rdx, %rdi call strcpy cmpq %rax, %rax jne .L5 addq $8, %rsp .cfi_remember_state .cfi_def_cfa_offset 8 ret .L5: .cfi_restore_state call abort .cfi_endproc This seems to start after "pro_and_epligoue" pass, which contains the following insn in it's dump: (insn 14 29 15 2 (set (reg:CCZ 17 flags) (compare:CCZ (reg/f:DI 0 ax [orig:87 _1 ] [87]) (reg:DI 0 ax [92]))) "strcpy-foo.c":3 8 {*cmpdi_1} (nil)) full dump: http://pastebin.com/TGMRFGyw Thanks, Prathamesh
Well, it's really the inability to optimize away the comparison post-reload. Only the register allocator figures that the return value is equal to the arg. I'd have expected postreload-cse to handle this but it doesn't (it doesn't copy-propagate). jump2 faces (insn 14 29 15 2 (set (reg:CCZ 17 flags) (compare:CCZ (reg/f:DI 0 ax [orig:87 _1 ] [87]) (reg:DI 0 ax [92]))) "t.c":3 8 {*cmpdi_1} (expr_list:REG_DEAD (reg:DI 0 ax [92]) (nil))) but it doesn't seem to be able to do anything about it (maybe the pass name puts up hope too high...). That said, pass_postreload_cse should have done its job here.