// 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);
}
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
;
; 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