Index: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2102,9 +2102,13 @@ break; case ISD::AND: { // X & -1 -> X (ignoring bits which aren't demanded). - ConstantSDNode *AndVal = isConstOrConstSplat(V.getOperand(1)); - if (AndVal && Mask.isSubsetOf(AndVal->getAPIntValue())) - return V.getOperand(0); + // Also handle the case where masked out bits in X are known to be zero. + if (ConstantSDNode *RHSC = isConstOrConstSplat(V.getOperand(1))) { + const APInt &AndVal = RHSC->getAPIntValue(); + if (Mask.isSubsetOf(AndVal) || + Mask.isSubsetOf(computeKnownBits(V.getOperand(0)).Zero | AndVal)) + return V.getOperand(0); + } break; } case ISD::ANY_EXTEND: { Index: llvm/trunk/test/CodeGen/X86/bt.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/bt.ll +++ llvm/trunk/test/CodeGen/X86/bt.ll @@ -1153,7 +1153,6 @@ ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl ; X86-NEXT: shlb $2, %cl -; X86-NEXT: andb $28, %cl ; X86-NEXT: movzbl %cl, %ecx ; X86-NEXT: btl %ecx, %eax ; X86-NEXT: setb %al @@ -1162,7 +1161,6 @@ ; X64-LABEL: demanded_with_known_zeroes: ; X64: # %bb.0: # %entry ; X64-NEXT: shlb $2, %dil -; X64-NEXT: andb $28, %dil ; X64-NEXT: movzbl %dil, %eax ; X64-NEXT: btl %eax, %esi ; X64-NEXT: setb %al