[PATCH] D80186: [Inliner] Update !associated metadata during inlining

Petr Hosek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 1 12:26:12 PDT 2020


phosek planned changes to this revision.
phosek added a comment.

So after testing this change a bit more, I found a fundamental issue which is the handling of cases when a function is inlined into multiple functions.

Say we have the following IR:

  @__inner_internal_metadata = private global [1 x i64] zeroinitializer, align 8, !associated !0
  
  define internal void @inner_internal() {
    %1 = load i64, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__inner_internal_metadata, i64 0, i64 1), align 8
    %2 = add i64 %1, 1
    store i64 %2, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__inner_internal_metadata, i64 0, i64 1), align 8
    ret void
  }
  
  define void @outer1() {
    call void @inner_internal()
    ret void
  }
  
  define void @outer2() {
    call void @inner_internal()
    ret void
  }
  
  !0 = !{void ()* @inner_internal}

Without this patch, we end up with:

  @__inner_internal_metadata = private global [1 x i64] zeroinitializer, align 8, !associated !0
  
  define void @outer1() {
    %1 = load i64, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__inner_internal_metadata, i64 1, i64 0), align 8
    %2 = add i64 %1, 1
    store i64 %2, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__inner_internal_metadata, i64 1, i64 0), align 8
    ret void
  }
  
  define void @outer2() {
    %1 = load i64, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__inner_internal_metadata, i64 1, i64 0), align 8
    %2 = add i64 %1, 1
    store i64 %2, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__inner_internal_metadata, i64 1, i64 0), align 8
    ret void
  }
  
  !0 = distinct !{null}

With this patch, we end up with:

  @__inner_internal_metadata = private global [1 x i64] zeroinitializer, align 8, !associated !0
  
  define void @outer1() {
    %1 = load i64, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__inner_internal_metadata, i64 1, i64 0), align 8
    %2 = add i64 %1, 1
    store i64 %2, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__inner_internal_metadata, i64 1, i64 0), align 8
    ret void
  }
  
  define void @outer2() {
    %1 = load i64, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__inner_internal_metadata, i64 1, i64 0), align 8
    %2 = add i64 %1, 1
    store i64 %2, i64* getelementptr inbounds ([1 x i64], [1 x i64]* @__inner_internal_metadata, i64 1, i64 0), align 8
    ret void
  }
  
  !0 = !{void ()* @outer2}

Both of these are wrong. In the first case we end up with broken metadata, in the second case the metadata is pointing only to a single function where it should be pointing to both. I'm not sure how to solve this, since there isn't a way to express this with `SHF_LINK_ORDER` since a single section could only be linked to a single section, but in this case we need a single section (with metadata) to be linked to multiple sections. Any thoughts?


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

https://reviews.llvm.org/D80186





More information about the llvm-commits mailing list