[PATCH] D76140: [InlineFunction] update attributes during inlining

Johannes Doerfert via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 13 14:34:14 PDT 2020


jdoerfert added a comment.

In D76140#1922328 <https://reviews.llvm.org/D76140#1922328>, @anna wrote:

> In D76140#1922292 <https://reviews.llvm.org/D76140#1922292>, @reames wrote:
>
> > In D76140#1922162 <https://reviews.llvm.org/D76140#1922162>, @jdoerfert wrote:
> >
> > > In addition to @reames correctness concerns this is not valid for a different reason. You cannot backwards propagate information in the general case:
> > >
> > >   __attribute__((nonnull)) int *foo(int c) {
> > >      int *A = unknown();
> > >      int *B = unknown();
> > >      do_sth_with_ptr_and_may_use_nonnull(A, B);
> > >      return c ? A : B; // or if (C) return A; else return B;
> > >   }
> > >
> > >
> > > Knowing `foo` returns a `nonnull` value cannot be used to annotate `A` or `B`.
> >
> >
> > Good catch, I'd missed that.
>
>
> Just noticed this. I think we can special case this to: the return and def call are in the same basic block (it will take care of the if-else in the example) and has only one use which is the return. The latter takes care of avoiding incorrect semantics in that call `do_sth_with_ptr_and_may_use_nonnull`  or any other use that depends on knowing which of the ptr is non-null.


None of this is sufficient. We are repeating a lot of deduction logic here now...

Take:

  __attribute__((nonnull)) int *foo() {
      int *Base = unknown();
      do_sth_with_ptr_and_may_use_nonnull(Base);
      int *A = return_arg(/* returned */ Base);
      exit();
      return A;
  }

Return and call are in the same block, only a single use of A exists, however, backwards propagating `nonnull` to A is wrong and will be problematic if it is used to optimize Base.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76140/new/

https://reviews.llvm.org/D76140





More information about the llvm-commits mailing list