[llvm] [win] Control Flow Guard: Don't set the GuardCF COFF feature if the checks are missing (PR #182205)

Daniel Paoliello via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 19 09:19:44 PST 2026


https://github.com/dpaoliello updated https://github.com/llvm/llvm-project/pull/182205

>From fb564ac629757ec9b8f8a03447bec45dfcd46f0b Mon Sep 17 00:00:00 2001
From: Daniel Paoliello <danpao at microsoft.com>
Date: Wed, 18 Feb 2026 17:22:59 -0800
Subject: [PATCH] [win] Control Flow Guard: Don't set the GuardCF COFF feature
 if the checks are missing

---
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp       | 4 ++--
 llvm/test/CodeGen/AArch64/cfguard-module-flag.ll | 2 ++
 llvm/test/CodeGen/WinCFGuard/cfguard.ll          | 3 ++-
 llvm/test/CodeGen/X86/cfguard-module-flag.ll     | 6 ++++++
 4 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index d968ead83e5ed..9650e6501811a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -5094,8 +5094,8 @@ void AsmPrinter::emitCOFFFeatureSymbol(Module &M) {
     Feat00Value |= COFF::Feat00Flags::SafeSEH;
   }
 
-  if (M.getControlFlowGuardMode() != ControlFlowGuardMode::Disabled) {
-    // Object is CFG-aware.
+  if (M.getControlFlowGuardMode() == ControlFlowGuardMode::Enabled) {
+    // Object is CFG-aware. Only set if we actually inserted the checks.
     Feat00Value |= COFF::Feat00Flags::GuardCF;
   }
 
diff --git a/llvm/test/CodeGen/AArch64/cfguard-module-flag.ll b/llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
index 317ad2c42a3e1..7cd9cf1ed2e5c 100644
--- a/llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
+++ b/llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
@@ -6,6 +6,8 @@
 ; Test that Control Flow Guard checks are not added in modules with the
 ; cfguard=1 flag (emit tables but no checks).
 
+; If no checks were inserted then the GuardCF bit shouldn't be set in @feat.00.
+; CHECK: "@feat.00" = 0
 
 declare void @target_func()
 
diff --git a/llvm/test/CodeGen/WinCFGuard/cfguard.ll b/llvm/test/CodeGen/WinCFGuard/cfguard.ll
index a77d5490ef876..25baa97015285 100644
--- a/llvm/test/CodeGen/WinCFGuard/cfguard.ll
+++ b/llvm/test/CodeGen/WinCFGuard/cfguard.ll
@@ -1,7 +1,8 @@
 ; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s
 ; Control Flow Guard is currently only available on Windows
 
-; CHECK: @feat.00 = 2048
+; If no checks were inserted then the GuardCF bit shouldn't be set in @feat.00.
+; CHECK: @feat.00 = 0
 
 ; CHECK: .section .gfids$y
 ; CHECK: .symidx "?address_taken@@YAXXZ"
diff --git a/llvm/test/CodeGen/X86/cfguard-module-flag.ll b/llvm/test/CodeGen/X86/cfguard-module-flag.ll
index f69eccfc3d282..bf0120781292f 100644
--- a/llvm/test/CodeGen/X86/cfguard-module-flag.ll
+++ b/llvm/test/CodeGen/X86/cfguard-module-flag.ll
@@ -7,6 +7,12 @@
 ; Test that Control Flow Guard checks are not added in modules with the
 ; cfguard=1 flag (emit tables but no checks).
 
+; If no checks were inserted then the GuardCF bit shouldn't be set in @feat.00.
+; CHECK: "@feat.00" = 0
+; i686 has SafeSEH (0x1) but should NOT have GuardCF (0x800).
+; X86: @feat.00 = 1
+; x86_64 has no SafeSEH and should NOT have GuardCF.
+; X64: @feat.00 = 0
 
 declare void @target_func()
 



More information about the llvm-commits mailing list