Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -5616,9 +5616,11 @@ // Check if we can replace AND+IMM64 with a shift. This is possible for // masks like 0xFF000000 or 0x00FFFFFF and if we care only about the zero - // flag. - if (CmpVT == MVT::i64 && !isInt<32>(Mask) && - onlyUsesZeroFlag(SDValue(Node, 0))) { + // flag. Also, test the operand of the 'and' for extra uses because that + // may require a register copy when converting to a shift. + // TODO: Extend this to handle i32. + if (N0.getOperand(0).hasOneUse() && CmpVT == MVT::i64 && + !isInt<8>(Mask) && onlyUsesZeroFlag(SDValue(Node, 0))) { unsigned ShiftOpcode = ISD::DELETED_NODE; unsigned ShiftAmt; if (isMask_64(~Mask)) { Index: llvm/test/CodeGen/X86/cmp.ll =================================================================== --- llvm/test/CodeGen/X86/cmp.ll +++ llvm/test/CodeGen/X86/cmp.ll @@ -413,8 +413,7 @@ ; CHECK-LABEL: highmask_i64_mask32: ; CHECK: # %bb.0: ; CHECK-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0] -; CHECK-NEXT: testq $-1048576, %rdi # encoding: [0x48,0xf7,0xc7,0x00,0x00,0xf0,0xff] -; CHECK-NEXT: # imm = 0xFFF00000 +; CHECK-NEXT: shrq $20, %rdi # encoding: [0x48,0xc1,0xef,0x14] ; CHECK-NEXT: sete %al # encoding: [0x0f,0x94,0xc0] ; CHECK-NEXT: retq # encoding: [0xc3] %and = and i64 %val, -1048576 @@ -453,8 +452,7 @@ ; CHECK-LABEL: lowmask_i64_mask32: ; CHECK: # %bb.0: ; CHECK-NEXT: xorl %eax, %eax # encoding: [0x31,0xc0] -; CHECK-NEXT: testl $1048575, %edi # encoding: [0xf7,0xc7,0xff,0xff,0x0f,0x00] -; CHECK-NEXT: # imm = 0xFFFFF +; CHECK-NEXT: shlq $44, %rdi # encoding: [0x48,0xc1,0xe7,0x2c] ; CHECK-NEXT: setne %al # encoding: [0x0f,0x95,0xc0] ; CHECK-NEXT: retq # encoding: [0xc3] %and = and i64 %val, 1048575