[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