[llvm] [DAGCombiner] Fold (or (seteq X, 0), (seteq X, -1)) to (setult (add X, 1), 2) (PR #192183)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 14 22:12:59 PDT 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-arm

Author: Jim Lin (tclin914)

<details>
<summary>Changes</summary>

This is the De Morgan dual of the existing fold:
    (and (setne X, 0), (setne X, -1)) --> (setuge (add X, 1), 2)

The or-of-equalities version checks if X is either 0 or -1, which is
equivalent to (X+1) < 2 (unsigned). This reduces two comparisons and
an or to one add and one comparison.


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


2 Files Affected:

- (modified) llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (+6-4) 
- (modified) llvm/test/CodeGen/ARM/setcc-logic.ll (+14) 


``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index aee5aabdc9e02..b72ed539be473 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6605,17 +6605,19 @@ SDValue DAGCombiner::foldLogicOfSetCCs(bool IsAnd, SDValue N0, SDValue N1,
     }
   }
 
-  // TODO: What is the 'or' equivalent of this fold?
   // (and (setne X, 0), (setne X, -1)) --> (setuge (add X, 1), 2)
-  if (IsAnd && LL == RL && CC0 == CC1 && OpVT.getScalarSizeInBits() > 1 &&
-      IsInteger && CC0 == ISD::SETNE &&
+  // (or  (seteq X, 0), (seteq X, -1)) --> (setult (add X, 1), 2)
+  if (LL == RL && CC0 == CC1 && OpVT.getScalarSizeInBits() > 1 &&
+      IsInteger &&
+      ((IsAnd && CC0 == ISD::SETNE) || (!IsAnd && CC0 == ISD::SETEQ)) &&
       ((isNullConstant(LR) && isAllOnesConstant(RR)) ||
        (isAllOnesConstant(LR) && isNullConstant(RR)))) {
     SDValue One = DAG.getConstant(1, DL, OpVT);
     SDValue Two = DAG.getConstant(2, DL, OpVT);
     SDValue Add = DAG.getNode(ISD::ADD, SDLoc(N0), OpVT, LL, One);
     AddToWorklist(Add.getNode());
-    return DAG.getSetCC(DL, VT, Add, Two, ISD::SETUGE);
+    return DAG.getSetCC(DL, VT, Add, Two,
+                        IsAnd ? ISD::SETUGE : ISD::SETULT);
   }
 
   // Try more general transforms if the predicates match and the only user of
diff --git a/llvm/test/CodeGen/ARM/setcc-logic.ll b/llvm/test/CodeGen/ARM/setcc-logic.ll
index cf482f39f2b5b..dc34db54614f7 100644
--- a/llvm/test/CodeGen/ARM/setcc-logic.ll
+++ b/llvm/test/CodeGen/ARM/setcc-logic.ll
@@ -15,6 +15,20 @@ define zeroext i1 @ne_neg1_and_ne_zero(i32 %x) nounwind {
   ret i1 %and
 }
 
+define zeroext i1 @eq_zero_or_eq_neg1(i32 %x) nounwind {
+; CHECK-LABEL: eq_zero_or_eq_neg1:
+; CHECK:       @ %bb.0:
+; CHECK-NEXT:    add r1, r0, #1
+; CHECK-NEXT:    mov r0, #0
+; CHECK-NEXT:    cmp r1, #2
+; CHECK-NEXT:    movwlo r0, #1
+; CHECK-NEXT:    bx lr
+  %cmp1 = icmp eq i32 %x, 0
+  %cmp2 = icmp eq i32 %x, -1
+  %or = or i1 %cmp1, %cmp2
+  ret i1 %or
+}
+
 ; PR32401 - https://bugs.llvm.org/show_bug.cgi?id=32401
 
 define zeroext i1 @and_eq(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {

``````````

</details>


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


More information about the llvm-commits mailing list