[llvm] [X86][KCFI] Do not emit a type prefix for nocf_check functions (PR #158133)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 11 11:51:32 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Sami Tolvanen (samitolvanen)

<details>
<summary>Changes</summary>

With indirect branch protection, the `nocf_check` attribute prevents a function from being called indirectly by omitting the ENDBR instruction from the beginning of the function body. As KCFI type prefixes are only needed for indirectly callable functions, don't emit the unnecessary prefix for `nocf_check` functions.

---
Full diff: https://github.com/llvm/llvm-project/pull/158133.diff


2 Files Affected:

- (modified) llvm/lib/Target/X86/X86AsmPrinter.cpp (+3-2) 
- (added) llvm/test/CodeGen/X86/kcfi-nocf-check.ll (+39) 


``````````diff
diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp
index ff22ee8c86fac..486bf3986cf5a 100644
--- a/llvm/lib/Target/X86/X86AsmPrinter.cpp
+++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp
@@ -170,8 +170,9 @@ void X86AsmPrinter::emitKCFITypeId(const MachineFunction &MF) {
     Type = mdconst::extract<ConstantInt>(MD->getOperand(0));
 
   // If we don't have a type to emit, just emit padding if needed to maintain
-  // the same alignment for all functions.
-  if (!Type) {
+  // the same alignment for all functions. Also skip `nocf_check` functions as
+  // they are not indirectly callable due to a missing ENDBR.
+  if (!Type || F.doesNoCfCheck()) {
     EmitKCFITypePadding(MF, /*HasType=*/false);
     return;
   }
diff --git a/llvm/test/CodeGen/X86/kcfi-nocf-check.ll b/llvm/test/CodeGen/X86/kcfi-nocf-check.ll
new file mode 100644
index 0000000000000..1ce886c1587f8
--- /dev/null
+++ b/llvm/test/CodeGen/X86/kcfi-nocf-check.ll
@@ -0,0 +1,39 @@
+; RUN: llc -mtriple=x86_64-unknown-unknown -x86-indirect-branch-tracking < %s | FileCheck %s
+
+; CHECK-LABEL: __cfi_cf_check_func:
+; CHECK:       movl	$12345678, %eax
+define void @cf_check_func() !kcfi_type !2 {
+; CHECK-LABEL: cf_check_func:
+; CHECK:       endbr64
+; CHECK:       retq
+entry:
+  ret void
+}
+
+; CHECK-NOT:   __cfi_notype_cf_check_func:
+; CHECK-NOT:   movl
+define void @notype_cf_check_func() {
+; CHECK-LABEL: notype_cf_check_func:
+; CHECK:       endbr64
+; CHECK:       retq
+entry:
+  ret void
+}
+
+; CHECK-NOT:   __cfi_nocf_check_func:
+; CHECK-NOT:   movl
+define void @nocf_check_func() #0 !kcfi_type !2 {
+; CHECK-LABEL: nocf_check_func:
+; CHECK-NOT:   endbr64
+; CHECK:       retq
+entry:
+  ret void
+}
+
+attributes #0 = { nocf_check }
+
+!llvm.module.flags = !{!0, !1}
+
+!0 = !{i32 8, !"cf-protection-branch", i32 1}
+!1 = !{i32 4, !"kcfi", i32 1}
+!2 = !{i32 12345678}

``````````

</details>


https://github.com/llvm/llvm-project/pull/158133


More information about the llvm-commits mailing list