Skip to content

Commit 3f94bdc

Browse files
author
spatel
committed
[x86] reduce 64-bit mask constant to 32-bits by right shifting
This is a follow-up from D38181 (r314023). We have to put 64-bit constants into a register using a separate instruction, so we should try harder to avoid that. From what I see, we're not likely to encounter this pattern in the DAG because the upstream setcc combines from this don't (usually?) produce this pattern. If we fix that, then this will become more relevant. Since the cost of handling this case is just loosening the predicate of the existing fold, we might as well do it now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314064 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 1717084 commit 3f94bdc

File tree

2 files changed

+17
-16
lines changed

2 files changed

+17
-16
lines changed

lib/Target/X86/X86ISelLowering.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31688,21 +31688,22 @@ static SDValue combineShiftRightLogical(SDNode *N, SelectionDAG &DAG) {
3168831688
if (!ShiftC || !AndC)
3168931689
return SDValue();
3169031690

31691-
// If the 'and' mask is already smaller than a byte, then don't bother.
31692-
// If the new 'and' mask would be bigger than a byte, then don't bother.
31693-
// If the mask fits in a byte, then we know we can generate smaller and
31694-
// potentially better code by shifting first.
31695-
// TODO: Always try to shrink a mask that is over 32-bits?
31691+
// If we can shrink the constant mask below 8-bits or 32-bits, then this
31692+
// transform should reduce code size. It may also enable secondary transforms
31693+
// from improved known-bits analysis or instruction selection.
3169631694
APInt MaskVal = AndC->getAPIntValue();
3169731695
APInt NewMaskVal = MaskVal.lshr(ShiftC->getAPIntValue());
31698-
if (MaskVal.getMinSignedBits() <= 8 || NewMaskVal.getMinSignedBits() > 8)
31699-
return SDValue();
31700-
31701-
// srl (and X, AndC), ShiftC --> and (srl X, ShiftC), (AndC >> ShiftC)
31702-
SDLoc DL(N);
31703-
SDValue NewMask = DAG.getConstant(NewMaskVal, DL, VT);
31704-
SDValue NewShift = DAG.getNode(ISD::SRL, DL, VT, N0.getOperand(0), N1);
31705-
return DAG.getNode(ISD::AND, DL, VT, NewShift, NewMask);
31696+
unsigned OldMaskSize = MaskVal.getMinSignedBits();
31697+
unsigned NewMaskSize = NewMaskVal.getMinSignedBits();
31698+
if ((OldMaskSize > 8 && NewMaskSize <= 8) ||
31699+
(OldMaskSize > 32 && NewMaskSize <= 32)) {
31700+
// srl (and X, AndC), ShiftC --> and (srl X, ShiftC), (AndC >> ShiftC)
31701+
SDLoc DL(N);
31702+
SDValue NewMask = DAG.getConstant(NewMaskVal, DL, VT);
31703+
SDValue NewShift = DAG.getNode(ISD::SRL, DL, VT, N0.getOperand(0), N1);
31704+
return DAG.getNode(ISD::AND, DL, VT, NewShift, NewMask);
31705+
}
31706+
return SDValue();
3170631707
}
3170731708

3170831709
/// \brief Returns a vector of 0s if the node in input is a vector logical

test/CodeGen/X86/shift-and.ll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,9 +205,9 @@ define i64 @big_mask_constant(i64 %x) nounwind {
205205
;
206206
; X64-LABEL: big_mask_constant:
207207
; X64: # BB#0:
208-
; X64-NEXT: movabsq $17179869184, %rax # imm = 0x400000000
209-
; X64-NEXT: andq %rdi, %rax
210-
; X64-NEXT: shrq $7, %rax
208+
; X64-NEXT: shrq $7, %rdi
209+
; X64-NEXT: andl $134217728, %edi # imm = 0x8000000
210+
; X64-NEXT: movq %rdi, %rax
211211
; X64-NEXT: retq
212212
%and = and i64 %x, 17179869184 ; 0x400000000
213213
%sh = lshr i64 %and, 7

0 commit comments

Comments
 (0)