This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/86132] New: Failure to elide condition known to be non-null


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

            Bug ID: 86132
           Summary: Failure to elide condition known to be non-null
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: nathan at gcc dot gnu.org
  Target Milestone: ---

Created attachment 44268
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44268&action=edit
test case

x86_64 linux target using trunk:

trunk/obj/x86_64/gcc/cc1plus jay.ii -O3

Both single_slow() and single() implement a cache of an object that is
expensive to construct.  We know if we call either once, subsequent calls will
return the same value -- can the compiler tell?  (Ignore the problem of
operator new throwing, that's not important, alternatives that cannot thtor
show the same problem).

Yes and no.  a() is optimized down to a single inlined call of single().  b()
is not so fortunate and contains two inlined calls of single().

single_slow() is annotated to return non-null.  but its internals could well be
opaque.  single() is inlineable, and expected to be so.

Thus the value propagator should be able to determine that the assignment to
single::object of the result of single_slow(), assigns a non-null value.  It
manages to do this in the a() case, but not the b() case.  My guess is it
thinks that the call to want_foo(Foo &) could affect the value of
single::object.  But that's not possible.  It's function-local, its address
does not escape, and it has a single assignment only reachable when it is NULL.

_Z1av:
        cmpq    $0, _ZZ6singlevE6object(%rip)
        je      .L15   ;; the only test
        ret
.L15:
        subq    $8, %rsp
        call    _Z11single_slowv  ; the one call
        movq    %rax, _ZZ6singlevE6object(%rip)
        addq    $8, %rsp
        ret

_Z1bv:
        subq    $8, %rsp
        movq    _ZZ6singlevE6object(%rip), %rdi
        testq   %rdi, %rdi  ;; test one.
        je      .L20
.L17:
        call    _Z8want_fooR3Foo
        movq    _ZZ6singlevE6object(%rip), %rdi
        testq   %rdi, %rdi  ;; test two
        je      .L21
        addq    $8, %rsp
        jmp     _Z8want_fooR3Foo
.L20:
        call    _Z11single_slowv
        movq    %rax, %rdi
        movq    %rax, _ZZ6singlevE6object(%rip)
        jmp     .L17
.L21:
        call    _Z11single_slowv
        movq    %rax, _ZZ6singlevE6object(%rip)
        movq    %rax, %rdi
        addq    $8, %rsp
        jmp     _Z8want_fooR3Foo

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]