[llvm] r293208 - [InstCombine] use m_APInt to allow (X << C) >>u C --> X & (-1 >>u C) with splat vectors
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Thu Jan 26 12:52:27 PST 2017
Author: spatel
Date: Thu Jan 26 14:52:27 2017
New Revision: 293208
URL: http://llvm.org/viewvc/llvm-project?rev=293208&view=rev
Log:
[InstCombine] use m_APInt to allow (X << C) >>u C --> X & (-1 >>u C) with splat vectors
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp
llvm/trunk/test/Transforms/InstCombine/apint-shift.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp?rev=293208&r1=293207&r2=293208&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp Thu Jan 26 14:52:27 2017
@@ -353,29 +353,37 @@ foldShiftByConstOfShiftByConst(BinaryOpe
// Combinations of right and left shifts will still be optimized in
// DAGCombine where scalar evolution no longer applies.
+ Value *X = ShiftOp->getOperand(0);
+ unsigned ShiftAmt1 = ShAmt1->getLimitedValue();
+ unsigned ShiftAmt2 = COp1->getLimitedValue();
+ assert(ShiftAmt2 != 0 && "Should have been simplified earlier");
+ if (ShiftAmt1 == 0)
+ return nullptr; // Will be simplified in the future.
+
+ if (ShiftAmt1 == ShiftAmt2) {
+ // FIXME: This repeats a fold that exists in foldShiftedShift(), but we're
+ // not handling the related fold here:
+ // (X >>u C) << C --> X & (-1 << C).
+ // foldShiftedShift() is always called before this, but it is restricted to
+ // only handle cases where the ShiftOp has one use. We don't have that
+ // restriction here.
+ if (I.getOpcode() != Instruction::LShr ||
+ ShiftOp->getOpcode() != Instruction::Shl)
+ return nullptr;
+
+ // (X << C) >>u C --> X & (-1 >>u C).
+ APInt Mask(APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt1));
+ return BinaryOperator::CreateAnd(X, ConstantInt::get(I.getType(), Mask));
+ }
+
// FIXME: Everything under here should be extended to work with vector types.
auto *ShiftAmt1C = dyn_cast<ConstantInt>(ShiftOp->getOperand(1));
if (!ShiftAmt1C)
return nullptr;
- uint32_t ShiftAmt1 = ShiftAmt1C->getLimitedValue(TypeBits);
- uint32_t ShiftAmt2 = COp1->getLimitedValue(TypeBits);
- assert(ShiftAmt2 != 0 && "Should have been simplified earlier");
- if (ShiftAmt1 == 0)
- return nullptr; // Will be simplified in the future.
-
- Value *X = ShiftOp->getOperand(0);
IntegerType *Ty = cast<IntegerType>(I.getType());
- if (ShiftAmt1 == ShiftAmt2) {
- // If we have ((X << C) >>u C), turn this into X & (-1 >>u C).
- if (I.getOpcode() == Instruction::LShr &&
- ShiftOp->getOpcode() == Instruction::Shl) {
- APInt Mask(APInt::getLowBitsSet(TypeBits, TypeBits - ShiftAmt1));
- return BinaryOperator::CreateAnd(X,
- ConstantInt::get(I.getContext(), Mask));
- }
- } else if (ShiftAmt1 < ShiftAmt2) {
+ if (ShiftAmt1 < ShiftAmt2) {
uint32_t ShiftDiff = ShiftAmt2 - ShiftAmt1;
// (X >>?,exact C1) << C2 --> X << (C2-C1)
Modified: llvm/trunk/test/Transforms/InstCombine/apint-shift.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/apint-shift.ll?rev=293208&r1=293207&r2=293208&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/apint-shift.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/apint-shift.ll Thu Jan 26 14:52:27 2017
@@ -444,12 +444,12 @@ define i44 @shl_lshr_eq_amt_multi_use(i4
ret i44 %D
}
-; FIXME: Fold vector lshr (shl X, C), C -> and X, C' regardless of the number of uses of the shl.
+; Fold vector lshr (shl X, C), C -> and X, C' regardless of the number of uses of the shl.
define <2 x i44> @shl_lshr_eq_amt_multi_use_splat_vec(<2 x i44> %A) {
; CHECK-LABEL: @shl_lshr_eq_amt_multi_use_splat_vec(
; CHECK-NEXT: [[B:%.*]] = shl <2 x i44> %A, <i44 33, i44 33>
-; CHECK-NEXT: [[C:%.*]] = lshr exact <2 x i44> [[B]], <i44 33, i44 33>
+; CHECK-NEXT: [[C:%.*]] = and <2 x i44> %A, <i44 2047, i44 2047>
; CHECK-NEXT: [[D:%.*]] = or <2 x i44> [[B]], [[C]]
; CHECK-NEXT: ret <2 x i44> [[D]]
;
More information about the llvm-commits
mailing list