[llvm] [X86] Fix X86CmovConversion sinking volatile loads into conditional branches (PR #219827)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 30 10:12:21 PDT 2026
https://github.com/AZero13 created https://github.com/llvm/llvm-project/pull/219827
The `X86CmovConversion` pass unfolds memory operands of `CMOVrm` instructions and sinks the resulting load into a conditionally executed basic block. While safe for ordinary loads, doing this for a volatile load violates the LLVM LangRef since it causes a volatile memory access to conditionally not execute.
Fix this by not converting with hasOrderedMemoryRef is true.
Fixes #219814
>From dedb4896ed083f4aaab52450ea89ba455d7ec348 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Sun, 30 Aug 2026 13:11:19 -0400
Subject: [PATCH] [X86] Fix X86CmovConversion sinking volatile loads into
conditional branches
The `X86CmovConversion` pass unfolds memory operands of `CMOVrm` instructions and sinks the resulting load into a conditionally executed basic block. While safe for ordinary loads, doing this for a volatile load violates the LLVM LangRef since it causes a volatile memory access to conditionally not execute.
Fix this by not converting with hasOrderedMemoryRef is true.
Fixes #219814
---
llvm/lib/Target/X86/X86CmovConversion.cpp | 2 +-
llvm/test/CodeGen/X86/cmov-conversion-volatile.ll | 15 +++++++++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/X86/cmov-conversion-volatile.ll
diff --git a/llvm/lib/Target/X86/X86CmovConversion.cpp b/llvm/lib/Target/X86/X86CmovConversion.cpp
index 999ff334700b7..002b3b2beb551 100644
--- a/llvm/lib/Target/X86/X86CmovConversion.cpp
+++ b/llvm/lib/Target/X86/X86CmovConversion.cpp
@@ -315,7 +315,7 @@ bool X86CmovConversionImpl::collectCmovCandidates(
// unpredictable, skip it and do not convert it to branch.
if (CC != X86::COND_INVALID &&
!I.getFlag(MachineInstr::MIFlag::Unpredictable) &&
- (IncludeLoads || !I.mayLoad())) {
+ (IncludeLoads || !I.mayLoad()) && !I.hasOrderedMemoryRef()) {
if (Group.empty()) {
// We found first CMOV in the range, reset flags.
FirstCC = CC;
diff --git a/llvm/test/CodeGen/X86/cmov-conversion-volatile.ll b/llvm/test/CodeGen/X86/cmov-conversion-volatile.ll
new file mode 100644
index 0000000000000..710533b6f64c2
--- /dev/null
+++ b/llvm/test/CodeGen/X86/cmov-conversion-volatile.ll
@@ -0,0 +1,15 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu -O1 < %s | FileCheck %s
+
+define dso_local i32 @fq(ptr nofree noundef captures(address) %0, i32 noundef %1) local_unnamed_addr {
+; CHECK-LABEL: fq:
+; CHECK: # %bb.0:
+; CHECK-NEXT: testl %esi, %esi
+; CHECK-NEXT: movl $7, %eax
+; CHECK-NEXT: cmovel (%rdi), %eax
+; CHECK-NEXT: retq
+ %3 = load volatile i32, ptr %0, align 4
+ %4 = icmp eq i32 %1, 0
+ %5 = select i1 %4, i32 %3, i32 7
+ ret i32 %5
+}
More information about the llvm-commits
mailing list