[llvm] [X86] Fix XOR folding in EmitCmp (PR #210546)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 18 13:41:26 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Alexander Coffin (GreenBeard)

<details>
<summary>Changes</summary>

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.)

---
Full diff: https://github.com/llvm/llvm-project/pull/210546.diff


2 Files Affected:

- (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+10-2) 
- (added) llvm/test/CodeGen/X86/xor-fold.ll (+23) 


``````````diff
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
new file mode 100644
index 0000000000000..d57326a98637d
--- /dev/null
+++ b/llvm/test/CodeGen/X86/xor-fold.ll
@@ -0,0 +1,23 @@
+; 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:    xorl $7, (%eax)
+; X86-NEXT:    setne %al
+; X86-NEXT:    retl
+;
+; X64-LABEL: foo:
+; X64:       # %bb.0:
+; X64-NEXT:    xorl $7, (%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
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/210546


More information about the llvm-commits mailing list