Bug 78579 - redundant instruction of the form cmp r0, r0 generated in assembly with -O2
Summary: redundant instruction of the form cmp r0, r0 generated in assembly with -O2
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 7.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2016-11-29 07:54 UTC by prathamesh3492
Modified: 2023-08-08 07:03 UTC (History)
1 user (show)

See Also:
Host: x86_64-unknown-linux-gnu
Target: x86_64-unknown-linux-gnu
Build: x86_64-unknown-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2023-08-08 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description prathamesh3492 2016-11-29 07:54:15 UTC
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
Comment 1 Richard Biener 2016-11-29 09:50:42 UTC
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.