[llvm] 4db69f4 - [win] Control Flow Guard: Don't set the GuardCF COFF feature if the checks are missing (#182205)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 19 10:21:57 PST 2026
Author: Daniel Paoliello
Date: 2026-02-19T10:21:53-08:00
New Revision: 4db69f41457e11af677461124f4bf7f7543b6772
URL: https://github.com/llvm/llvm-project/commit/4db69f41457e11af677461124f4bf7f7543b6772
DIFF: https://github.com/llvm/llvm-project/commit/4db69f41457e11af677461124f4bf7f7543b6772.diff
LOG: [win] Control Flow Guard: Don't set the GuardCF COFF feature if the checks are missing (#182205)
LLVM allows Windows Control Flow Guard to be enabled in "table only"
mode where it emits the Control Flow Guard tables (indicating addresses
for valid targets) but doesn't emit any checks at call sites. This is
almost the same as MSVC's `/d2guardnochecks` flag, EXCEPT MSVC doesn't
set the COFF feature bit indicating that Control Flow Guard is enabled
(`GuardCF`) whereas LLVM does.
This change aligns LLVM with MSVC: in table only mode, the Control Flow
Guard COFF feature bit (`GuardCF`) will not be set.
Added:
Modified:
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/test/CodeGen/AArch64/cfguard-module-flag.ll
llvm/test/CodeGen/WinCFGuard/cfguard.ll
llvm/test/CodeGen/X86/cfguard-module-flag.ll
Removed:
################################################################################
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