[llvm] [MergeFunctions] Fix merging functions with different KCFI type identifiers (PR #217665)

via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 19:24:20 PDT 2026


https://github.com/Lane0218 updated https://github.com/llvm/llvm-project/pull/217665

>From 06171629d1af415364d19ccb95e293d8f394c685 Mon Sep 17 00:00:00 2001
From: Lane0218 <laneljc at qq.com>
Date: Thu, 20 Aug 2026 23:26:33 +0800
Subject: [PATCH] [MergeFunctions] Fix merging functions with different KCFI
 type identifiers

---
 llvm/docs/MergeFunctions.md                   |  1 +
 .../Transforms/Utils/FunctionComparator.cpp   |  4 +++
 .../MergeFunc/kcfi-function-merging.ll        | 36 +++++++++++++++++++
 3 files changed, 41 insertions(+)
 create mode 100644 llvm/test/Transforms/MergeFunc/kcfi-function-merging.ll

diff --git a/llvm/docs/MergeFunctions.md b/llvm/docs/MergeFunctions.md
index bb39e40032894..4649cd90ec792 100644
--- a/llvm/docs/MergeFunctions.md
+++ b/llvm/docs/MergeFunctions.md
@@ -279,6 +279,7 @@ properties to be compared on this stage:
    - *Variable arguments*. *LHS* and *RHS* should be both either with or
      without *var-args*.
    - *Calling convention* should be the same.
+   - Function-level `!kcfi_type` metadata, if present, should be identical.
 
 2. Function type. Checked by `FunctionComparator::cmpType(Type*, Type*)`
 method. It checks return type and parameters type; the method itself will be
diff --git a/llvm/lib/Transforms/Utils/FunctionComparator.cpp b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
index 05c24af6efb39..9e84c78087303 100644
--- a/llvm/lib/Transforms/Utils/FunctionComparator.cpp
+++ b/llvm/lib/Transforms/Utils/FunctionComparator.cpp
@@ -990,6 +990,10 @@ int FunctionComparator::compareSignature() const {
   if (int Res = cmpAttrs(FnL->getAttributes(), FnR->getAttributes()))
     return Res;
 
+  if (int Res = cmpMDNode(FnL->getMetadata(LLVMContext::MD_kcfi_type),
+                          FnR->getMetadata(LLVMContext::MD_kcfi_type)))
+    return Res;
+
   if (int Res = cmpNumbers(FnL->hasGC(), FnR->hasGC()))
     return Res;
 
diff --git a/llvm/test/Transforms/MergeFunc/kcfi-function-merging.ll b/llvm/test/Transforms/MergeFunc/kcfi-function-merging.ll
new file mode 100644
index 0000000000000..c3d3daadc5f51
--- /dev/null
+++ b/llvm/test/Transforms/MergeFunc/kcfi-function-merging.ll
@@ -0,0 +1,36 @@
+; RUN: opt -S -passes=mergefunc < %s | FileCheck %s
+
+; Functions with different KCFI type identifiers must not be merged.
+
+define internal i32 @a() unnamed_addr !kcfi_type !0 {
+; CHECK-LABEL: define internal i32 @a()
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: }
+entry:
+  ret i32 0
+}
+
+define internal i32 @b() unnamed_addr !kcfi_type !1 {
+; CHECK-LABEL: define internal i32 @b()
+; CHECK-NEXT: entry:
+; CHECK-NEXT: ret i32 0
+; CHECK-NEXT: }
+entry:
+  ret i32 0
+}
+
+define i32 @caller() {
+; CHECK-LABEL: define i32 @caller()
+; CHECK-NEXT: entry:
+; CHECK-NEXT: %x = call i32 @a()
+; CHECK-NEXT: %y = call i32 @b()
+; CHECK-NEXT: ret i32 %y
+entry:
+  %x = call i32 @a()
+  %y = call i32 @b()
+  ret i32 %y
+}
+
+!0 = !{i32 1234}
+!1 = !{i32 6789}



More information about the llvm-commits mailing list