[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