[clang] [llvm] Don't optimize out no-op atomics in kernel mode (PR #193562)

via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 24 11:54:54 PDT 2026


https://github.com/eleviant updated https://github.com/llvm/llvm-project/pull/193562

>From f0e48adea890071f140bfc47623725b260cedcbe Mon Sep 17 00:00:00 2001
From: Evgeny Leviant <eleviant at accesssoftek.com>
Date: Fri, 24 Apr 2026 20:54:06 +0200
Subject: [PATCH] Address review comments from @efriedma-quic and @nikic

---
 clang/lib/CodeGen/CGBuiltin.cpp             |  1 +
 clang/test/CodeGen/MSKernel/interlocked.c   | 14 ++++++++++++++
 llvm/lib/CodeGen/AtomicExpandPass.cpp       |  4 +++-
 llvm/test/CodeGen/X86/volatile-atomicrmw.ll | 13 +++++++++++++
 4 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CodeGen/MSKernel/interlocked.c
 create mode 100644 llvm/test/CodeGen/X86/volatile-atomicrmw.ll

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 7a745b6e36138..66d95f7589993 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -313,6 +313,7 @@ Value *MakeBinaryAtomicValue(
 
   llvm::Value *Result =
       CGF.Builder.CreateAtomicRMW(Kind, DestAddr, Val, Ordering);
+  cast<llvm::AtomicRMWInst>(Result)->setVolatile(CGF.CGM.getLangOpts().Kernel);
   return EmitFromInt(CGF, Result, T, ValueType);
 }
 
diff --git a/clang/test/CodeGen/MSKernel/interlocked.c b/clang/test/CodeGen/MSKernel/interlocked.c
new file mode 100644
index 0000000000000..711b34f06ff29
--- /dev/null
+++ b/clang/test/CodeGen/MSKernel/interlocked.c
@@ -0,0 +1,14 @@
+// Check that we don't fold no-op andl to memory barrier
+// 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
+// RUN: %clang_cc1 -fms-kernel -fms-extensions -Wno-implicit-function-declaration  -triple aarch64-pc-win32 -O2 -S -o - %s | FileCheck %s --check-prefix=ARM64
+
+// X86:      lock andl $-1, (%rcx)
+// X86-NEXT: retq
+
+// ARM64:      ldaxr
+// ARM64-NEXT: stlxr
+// ARM64-NEXT: cbnz
+
+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 068365e0d35a0..8d0235dbea875 100644
--- a/llvm/lib/CodeGen/AtomicExpandPass.cpp
+++ b/llvm/lib/CodeGen/AtomicExpandPass.cpp
@@ -1682,7 +1682,9 @@ bool AtomicExpandImpl::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) {
 }
 
 bool AtomicExpandImpl::isIdempotentRMW(AtomicRMWInst *RMWI) {
-  // TODO: Add floating point support.
+  if (RMWI->isVolatile())
+    return false;
+  // TODO: Add floating point support.  
   auto C = dyn_cast<ConstantInt>(RMWI->getValOperand());
   if (!C)
     return false;
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