Index: lib/CodeGen/SelectionDAG/TargetLowering.cpp =================================================================== --- lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -570,18 +570,22 @@ Known.Zero &= Known2.Zero; } return false; // Don't fall through, will infinitely loop. - case ISD::AND: + case ISD::AND: { + KnownBits RHSKnown; + // Do not increment Depth here; that can cause an infinite loop. + TLO.DAG.computeKnownBits(Op.getOperand(1), RHSKnown, Depth); + // If the RHS is a constant, check to see if the LHS would be zero without // using the bits from the RHS. Below, we use knowledge about the RHS to // simplify the LHS, here we're using information from the LHS to simplify // the RHS. - if (ConstantSDNode *RHSC = isConstOrConstSplat(Op.getOperand(1))) { + if (RHSKnown.isConstant()) { SDValue Op0 = Op.getOperand(0); KnownBits LHSKnown; // Do not increment Depth here; that can cause an infinite loop. TLO.DAG.computeKnownBits(Op0, LHSKnown, Depth); - // If the LHS already has zeros where RHSC does, this and is dead. - if ((LHSKnown.Zero & NewMask) == (~RHSC->getAPIntValue() & NewMask)) + // If the LHS already has zeros where RHS does, this and is dead. + if ((LHSKnown.Zero & NewMask) == (RHSKnown.Zero & NewMask)) return TLO.CombineTo(Op, Op0); // If any of the set bits in the RHS are known zero on the LHS, shrink @@ -595,13 +599,19 @@ // the xor. For example, for a 32-bit X: // and (xor (srl X, 31), -1), 1 --> xor (srl X, 31), 1 if (isBitwiseNot(Op0) && Op0.hasOneUse() && - LHSKnown.One == ~RHSC->getAPIntValue()) { + LHSKnown.One == RHSKnown.Zero) { SDValue Xor = TLO.DAG.getNode(ISD::XOR, dl, Op.getValueType(), Op0.getOperand(0), Op.getOperand(1)); return TLO.CombineTo(Op, Xor); } } + // If all of the demanded bits are known on RHS, try to simplify LHS. + if (NewMask.isSubsetOf(RHSKnown.Zero | RHSKnown.One)) + if (SimplifyDemandedBits(Op.getOperand(0), NewMask & RHSKnown.One, Known, + TLO, Depth + 1)) + return true; + if (SimplifyDemandedBits(Op.getOperand(1), NewMask, Known, TLO, Depth+1)) return true; assert(!Known.hasConflict() && "Bits known to be one AND zero?"); @@ -631,6 +641,7 @@ // Output known-0 are known to be clear if zero in either the LHS | RHS. Known.Zero |= Known2.Zero; break; + } case ISD::OR: if (SimplifyDemandedBits(Op.getOperand(1), NewMask, Known, TLO, Depth+1)) return true; Index: test/CodeGen/X86/combine-and.ll =================================================================== --- test/CodeGen/X86/combine-and.ll +++ test/CodeGen/X86/combine-and.ll @@ -281,7 +281,6 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: psrlw $1, %xmm0 ; CHECK-NEXT: pand {{.*}}(%rip), %xmm0 -; CHECK-NEXT: pand {{.*}}(%rip), %xmm0 ; CHECK-NEXT: paddb %xmm1, %xmm0 ; CHECK-NEXT: retq %1 = lshr <16 x i8> %a0,