Skip to content

Commit d2942a8

Browse files
authored
[MergeFunctions] Fix thunks for non-instruction debug info (llvm#82080)
When MergeFunctions creates new thunk functions, it needs to copy over the debug info format kind from the original function, otherwise we'll mix debug info formats and run into assertions. This was exposed by a downstream change that runs MergeFunctions before inlining, which caused assertions when inlining attempted to inline thunks created by merging, and the added test covers both scenarios where merging creates thunks.
1 parent 4c6043d commit d2942a8

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

llvm/lib/Transforms/IPO/MergeFunctions.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,7 @@ void MergeFunctions::writeThunk(Function *F, Function *G) {
747747
NewG = Function::Create(G->getFunctionType(), G->getLinkage(),
748748
G->getAddressSpace(), "", G->getParent());
749749
NewG->setComdat(G->getComdat());
750+
NewG->IsNewDbgInfoFormat = G->IsNewDbgInfoFormat;
750751
BB = BasicBlock::Create(F->getContext(), "", NewG);
751752
}
752753

@@ -874,6 +875,7 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) {
874875
F->getAddressSpace(), "", F->getParent());
875876
NewF->copyAttributesFrom(F);
876877
NewF->takeName(F);
878+
NewF->IsNewDbgInfoFormat = F->IsNewDbgInfoFormat;
877879
// Ensure CFI type metadata is propagated to the new function.
878880
copyMetadataIfPresent(F, NewF, "type");
879881
copyMetadataIfPresent(F, NewF, "kcfi_type");
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
;; Ensure that the MergeFunctions pass creates thunks with the appropriate debug
2+
;; info format set (which would otherwise assert when inlining those thunks).
3+
; RUN: opt -S -passes=mergefunc,inline --try-experimental-debuginfo-iterators < %s | FileCheck %s
4+
5+
declare void @f1()
6+
declare void @f2()
7+
8+
define void @f3() {
9+
call void @f1()
10+
call void @f2()
11+
ret void
12+
}
13+
14+
;; MergeFunctions will replace f4 with a thunk that calls f3. Inlining will
15+
;; inline f3 into that thunk, which would assert if the thunk had the incorrect
16+
;; debug info format.
17+
define void @f4() {
18+
call void @f1()
19+
call void @f2()
20+
ret void
21+
}
22+
23+
; CHECK-LABEL: define void @f4() {
24+
; CHECK-NEXT: call void @f1()
25+
; CHECK-NEXT: call void @f2()
26+
; CHECK-NEXT: ret void
27+
; CHECK-NEXT: }
28+
29+
;; Both of these are interposable, so MergeFunctions will create a common thunk
30+
;; that both will call. Inlining will inline that thunk back, which would assert
31+
;; if the thunk had the incorrect debug info format.
32+
define weak void @f5() {
33+
call void @f2()
34+
call void @f1()
35+
ret void
36+
}
37+
38+
define weak void @f6() {
39+
call void @f2()
40+
call void @f1()
41+
ret void
42+
}
43+
44+
; CHECK-LABEL: define weak void @f6() {
45+
; CHECK-NEXT: call void @f2()
46+
; CHECK-NEXT: call void @f1()
47+
; CHECK-NEXT: ret void
48+
; CHECK-NEXT: }
49+
50+
; CHECK-LABEL: define weak void @f5() {
51+
; CHECK-NEXT: call void @f2()
52+
; CHECK-NEXT: call void @f1()
53+
; CHECK-NEXT: ret void
54+
; CHECK-NEXT: }

0 commit comments

Comments
 (0)