Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 6a295f2

Browse files
committed
[InstCombine] use m_APInt to allow (X << C) >>u C --> X & (-1 >>u C) with splat vectors
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293208 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 8f44449 commit 6a295f2

File tree

2 files changed

+26
-18
lines changed

2 files changed

+26
-18
lines changed

lib/Transforms/InstCombine/InstCombineShifts.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -353,29 +353,37 @@ foldShiftByConstOfShiftByConst(BinaryOperator &I, const APInt *COp1,
353353
// Combinations of right and left shifts will still be optimized in
354354
// DAGCombine where scalar evolution no longer applies.
355355

356+
Value *X = ShiftOp->getOperand(0);
357+
unsigned ShiftAmt1 = ShAmt1->getLimitedValue();
358+
unsigned ShiftAmt2 = COp1->getLimitedValue();
359+
assert(ShiftAmt2 != 0 && "Should have been simplified earlier");
360+
if (ShiftAmt1 == 0)
361+
return nullptr; // Will be simplified in the future.
362+
363+
if (ShiftAmt1 == ShiftAmt2) {
364+
// FIXME: This repeats a fold that exists in foldShiftedShift(), but we're
365+
// not handling the related fold here:
366+
// (X >>u C) << C --> X & (-1 << C).
367+
// foldShiftedShift() is always called before this, but it is restricted to
368+
// only handle cases where the ShiftOp has one use. We don't have that
369+
// restriction here.
370+
if (I.getOpcode() != Instruction::LShr ||
371+
ShiftOp->getOpcode() != Instruction::Shl)
372+
return nullptr;
373+
374+
// (X << C) >>u C --> X & (-1 >>u C).
375+
APInt Mask(APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt1));
376+
return BinaryOperator::CreateAnd(X, ConstantInt::get(I.getType(), Mask));
377+
}
378+
356379
// FIXME: Everything under here should be extended to work with vector types.
357380

358381
auto *ShiftAmt1C = dyn_cast<ConstantInt>(ShiftOp->getOperand(1));
359382
if (!ShiftAmt1C)
360383
return nullptr;
361384

362-
uint32_t ShiftAmt1 = ShiftAmt1C->getLimitedValue(TypeBits);
363-
uint32_t ShiftAmt2 = COp1->getLimitedValue(TypeBits);
364-
assert(ShiftAmt2 != 0 && "Should have been simplified earlier");
365-
if (ShiftAmt1 == 0)
366-
return nullptr; // Will be simplified in the future.
367-
368-
Value *X = ShiftOp->getOperand(0);
369385
IntegerType *Ty = cast<IntegerType>(I.getType());
370-
if (ShiftAmt1 == ShiftAmt2) {
371-
// If we have ((X << C) >>u C), turn this into X & (-1 >>u C).
372-
if (I.getOpcode() == Instruction::LShr &&
373-
ShiftOp->getOpcode() == Instruction::Shl) {
374-
APInt Mask(APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt1));
375-
return BinaryOperator::CreateAnd(X,
376-
ConstantInt::get(I.getContext(), Mask));
377-
}
378-
} else if (ShiftAmt1 < ShiftAmt2) {
386+
if (ShiftAmt1 < ShiftAmt2) {
379387
uint32_t ShiftDiff = ShiftAmt2 - ShiftAmt1;
380388

381389
// (X >>?,exact C1) << C2 --> X << (C2-C1)

test/Transforms/InstCombine/apint-shift.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,12 +444,12 @@ define i44 @shl_lshr_eq_amt_multi_use(i44 %A) {
444444
ret i44 %D
445445
}
446446

447-
; FIXME: Fold vector lshr (shl X, C), C -> and X, C' regardless of the number of uses of the shl.
447+
; Fold vector lshr (shl X, C), C -> and X, C' regardless of the number of uses of the shl.
448448

449449
define <2 x i44> @shl_lshr_eq_amt_multi_use_splat_vec(<2 x i44> %A) {
450450
; CHECK-LABEL: @shl_lshr_eq_amt_multi_use_splat_vec(
451451
; CHECK-NEXT: [[B:%.*]] = shl <2 x i44> %A, <i44 33, i44 33>
452-
; CHECK-NEXT: [[C:%.*]] = lshr exact <2 x i44> [[B]], <i44 33, i44 33>
452+
; CHECK-NEXT: [[C:%.*]] = and <2 x i44> %A, <i44 2047, i44 2047>
453453
; CHECK-NEXT: [[D:%.*]] = or <2 x i44> [[B]], [[C]]
454454
; CHECK-NEXT: ret <2 x i44> [[D]]
455455
;

0 commit comments

Comments
 (0)