aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/IPO/MergeFunctions.cpp
diff options
context:
space:
mode:
authorOskar Wirga <10386631+oskarwirga@users.noreply.github.com>2023-10-18 11:22:35 -0700
committerGitHub <noreply@github.com>2023-10-18 11:22:35 -0700
commitc9b7d21dc577b10dce2b8d67b86b279cfc374d40 (patch)
tree43ff5ef984665823dc501bee516a6365eaed4d40 /llvm/lib/Transforms/IPO/MergeFunctions.cpp
parent10079a23c5b6becfdaaa34d8ba72c91706ad4a6d (diff)
downloadllvm-c9b7d21dc577b10dce2b8d67b86b279cfc374d40.zip
llvm-c9b7d21dc577b10dce2b8d67b86b279cfc374d40.tar.gz
llvm-c9b7d21dc577b10dce2b8d67b86b279cfc374d40.tar.bz2
[CFI/MergeFunctions] Modify MergeFunctions to propagate type information (#68628)
When MergeFuncs creates a thunk, it does not modify the function in place, but creates a new one altogether. If type metadata is not properly forwarded to this new function, LowerTypeTests will be unable to put this thunk into the dispatch table. The fix here is to just forward the type metadata to the newly created functions.
Diffstat (limited to 'llvm/lib/Transforms/IPO/MergeFunctions.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/MergeFunctions.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
index c19cf71..c8c011d 100644
--- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
@@ -662,6 +662,13 @@ static bool canCreateThunkFor(Function *F) {
return true;
}
+/// Copy metadata from one function to another.
+static void copyMetadataIfPresent(Function *From, Function *To, StringRef Key) {
+ if (MDNode *MD = From->getMetadata(Key)) {
+ To->setMetadata(Key, MD);
+ }
+}
+
// Replace G with a simple tail call to bitcast(F). Also (unless
// MergeFunctionsPDI holds) replace direct uses of G with bitcast(F),
// delete G. Under MergeFunctionsPDI, we use G itself for creating
@@ -740,6 +747,9 @@ void MergeFunctions::writeThunk(Function *F, Function *G) {
} else {
NewG->copyAttributesFrom(G);
NewG->takeName(G);
+ // Ensure CFI type metadata is propagated to the new function.
+ copyMetadataIfPresent(G, NewG, "type");
+ copyMetadataIfPresent(G, NewG, "kcfi_type");
removeUsers(G);
G->replaceAllUsesWith(NewG);
G->eraseFromParent();
@@ -815,6 +825,9 @@ void MergeFunctions::mergeTwoFunctions(Function *F, Function *G) {
F->getAddressSpace(), "", F->getParent());
NewF->copyAttributesFrom(F);
NewF->takeName(F);
+ // Ensure CFI type metadata is propagated to the new function.
+ copyMetadataIfPresent(F, NewF, "type");
+ copyMetadataIfPresent(F, NewF, "kcfi_type");
removeUsers(F);
F->replaceAllUsesWith(NewF);