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
+}
+


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to