[llvm] [X86] Fix XOR folding in EmitCmp (PR #216134)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 13 10:56:04 PDT 2026
https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/216134
>From 542ca8dc7d83462312b3f4027ce676eb2f4eb4e6 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Thu, 13 Aug 2026 13:26:33 -0400
Subject: [PATCH 1/2] Pre-commit test
---
llvm/test/CodeGen/X86/cmp-xor.ll | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/llvm/test/CodeGen/X86/cmp-xor.ll b/llvm/test/CodeGen/X86/cmp-xor.ll
index a8a7da4871ba9..1012c9b4c4a45 100644
--- a/llvm/test/CodeGen/X86/cmp-xor.ll
+++ b/llvm/test/CodeGen/X86/cmp-xor.ll
@@ -54,3 +54,26 @@ define i32 @cmp_xor_i32_commute(i32 %a, i32 %b, i32 %c)
ret i32 %sel
}
+define zeroext i1 @xor_cmp_rmw_i32(ptr %x) {
+; X86-LABEL: xor_cmp_rmw_i32:
+; 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
+ %load = load i32, ptr %x
+ %xor = xor i32 %load, 7
+ store i32 %xor, ptr %x
+ %cmp = icmp ne i32 %load, 7
+ ret i1 %cmp
+}
>From b5489d849ee500f548672be1e1146a8e55f7a0f6 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Thu, 13 Aug 2026 13:41:54 -0400
Subject: [PATCH 2/2] [X86] Fix XOR folding in EmitCmp
Prevent redundant xors from being emitted.
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 29 +++++++++++++++++++++++++
llvm/test/CodeGen/X86/cmp-xor.ll | 10 +++------
2 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index eed9416741c17..37eb3715809d0 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -59481,6 +59481,34 @@ static SDValue combineX86AddSub(SDNode *N, SelectionDAG &DAG,
/*ZeroSecondOpOnly*/ true);
}
+static SDValue combineX86XOR(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI) {
+ assert(N->getOpcode() == X86ISD::XOR && "Expected X86ISD::XOR");
+
+ SDLoc DL(N);
+ SDValue LHS = N->getOperand(0);
+ SDValue RHS = N->getOperand(1);
+ MVT VT = LHS.getSimpleValueType();
+
+ // If we don't use the flag result, simplify back to a generic op.
+ if (!N->hasAnyUseOfValue(1)) {
+ SDValue Res = DAG.getNode(ISD::XOR, DL, VT, LHS, RHS);
+ return DAG.getMergeValues({Res, DAG.getConstant(0, DL, MVT::i32)}, DL);
+ }
+
+ // Fold any matching generic nodes to reuse this node.
+ auto MatchGeneric = [&](SDValue N0, SDValue N1) {
+ SDValue Ops[] = {N0, N1};
+ SDVTList VTs = DAG.getVTList(N->getValueType(0));
+ if (SDNode *Generic = DAG.getNodeIfExists(ISD::XOR, VTs, Ops))
+ DCI.CombineTo(Generic, SDValue(N, 0));
+ };
+ MatchGeneric(LHS, RHS);
+ MatchGeneric(RHS, LHS);
+
+ return SDValue();
+}
+
static SDValue combineSBB(SDNode *N, SelectionDAG &DAG) {
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
@@ -63240,6 +63268,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
case ISD::SUB: return combineSub(N, DAG, DCI, Subtarget);
case X86ISD::ADD:
case X86ISD::SUB: return combineX86AddSub(N, DAG, DCI, Subtarget);
+ case X86ISD::XOR: return combineX86XOR(N, DAG, DCI);
case ISD::SADDSAT:
case ISD::SSUBSAT: return combineToHorizontalAddSub(N, DAG, Subtarget);
case X86ISD::CLOAD:
diff --git a/llvm/test/CodeGen/X86/cmp-xor.ll b/llvm/test/CodeGen/X86/cmp-xor.ll
index 1012c9b4c4a45..eed1951898b1d 100644
--- a/llvm/test/CodeGen/X86/cmp-xor.ll
+++ b/llvm/test/CodeGen/X86/cmp-xor.ll
@@ -58,17 +58,13 @@ define zeroext i1 @xor_cmp_rmw_i32(ptr %x) {
; X86-LABEL: xor_cmp_rmw_i32:
; 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-LABEL: xor_cmp_rmw_i32:
; 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
%load = load i32, ptr %x
More information about the llvm-commits
mailing list