Skip to content

Commit 4d6f365

Browse files
committed
Propagate implicit.ref metadata when inlining.
Propagate the metadata from callee to caller on inlining. Also adds a test verifying that the metadata is maintained when cloning a function.
1 parent c9ed9d9 commit 4d6f365

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

llvm/lib/Transforms/Utils/InlineFunction.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,6 +2830,15 @@ void llvm::InlineFunctionImpl(CallBase &CB, InlineFunctionInfo &IFI,
28302830
// Propagate metadata on the callsite if necessary.
28312831
PropagateCallSiteMetadata(CB, FirstNewBlock, Caller->end());
28322832

2833+
// Propagate implicit ref metadata.
2834+
if (CalledFunc->hasMetadata(LLVMContext::MD_implicit_ref)) {
2835+
SmallVector<MDNode *> MDs;
2836+
CalledFunc->getMetadata(LLVMContext::MD_implicit_ref, MDs);
2837+
for (MDNode *MD : MDs) {
2838+
Caller->addMetadata(LLVMContext::MD_implicit_ref, *MD);
2839+
}
2840+
}
2841+
28332842
// Register any cloned assumptions.
28342843
if (IFI.GetAssumptionCache)
28352844
for (BasicBlock &NewBlock :
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
; RUN: opt -passes="ipsccp<func-spec>" -S -force-specialization < %s 2>&1 | FileCheck %s
2+
3+
@a = global i32 1
4+
5+
define i64 @main(i64 %x, i1 %flag) {
6+
entry:
7+
br i1 %flag, label %plus, label %minus
8+
9+
plus:
10+
%tmp0 = call i64 @compute(i64 %x, ptr @plus)
11+
br label %merge
12+
13+
minus:
14+
%tmp1 = call i64 @compute(i64 %x, ptr @minus)
15+
br label %merge
16+
17+
merge:
18+
%tmp2 = phi i64 [ %tmp0, %plus ], [ %tmp1, %minus]
19+
ret i64 %tmp2
20+
}
21+
22+
define internal i64 @compute(i64 %x, ptr %binop) !implicit.ref !0 {
23+
entry:
24+
%tmp0 = call i64 %binop(i64 %x)
25+
ret i64 %tmp0
26+
}
27+
28+
define internal i64 @plus(i64 %x) {
29+
entry:
30+
%tmp0 = add i64 %x, 1
31+
ret i64 %tmp0
32+
}
33+
34+
define internal i64 @minus(i64 %x) {
35+
entry:
36+
%tmp0 = sub i64 %x, 1
37+
ret i64 %tmp0
38+
}
39+
40+
!0 = !{ptr @a}
41+
42+
; CHECK: @compute.specialized.1(i64 %x, ptr %binop) !implicit.ref !0
43+
; CHECK: @compute.specialized.2(i64 %x, ptr %binop) !implicit.ref !0
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s
2+
3+
@a = global i32 1
4+
@b = global i32 2
5+
@c = global double 3.141593e+00
6+
7+
define i32 @callee1() !implicit.ref !0 {
8+
ret i32 0
9+
}
10+
11+
define i32 @callee2() !implicit.ref !1 {
12+
ret i32 1
13+
}
14+
15+
define i32 @callee3() {
16+
%i = call i32 @callee2()
17+
ret i32 %i
18+
}
19+
; CHECK: @callee3() !implicit.ref !1
20+
21+
define i32 @caller1() {
22+
%i = call i32 @callee1()
23+
ret i32 %i
24+
}
25+
; CHECK: @caller1() !implicit.ref !0
26+
27+
define i32 @caller2() !implicit.ref !2 {
28+
%i = call i32 @callee1()
29+
ret i32 %i
30+
}
31+
; CHECK: @caller2() !implicit.ref !2 !implicit.ref !0
32+
33+
define i32 @caller3() {
34+
%i = call i32 @caller4()
35+
ret i32 %i
36+
}
37+
; CHECK: @caller3() !implicit.ref !0 !implicit.ref !1
38+
39+
define i32 @caller4() {
40+
%a = call i32 @callee1()
41+
%b = call i32 @callee2()
42+
%add = add i32 %a, %b
43+
ret i32 %add
44+
}
45+
; CHECK: @caller4() !implicit.ref !0 !implicit.ref !1
46+
47+
!0 = !{ptr @a}
48+
!1 = !{ptr @b}
49+
!2 = !{ptr @c}
50+

0 commit comments

Comments
 (0)