diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 0d71761fd0f..0e316db55cb 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2675,6 +2675,19 @@ SDValue DAGCombiner::visitAND(SDNode *N) { return DAG.getSetCC(SDLoc(N), VT, ORNode, LR, Op1); } } + // Simplify (and (setne X, 0), (setne X, -1)) -> (setuge (add X, 1), 2) + if (LL == RL && isa(LR) && isa(RR) && + Op0 == Op1 && LL.getValueType().isInteger() && + Op0 == ISD::SETNE && ((cast(LR)->isNullValue() && + cast(RR)->isAllOnesValue()) || + (cast(LR)->isAllOnesValue() && + cast(RR)->isNullValue()))) { + SDValue ADDNode = DAG.getNode(ISD::ADD, SDLoc(N0), LL.getValueType(), + LL, DAG.getConstant(1, LL.getValueType())); + AddToWorkList(ADDNode.getNode()); + return DAG.getSetCC(SDLoc(N), VT, ADDNode, + DAG.getConstant(2, LL.getValueType()), ISD::SETUGE); + } // canonicalize equivalent to ll == rl if (LL == RR && LR == RL) { Op1 = ISD::getSetCCSwappedOperands(Op1); diff --git a/test/CodeGen/ARM/setcc-sentinals.ll b/test/CodeGen/ARM/setcc-sentinals.ll new file mode 100644 index 00000000000..4033a810985 --- /dev/null +++ b/test/CodeGen/ARM/setcc-sentinals.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -mcpu=cortex-a8 -march=arm -asm-verbose=false | FileCheck %s + +define zeroext i1 @test0(i32 %x) nounwind { +; CHECK-LABEL: test0: +; CHECK-NEXT: add [[REG:(r[0-9]+)|(lr)]], r0, #1 +; CHECK-NEXT: mov r0, #0 +; CHECK-NEXT: cmp [[REG]], #1 +; CHECK-NEXT: movhi r0, #1 +; CHECK-NEXT: bx lr + %cmp1 = icmp ne i32 %x, -1 + %not.cmp = icmp ne i32 %x, 0 + %.cmp1 = and i1 %cmp1, %not.cmp + ret i1 %.cmp1 +} diff --git a/test/CodeGen/X86/setcc-sentinals.ll b/test/CodeGen/X86/setcc-sentinals.ll new file mode 100644 index 00000000000..cae5f58d17f --- /dev/null +++ b/test/CodeGen/X86/setcc-sentinals.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -mcpu=generic -march=x86-64 -asm-verbose=false | FileCheck %s + +define zeroext i1 @test0(i64 %x) nounwind { +; CHECK-LABEL: test0: +; CHECK-NEXT: incq %rdi +; CHECK-NEXT: cmpq $1, %rdi +; CHECK-NEXT: seta %al +; CHECK-NEXT: ret + %cmp1 = icmp ne i64 %x, -1 + %not.cmp = icmp ne i64 %x, 0 + %.cmp1 = and i1 %cmp1, %not.cmp + ret i1 %.cmp1 +}