Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -3025,6 +3025,18 @@ } } + // Given: + // icmp eq/ne (urem %x, %y), 0 + // Iff %x has 0 or 1 bits set, and %y has at least 2 bits set, omit 'urem': + // icmp eq/ne %x, 0 + if (N0.getOpcode() == ISD::UREM && N1C->isNullValue() && + (Cond == ISD::SETEQ || Cond == ISD::SETNE)) { + KnownBits XKnown = DAG.computeKnownBits(N0.getOperand(0)); + KnownBits YKnown = DAG.computeKnownBits(N0.getOperand(1)); + if (XKnown.countMaxPopulation() == 1 && YKnown.countMinPopulation() >= 2) + return DAG.getSetCC(dl, VT, N0.getOperand(0), N1, Cond); + } + if (SDValue V = optimizeSetCCOfSignedTruncationCheck(VT, N0, N1, Cond, DCI, dl)) return V; Index: test/CodeGen/X86/jump_sign.ll =================================================================== --- test/CodeGen/X86/jump_sign.ll +++ test/CodeGen/X86/jump_sign.ll @@ -397,14 +397,11 @@ ; CHECK-LABEL: func_test1: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: movl b, %eax -; CHECK-NEXT: xorl %ecx, %ecx ; CHECK-NEXT: cmpl {{[0-9]+}}(%esp), %eax ; CHECK-NEXT: setb %cl ; CHECK-NEXT: movl a, %eax -; CHECK-NEXT: andl %eax, %ecx -; CHECK-NEXT: imull $-85, %ecx, %ecx -; CHECK-NEXT: cmpb $86, %cl -; CHECK-NEXT: jb .LBB18_2 +; CHECK-NEXT: testb %al, %cl +; CHECK-NEXT: je .LBB18_2 ; CHECK-NEXT: # %bb.1: # %if.then ; CHECK-NEXT: decl %eax ; CHECK-NEXT: movl %eax, a Index: test/CodeGen/X86/omit-urem-of-power-of-two-or-zero-when-comparing-with-zero.ll =================================================================== --- test/CodeGen/X86/omit-urem-of-power-of-two-or-zero-when-comparing-with-zero.ll +++ test/CodeGen/X86/omit-urem-of-power-of-two-or-zero-when-comparing-with-zero.ll @@ -14,11 +14,8 @@ define i1 @p0_scalar_urem_by_const(i32 %x, i32 %y) { ; CHECK-LABEL: p0_scalar_urem_by_const: ; CHECK: # %bb.0: -; CHECK-NEXT: andl $128, %edi -; CHECK-NEXT: imull $-1431655765, %edi, %eax # imm = 0xAAAAAAAB -; CHECK-NEXT: rorl %eax -; CHECK-NEXT: cmpl $1431655766, %eax # imm = 0x55555556 -; CHECK-NEXT: setb %al +; CHECK-NEXT: testb $-128, %dil +; CHECK-NEXT: sete %al ; CHECK-NEXT: retq %t0 = and i32 %x, 128 ; clearly a power-of-two or zero %t1 = urem i32 %t0, 6 ; '6' is clearly not a power of two @@ -29,12 +26,7 @@ define i1 @p1_scalar_urem_by_nonconst(i32 %x, i32 %y) { ; CHECK-LABEL: p1_scalar_urem_by_nonconst: ; CHECK: # %bb.0: -; CHECK-NEXT: movl %edi, %eax -; CHECK-NEXT: andl $128, %eax -; CHECK-NEXT: orl $6, %esi -; CHECK-NEXT: xorl %edx, %edx -; CHECK-NEXT: divl %esi -; CHECK-NEXT: testl %edx, %edx +; CHECK-NEXT: testb $-128, %dil ; CHECK-NEXT: sete %al ; CHECK-NEXT: retq %t0 = and i32 %x, 128 ; clearly a power-of-two or zero