[clang] 690a25f - [clang] Don't optimize out no-op atomics in kernel mode (#193562)
via cfe-commits
cfe-commits at lists.llvm.org
Wed May 27 23:51:27 PDT 2026
Author: eleviant
Date: 2026-05-28T08:51:20+02:00
New Revision: 690a25fd5b0bf7118370efbc681661a24a40b83a
URL: https://github.com/llvm/llvm-project/commit/690a25fd5b0bf7118370efbc681661a24a40b83a
DIFF: https://github.com/llvm/llvm-project/commit/690a25fd5b0bf7118370efbc681661a24a40b83a.diff
LOG: [clang] Don't optimize out no-op atomics in kernel mode (#193562)
The no-op atomics like InterlockedAnd(addr, (UINT32)-1) don't modify
the underlying value, however kernel code depends on these accesses
to touch the pool page virtual address and intentionally trigger a page
fault during page migration. This patch also fixes an LLVM issue where
idempotent volatile atomics were incorrectly lowered into memory fences.
Added:
clang/test/CodeGen/AArch64/mskernel-interlocked.c
clang/test/CodeGen/X86/mskernel-interlocked.c
llvm/test/CodeGen/X86/volatile-atomicrmw.ll
Modified:
clang/lib/CodeGen/CGBuiltin.cpp
llvm/lib/CodeGen/AtomicExpandPass.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index f4ded5c7b3f08..50d34889d8dc1 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -315,6 +315,9 @@ Value *MakeBinaryAtomicValue(
llvm::Value *Result =
CGF.Builder.CreateAtomicRMW(Kind, DestAddr, Val, Ordering);
+ // Consider atomics to be volatile in MS kernel mode.
+ if (CGF.CGM.getLangOpts().Kernel)
+ cast<llvm::AtomicRMWInst>(Result)->setVolatile(true);
return EmitFromInt(CGF, Result, T, ValueType);
}
diff --git a/clang/test/CodeGen/AArch64/mskernel-interlocked.c b/clang/test/CodeGen/AArch64/mskernel-interlocked.c
new file mode 100644
index 0000000000000..2d2d69402df93
--- /dev/null
+++ b/clang/test/CodeGen/AArch64/mskernel-interlocked.c
@@ -0,0 +1,11 @@
+// Check that we don't fold no-op andl to memory barrier
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -fms-kernel -fms-extensions -Wno-implicit-function-declaration -triple aarch64-pc-win32 -O2 -S -o - %s | FileCheck %s --check-prefix=ARM64
+
+// ARM64: ldaxr
+// ARM64-NEXT: stlxr
+// ARM64-NEXT: cbnz
+
+void access_via_interlocked(long volatile* addr) {
+ _InterlockedAnd(addr, (long)-1);
+}
diff --git a/clang/test/CodeGen/X86/mskernel-interlocked.c b/clang/test/CodeGen/X86/mskernel-interlocked.c
new file mode 100644
index 0000000000000..4f892cad5d1cd
--- /dev/null
+++ b/clang/test/CodeGen/X86/mskernel-interlocked.c
@@ -0,0 +1,10 @@
+// Check that we don't fold no-op andl to memory barrier
+// REQUIRES: x86-registered-target
+// RUN: %clang_cc1 -fms-kernel -fms-extensions -Wno-implicit-function-declaration -triple x86_64-pc-win32 -O2 -S -o - %s | FileCheck %s --check-prefix=X86
+
+// X86: lock andl $-1, (%rcx)
+// X86-NEXT: retq
+
+void access_via_interlocked(long volatile* addr) {
+ _InterlockedAnd(addr, (long)-1);
+}
diff --git a/llvm/lib/CodeGen/AtomicExpandPass.cpp b/llvm/lib/CodeGen/AtomicExpandPass.cpp
index 5ceb2b12c3d41..d99e220ef11a8 100644
--- a/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -1710,6 +1710,8 @@ bool AtomicExpandImpl::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
}
bool AtomicExpandImpl::isIdempotentRMW(AtomicRMWInst *RMWI) {
+ if (RMWI->isVolatile())
+ return false;
// TODO: Add floating point support.
auto C = dyn_cast<ConstantInt>(RMWI->getValOperand());
if (!C)
diff --git a/llvm/test/CodeGen/X86/volatile-atomicrmw.ll b/llvm/test/CodeGen/X86/volatile-atomicrmw.ll
new file mode 100644
index 0000000000000..dcdd8ea5f5e82
--- /dev/null
+++ b/llvm/test/CodeGen/X86/volatile-atomicrmw.ll
@@ -0,0 +1,13 @@
+; RUN: opt -S -passes='require<libcall-lowering-info>,expand-ir-insts,atomic-expand' %s -o - | FileCheck %s
+
+; volatile atomicrmw shouldn't be converted to a fence
+; CHECK: %0 = atomicrmw volatile and ptr %addr, i32 -1 seq_cst
+
+target triple = "x86_64-pc-windows-msvc"
+
+define dso_local void @access_via_interlocked(ptr noundef %addr) {
+entry:
+ %0 = atomicrmw volatile and ptr %addr, i32 -1 seq_cst, align 4
+ ret void
+}
+
More information about the cfe-commits
mailing list