Skip to content

Commit 4a24c68

Browse files
tclin914claude
andauthored
[DAGCombiner] Fold (or (seteq X, 0), (seteq X, -1)) to (setult (add X, 1), 2) (llvm#192183)
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. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 7780e54 commit 4a24c68

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6605,17 +6605,17 @@ SDValue DAGCombiner::foldLogicOfSetCCs(bool IsAnd, SDValue N0, SDValue N1,
66056605
}
66066606
}
66076607

6608-
// TODO: What is the 'or' equivalent of this fold?
66096608
// (and (setne X, 0), (setne X, -1)) --> (setuge (add X, 1), 2)
6610-
if (IsAnd && LL == RL && CC0 == CC1 && OpVT.getScalarSizeInBits() > 1 &&
6611-
IsInteger && CC0 == ISD::SETNE &&
6609+
// (or (seteq X, 0), (seteq X, -1)) --> (setult (add X, 1), 2)
6610+
if (LL == RL && CC0 == CC1 && OpVT.getScalarSizeInBits() > 1 && IsInteger &&
6611+
((IsAnd && CC0 == ISD::SETNE) || (!IsAnd && CC0 == ISD::SETEQ)) &&
66126612
((isNullConstant(LR) && isAllOnesConstant(RR)) ||
66136613
(isAllOnesConstant(LR) && isNullConstant(RR)))) {
66146614
SDValue One = DAG.getConstant(1, DL, OpVT);
66156615
SDValue Two = DAG.getConstant(2, DL, OpVT);
66166616
SDValue Add = DAG.getNode(ISD::ADD, SDLoc(N0), OpVT, LL, One);
66176617
AddToWorklist(Add.getNode());
6618-
return DAG.getSetCC(DL, VT, Add, Two, ISD::SETUGE);
6618+
return DAG.getSetCC(DL, VT, Add, Two, IsAnd ? ISD::SETUGE : ISD::SETULT);
66196619
}
66206620

66216621
// Try more general transforms if the predicates match and the only user of

llvm/test/CodeGen/ARM/setcc-logic.ll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@ define zeroext i1 @ne_neg1_and_ne_zero(i32 %x) nounwind {
1515
ret i1 %and
1616
}
1717

18+
define zeroext i1 @eq_zero_or_eq_neg1(i32 %x) nounwind {
19+
; CHECK-LABEL: eq_zero_or_eq_neg1:
20+
; CHECK: @ %bb.0:
21+
; CHECK-NEXT: add r1, r0, #1
22+
; CHECK-NEXT: mov r0, #0
23+
; CHECK-NEXT: cmp r1, #2
24+
; CHECK-NEXT: movwlo r0, #1
25+
; CHECK-NEXT: bx lr
26+
%cmp1 = icmp eq i32 %x, 0
27+
%cmp2 = icmp eq i32 %x, -1
28+
%or = or i1 %cmp1, %cmp2
29+
ret i1 %or
30+
}
31+
1832
; PR32401 - https://bugs.llvm.org/show_bug.cgi?id=32401
1933

2034
define zeroext i1 @and_eq(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {

0 commit comments

Comments
 (0)