Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3232,6 +3232,25 @@ return DAG.getSetCC(DL, VT, Add, Two, ISD::SETUGE); } + // Try a more general transform if we are comparing if 2 pairs of operands are + // both equal and the only user of the compares is the 'and'. This assumes + // that bitwise logic and a single compare is cheaper than 'and'ing the + // results of 2 compares: + // (and (seteq A, B), (seteq C, D)) --> (seteq (or (xor A, B), (xor C, D)), 0) + + // FIXME: This is limited to scalar integer because the above folds don't + // correctly check for vector constants. We don't want to fold those special + // cases to this because we don't have combines to produce the optimal code. + + if (OpVT.isScalarInteger() && CC0 == ISD::SETEQ && CC0 == CC1 && + N0.hasOneUse() && N1.hasOneUse()) { + SDValue XorL = DAG.getNode(ISD::XOR, SDLoc(N0), OpVT, LL, LR); + SDValue XorR = DAG.getNode(ISD::XOR, SDLoc(N1), OpVT, RL, RR); + SDValue Or = DAG.getNode(ISD::OR, DL, OpVT, XorL, XorR); + SDValue Zero = DAG.getConstant(0, DL, OpVT); + return DAG.getSetCC(DL, VT, Or, Zero, ISD::SETEQ); + } + // Canonicalize equivalent operands to LL == RL. if (LL == RR && LR == RL) { CC1 = ISD::getSetCCSwappedOperands(CC1); Index: test/CodeGen/ARM/and-setcc.ll =================================================================== --- test/CodeGen/ARM/and-setcc.ll +++ test/CodeGen/ARM/and-setcc.ll @@ -20,13 +20,11 @@ define zeroext i1 @cmpeq_logical(i32 %a, i32 %b, i32 %c, i32 %d) nounwind { ; CHECK-LABEL: cmpeq_logical: ; CHECK: @ BB#0: -; CHECK-NEXT: cmp r2, r3 -; CHECK-NEXT: mov r2, #0 -; CHECK-NEXT: movweq r2, #1 -; CHECK-NEXT: mov r12, #0 -; CHECK-NEXT: cmp r0, r1 -; CHECK-NEXT: movweq r12, #1 -; CHECK-NEXT: and r0, r12, r2 +; CHECK-NEXT: eor r2, r2, r3 +; CHECK-NEXT: eor r0, r0, r1 +; CHECK-NEXT: orrs r0, r0, r2 +; CHECK-NEXT: mov r0, #0 +; CHECK-NEXT: movweq r0, #1 ; CHECK-NEXT: bx lr %cmp1 = icmp eq i32 %a, %b %cmp2 = icmp eq i32 %c, %d Index: test/CodeGen/PowerPC/and-setcc.ll =================================================================== --- test/CodeGen/PowerPC/and-setcc.ll +++ test/CodeGen/PowerPC/and-setcc.ll @@ -21,11 +21,11 @@ define zeroext i1 @cmpeq_logical(i16 zeroext %a, i16 zeroext %b, i16 zeroext %c, i16 zeroext %d) { ; CHECK-LABEL: cmpeq_logical: ; CHECK: # BB#0: -; CHECK-NEXT: cmpw 0, 3, 4 -; CHECK-NEXT: cmpw 1, 5, 6 -; CHECK-NEXT: li 3, 1 -; CHECK-NEXT: crnand 20, 2, 6 -; CHECK-NEXT: isel 3, 0, 3, 20 +; CHECK-NEXT: xor 5, 5, 6 +; CHECK-NEXT: xor 3, 3, 4 +; CHECK-NEXT: or 3, 3, 5 +; CHECK-NEXT: cntlzw 3, 3 +; CHECK-NEXT: rlwinm 3, 3, 27, 31, 31 ; CHECK-NEXT: blr %cmp1 = icmp eq i16 %a, %b %cmp2 = icmp eq i16 %c, %d Index: test/CodeGen/X86/and-setcc.ll =================================================================== --- test/CodeGen/X86/and-setcc.ll +++ test/CodeGen/X86/and-setcc.ll @@ -19,11 +19,10 @@ define zeroext i1 @cmpeq_logical(i8 %a, i8 %b, i8 %c, i8 %d) nounwind { ; CHECK-LABEL: cmpeq_logical: ; CHECK: # BB#0: -; CHECK-NEXT: cmpb %sil, %dil -; CHECK-NEXT: sete %sil -; CHECK-NEXT: cmpb %cl, %dl +; CHECK-NEXT: xorl %esi, %edi +; CHECK-NEXT: xorl %ecx, %edx +; CHECK-NEXT: orb %dl, %dil ; CHECK-NEXT: sete %al -; CHECK-NEXT: andb %sil, %al ; CHECK-NEXT: retq %cmp1 = icmp eq i8 %a, %b %cmp2 = icmp eq i8 %c, %d Index: test/CodeGen/X86/avx512-cmp.ll =================================================================== --- test/CodeGen/X86/avx512-cmp.ll +++ test/CodeGen/X86/avx512-cmp.ll @@ -120,12 +120,12 @@ define i32 @test8(i32 %a1, i32 %a2, i32 %a3) { ; ALL-LABEL: test8: ; ALL: ## BB#0: +; ALL-NEXT: notl %edi +; ALL-NEXT: xorl $-2147483648, %esi ## imm = 0x80000000 ; ALL-NEXT: testl %edx, %edx ; ALL-NEXT: movl $1, %eax ; ALL-NEXT: cmovel %eax, %edx -; ALL-NEXT: cmpl $-2147483648, %esi ## imm = 0x80000000 -; ALL-NEXT: cmovnel %edx, %eax -; ALL-NEXT: cmpl $-1, %edi +; ALL-NEXT: orl %edi, %esi ; ALL-NEXT: cmovnel %edx, %eax ; ALL-NEXT: retq %tmp1 = icmp eq i32 %a1, -1