[llvm] [X86] Fix XOR folding in EmitCmp (PR #210546)
Alexander Coffin via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 18 13:40:27 PDT 2026
https://github.com/GreenBeard created https://github.com/llvm/llvm-project/pull/210546
I was having fun investigating some x86 folding of various instructions and am working on a larger change set that I'm not sure I like (I may redo it), but this seemed like a smaller non-controversial piece to upstream.
(This is my first time contributing to LLVM so I apologize if I'm doing anything obviously wrong.)
>From 21bd35d21932eff8c9426b3f3fc7994bf9163fec Mon Sep 17 00:00:00 2001
From: Alexander Coffin <alexcoffin1999 at gmail.com>
Date: Sat, 18 Jul 2026 11:44:58 -0700
Subject: [PATCH 1/2] [X86] Add XOR read, modify, write folding test
---
llvm/test/CodeGen/X86/xor-fold.ll | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100644 llvm/test/CodeGen/X86/xor-fold.ll
diff --git a/llvm/test/CodeGen/X86/xor-fold.ll b/llvm/test/CodeGen/X86/xor-fold.ll
new file mode 100644
index 0000000000000..e52a17789537b
--- /dev/null
+++ b/llvm/test/CodeGen/X86/xor-fold.ll
@@ -0,0 +1,27 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=X64
+
+define zeroext i1 @foo(ptr %x) {
+; X86-LABEL: foo:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl (%eax), %ecx
+; X86-NEXT: xorl $7, %ecx
+; X86-NEXT: movl %ecx, (%eax)
+; X86-NEXT: setne %al
+; X86-NEXT: retl
+;
+; X64-LABEL: foo:
+; X64: # %bb.0:
+; X64-NEXT: movl (%rdi), %eax
+; X64-NEXT: xorl $7, %eax
+; X64-NEXT: movl %eax, (%rdi)
+; X64-NEXT: setne %al
+; X64-NEXT: retq
+ %1 = load i32, ptr %x
+ %2 = xor i32 %1, 7
+ store i32 %2, ptr %x
+ %tobool.not = icmp ne i32 %1, 7
+ ret i1 %tobool.not
+}
>From ab732b9e7c15a3f16852a4ff8806ec8cdf7d2e8a Mon Sep 17 00:00:00 2001
From: Alexander Coffin <alexcoffin1999 at gmail.com>
Date: Sat, 18 Jul 2026 10:55:03 -0700
Subject: [PATCH 2/2] [X86] Fix XOR folding in EmitCmp
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 12 ++++++++++--
llvm/test/CodeGen/X86/xor-fold.ll | 8 ++------
2 files changed, 12 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 791e04deb9583..79b3e3bc5d9af 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -24077,13 +24077,21 @@ static SDValue EmitCmp(SDValue Op0, SDValue Op1, X86::CondCode X86CC,
// If we already have an XOR of the ops, use that to check for equality.
// Else use SUB instead of CMP to enable CSE between SUB and CMP.
unsigned X86Opc = X86ISD::SUB;
+ SDNode *IsdNode = nullptr;
if ((X86CC == X86::COND_E || X86CC == X86::COND_NE) &&
- (DAG.doesNodeExist(ISD::XOR, DAG.getVTList({CmpVT}), {Op0, Op1}) ||
- DAG.doesNodeExist(ISD::XOR, DAG.getVTList({CmpVT}), {Op1, Op0})))
+ ((IsdNode = DAG.getNodeIfExists(ISD::XOR, DAG.getVTList({CmpVT}),
+ {Op0, Op1})) ||
+ (IsdNode =
+ DAG.getNodeIfExists(ISD::XOR, DAG.getVTList({CmpVT}), {Op1, Op0}))))
X86Opc = X86ISD::XOR;
SDVTList VTs = DAG.getVTList(CmpVT, MVT::i32);
SDValue CmpOp = DAG.getNode(X86Opc, dl, VTs, Op0, Op1);
+
+ if (IsdNode != nullptr) {
+ DAG.ReplaceAllUsesWith(IsdNode, &CmpOp);
+ }
+
return CmpOp.getValue(1);
}
diff --git a/llvm/test/CodeGen/X86/xor-fold.ll b/llvm/test/CodeGen/X86/xor-fold.ll
index e52a17789537b..d57326a98637d 100644
--- a/llvm/test/CodeGen/X86/xor-fold.ll
+++ b/llvm/test/CodeGen/X86/xor-fold.ll
@@ -6,17 +6,13 @@ define zeroext i1 @foo(ptr %x) {
; X86-LABEL: foo:
; X86: # %bb.0:
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: movl (%eax), %ecx
-; X86-NEXT: xorl $7, %ecx
-; X86-NEXT: movl %ecx, (%eax)
+; X86-NEXT: xorl $7, (%eax)
; X86-NEXT: setne %al
; X86-NEXT: retl
;
; X64-LABEL: foo:
; X64: # %bb.0:
-; X64-NEXT: movl (%rdi), %eax
-; X64-NEXT: xorl $7, %eax
-; X64-NEXT: movl %eax, (%rdi)
+; X64-NEXT: xorl $7, (%rdi)
; X64-NEXT: setne %al
; X64-NEXT: retq
%1 = load i32, ptr %x
More information about the llvm-commits
mailing list