[llvm] Fix: Distinguish CFI Metadata Checks in MergeFunctions Pass (PR #65963)
Oskar Wirga via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 20 18:33:04 PDT 2023
https://github.com/oskarwirga updated https://github.com/llvm/llvm-project/pull/65963
>From 779eb8edb0390809ea2a6680bef39bfecad733ef Mon Sep 17 00:00:00 2001
From: Oskar Wirga <10386631+oskarwirga at users.noreply.github.com>
Date: Wed, 20 Sep 2023 18:32:35 -0700
Subject: [PATCH] Fix: Distinguish CFI Metadata Checks in MergeFunctions Pass
---
llvm/lib/Transforms/IPO/MergeFunctions.cpp | 30 ++++++++++++++-
.../MergeFunc/cfi-function-merging.ll | 38 +++++++++++++++++++
2 files changed, 66 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/Transforms/MergeFunc/cfi-function-merging.ll
diff --git a/llvm/lib/Transforms/IPO/MergeFunctions.cpp b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
index 312a8df440bf1e3..1421ecfcd8b948e 100644
--- a/llvm/lib/Transforms/IPO/MergeFunctions.cpp
+++ b/llvm/lib/Transforms/IPO/MergeFunctions.cpp
@@ -375,9 +375,35 @@ bool MergeFunctions::doFunctionalCheck(std::vector<WeakTrackingVH> &Worklist) {
}
#endif
+// This function iterates over two functions and compares their
+// metadata to make sure we aren't merging functions which have
+// distinct metadata that is different. We don't care about
+// debug data here, it shouldn't change MIR like CFI would.
+static bool hasDistinctMetadataIntrinsic(const Function &F) {
+ for (const BasicBlock &BB : F) {
+ for (const Instruction &I : BB.instructionsWithoutDebug()) {
+ if (!isa<IntrinsicInst>(&I))
+ continue; // Only intrinsics can reference metadata.
+
+ // Iterate through operands, and return true if you find a distinct
+ // metadata operand.
+ for (unsigned i = 0, e = I.getNumOperands(); i != e;
+ ++i) { // Replaced InstLIt with I
+ MetadataAsValue *MDL = dyn_cast<MetadataAsValue>(
+ I.getOperand(i)); // Replaced InstLIt with I
+ if (!MDL)
+ continue;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
/// Check whether \p F is eligible for function merging.
static bool isEligibleForMerging(Function &F) {
- return !F.isDeclaration() && !F.hasAvailableExternallyLinkage();
+ return !F.isDeclaration() && !F.hasAvailableExternallyLinkage() &&
+ !hasDistinctMetadataIntrinsic(F);
}
bool MergeFunctions::runOnModule(Module &M) {
@@ -404,7 +430,7 @@ bool MergeFunctions::runOnModule(Module &M) {
// If the hash value matches the previous value or the next one, we must
// consider merging it. Otherwise it is dropped and never considered again.
if ((I != S && std::prev(I)->first == I->first) ||
- (std::next(I) != IE && std::next(I)->first == I->first) ) {
+ (std::next(I) != IE && std::next(I)->first == I->first)) {
Deferred.push_back(WeakTrackingVH(I->second));
}
}
diff --git a/llvm/test/Transforms/MergeFunc/cfi-function-merging.ll b/llvm/test/Transforms/MergeFunc/cfi-function-merging.ll
new file mode 100644
index 000000000000000..a3d81f156f753b4
--- /dev/null
+++ b/llvm/test/Transforms/MergeFunc/cfi-function-merging.ll
@@ -0,0 +1,38 @@
+;; Check the cases involving internal CFI instrumented functions where we do not expect functions to be merged.
+; RUN: opt -S -passes=mergefunc < %s | FileCheck %s
+
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-none-linux-android28"
+
+; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn
+declare i1 @llvm.type.test(ptr, metadata) #6
+
+define internal void @A__on_zero_sharedEv(ptr noundef nonnull align 8 dereferenceable(32) %this) {
+; CHECK-LABEL: @A__on_zero_sharedEv
+entry:
+ %this.addr = alloca ptr, align 8
+ store ptr %this, ptr %this.addr, align 8
+ %this1 = load ptr, ptr %this.addr, align 8
+ %vtable = load ptr, ptr %this1, align 8
+ %0 = call i1 @llvm.type.test(ptr %vtable, metadata !11), !nosanitize !47
+ ret void
+}
+
+; Function Attrs: mustprogress noinline nounwind optnone uwtable
+define internal void @B__on_zero_sharedEv(ptr noundef nonnull align 8 dereferenceable(32) %this) {
+; CHECK-LABEL: @B__on_zero_sharedEv
+entry:
+ %this.addr = alloca ptr, align 8
+ store ptr %this, ptr %this.addr, align 8
+ %this1 = load ptr, ptr %this.addr, align 8
+ %vtable = load ptr, ptr %this1, align 8
+ %0 = call i1 @llvm.type.test(ptr %vtable, metadata !22), !nosanitize !47
+ ret void
+}
+
+!10 = !{i64 16, !11}
+!11 = distinct !{}
+!21 = !{i64 16, !22}
+!22 = distinct !{}
+!47 = !{}
More information about the llvm-commits
mailing list