This function reorders AND and SHL to enable the SHL to fold into an LEA. The
upper bits of the AND will be shifted out by the SHL so it doesn't matter what
mask value we use for these bits. By using sign bits from the original mask in
these upper bits we might enable a shorter immediate encoding to be used.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357846
91177308-0d34-0410-b5e6-
96231b3b80d8
// allows us to fold the shift into this addressing mode. Returns false if the
// transform succeeded.
static bool foldMaskedShiftToScaledMask(SelectionDAG &DAG, SDValue N,
- uint64_t Mask,
SDValue Shift, SDValue X,
X86ISelAddressMode &AM) {
if (Shift.getOpcode() != ISD::SHL ||
if (ShiftAmt != 1 && ShiftAmt != 2 && ShiftAmt != 3)
return true;
+ // Use a signed mask so that shifting right will insert sign bits. These
+ // bits will be removed when we shift the result left so it doesn't matter
+ // what we use. This might allow a smaller immediate encoding.
+ int64_t Mask = cast<ConstantSDNode>(N->getOperand(1))->getSExtValue();
+
MVT VT = N.getSimpleValueType();
SDLoc DL(N);
SDValue NewMask = DAG.getConstant(Mask >> ShiftAmt, DL, VT);
// Try to swap the mask and shift to place shifts which can be done as
// a scale on the outside of the mask.
- if (!foldMaskedShiftToScaledMask(*CurDAG, N, Mask, Shift, X, AM))
+ if (!foldMaskedShiftToScaledMask(*CurDAG, N, Shift, X, AM))
return false;
// Try to fold the mask and shift into BEXTR and scale.
define i8 @t1(i8* %X, i64 %i) {
; CHECK-LABEL: t1:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: movabsq $4611686018427387649, %rax # imm = 0x3FFFFFFFFFFFFF01
-; CHECK-NEXT: andq %rsi, %rax
-; CHECK-NEXT: movb (%rdi,%rax,4), %al
+; CHECK-NEXT: andq $-255, %rsi
+; CHECK-NEXT: movb (%rdi,%rsi,4), %al
; CHECK-NEXT: retq
entry:
define i8 @t2(i8* %X, i64 %i) {
; CHECK-LABEL: t2:
; CHECK: # %bb.0: # %entry
-; CHECK-NEXT: movabsq $4611686018427387890, %rax # imm = 0x3FFFFFFFFFFFFFF2
-; CHECK-NEXT: andq %rsi, %rax
-; CHECK-NEXT: movb (%rdi,%rax,4), %al
+; CHECK-NEXT: andq $-14, %rsi
+; CHECK-NEXT: movb (%rdi,%rsi,4), %al
; CHECK-NEXT: retq
entry:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; CHECK-NEXT: andl $1073741810, %ecx # imm = 0x3FFFFFF2
+; CHECK-NEXT: andl $-14, %ecx
; CHECK-NEXT: movb (%eax,%ecx,4), %al
; CHECK-NEXT: retl
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax
; CHECK-NEXT: movl {{[0-9]+}}(%esp), %ecx
-; CHECK-NEXT: andl $1073741569, %ecx # imm = 0x3FFFFF01
+; CHECK-NEXT: andl $-255, %ecx
; CHECK-NEXT: movb (%eax,%ecx,4), %al
; CHECK-NEXT: retl