diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index f66194ddd271f..c23c832cb2eb1 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -22975,8 +22975,19 @@ static SDValue getBT(SDValue Src, SDValue BitNo, const SDLoc &DL, SelectionDAG & // If the operand types disagree, extend the shift amount to match. Since // BT ignores high bits (like shifts) we can use anyextend. - if (Src.getValueType() != BitNo.getValueType()) - BitNo = DAG.getNode(ISD::ANY_EXTEND, DL, Src.getValueType(), BitNo); + if (Src.getValueType() != BitNo.getValueType()) { + // Peek through a mask/modulo operation. + // TODO: DAGCombine fails to do this as it just checks isTruncateFree, but + // we probably need a better IsDesirableToPromoteOp to handle this as well. + if (BitNo.getOpcode() == ISD::AND && BitNo->hasOneUse()) + BitNo = DAG.getNode(ISD::AND, DL, Src.getValueType(), + DAG.getNode(ISD::ANY_EXTEND, DL, Src.getValueType(), + BitNo.getOperand(0)), + DAG.getNode(ISD::ANY_EXTEND, DL, Src.getValueType(), + BitNo.getOperand(1))); + else + BitNo = DAG.getNode(ISD::ANY_EXTEND, DL, Src.getValueType(), BitNo); + } return DAG.getNode(X86ISD::BT, DL, MVT::i32, Src, BitNo); } diff --git a/llvm/test/CodeGen/X86/setcc.ll b/llvm/test/CodeGen/X86/setcc.ll index d600aa65578e4..9bac47c1a9d35 100644 --- a/llvm/test/CodeGen/X86/setcc.ll +++ b/llvm/test/CodeGen/X86/setcc.ll @@ -311,9 +311,8 @@ define i16 @shift_and(i16 %a) { define i32 @PR55138(i32 %x) { ; X86-LABEL: PR55138: ; X86: ## %bb.0: -; X86-NEXT: movb {{[0-9]+}}(%esp), %al -; X86-NEXT: andb $15, %al -; X86-NEXT: movzbl %al, %ecx +; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: andl $15, %ecx ; X86-NEXT: movl $27030, %edx ## imm = 0x6996 ; X86-NEXT: xorl %eax, %eax ; X86-NEXT: btl %ecx, %edx @@ -322,11 +321,10 @@ define i32 @PR55138(i32 %x) { ; ; X64-LABEL: PR55138: ; X64: ## %bb.0: -; X64-NEXT: andb $15, %dil -; X64-NEXT: movzbl %dil, %ecx -; X64-NEXT: movl $27030, %edx ## imm = 0x6996 +; X64-NEXT: andl $15, %edi +; X64-NEXT: movl $27030, %ecx ## imm = 0x6996 ; X64-NEXT: xorl %eax, %eax -; X64-NEXT: btl %ecx, %edx +; X64-NEXT: btl %edi, %ecx ; X64-NEXT: setb %al ; X64-NEXT: retq %urem = and i32 %x, 15