summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp38
-rw-r--r--llvm/test/Transforms/InstCombine/apint-mul1.ll2
-rw-r--r--llvm/test/Transforms/InstCombine/apint-mul2.ll2
3 files changed, 23 insertions, 19 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
index 6e7e11a15ae..9fd65001d14 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
@@ -132,18 +132,30 @@ static bool IsMultiple(const APInt &C1, const APInt &C2, APInt &Quotient,
/// \brief A helper routine of InstCombiner::visitMul().
///
-/// If C is a vector of known powers of 2, then this function returns
-/// a new vector obtained from C replacing each element with its logBase2.
+/// If C is a scalar/vector of known powers of 2, then this function returns
+/// a new scalar/vector obtained from logBase2 of C.
/// Return a null pointer otherwise.
-static Constant *getLogBase2Vector(ConstantDataVector *CV) {
+static Constant *getLogBase2(Type *Ty, Constant *C) {
const APInt *IVal;
- SmallVector<Constant *, 4> Elts;
+ if (const auto *CI = dyn_cast<ConstantInt>(C))
+ if (match(C, m_APInt(IVal)) && IVal->isPowerOf2())
+ return ConstantInt::get(Ty, IVal->logBase2());
+
+ if (!Ty->isVectorTy())
+ return nullptr;
- for (unsigned I = 0, E = CV->getNumElements(); I != E; ++I) {
- Constant *Elt = CV->getElementAsConstant(I);
+ SmallVector<Constant *, 4> Elts;
+ for (unsigned I = 0, E = Ty->getVectorNumElements(); I != E; ++I) {
+ Constant *Elt = C->getAggregateElement(I);
+ if (!Elt)
+ return nullptr;
+ if (isa<UndefValue>(Elt)) {
+ Elts.push_back(UndefValue::get(Ty->getScalarType()));
+ continue;
+ }
if (!match(Elt, m_APInt(IVal)) || !IVal->isPowerOf2())
return nullptr;
- Elts.push_back(ConstantInt::get(Elt->getType(), IVal->logBase2()));
+ Elts.push_back(ConstantInt::get(Ty->getScalarType(), IVal->logBase2()));
}
return ConstantVector::get(Elts);
@@ -232,16 +244,8 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
}
if (match(&I, m_Mul(m_Value(NewOp), m_Constant(C1)))) {
- Constant *NewCst = nullptr;
- if (match(C1, m_APInt(IVal)) && IVal->isPowerOf2())
- // Replace X*(2^C) with X << C, where C is either a scalar or a splat.
- NewCst = ConstantInt::get(NewOp->getType(), IVal->logBase2());
- else if (ConstantDataVector *CV = dyn_cast<ConstantDataVector>(C1))
- // Replace X*(2^C) with X << C, where C is a vector of known
- // constant powers of 2.
- NewCst = getLogBase2Vector(CV);
-
- if (NewCst) {
+ // Replace X*(2^C) with X << C, where C is either a scalar or a vector.
+ if (Constant *NewCst = getLogBase2(NewOp->getType(), C1)) {
unsigned Width = NewCst->getType()->getPrimitiveSizeInBits();
BinaryOperator *Shl = BinaryOperator::CreateShl(NewOp, NewCst);
diff --git a/llvm/test/Transforms/InstCombine/apint-mul1.ll b/llvm/test/Transforms/InstCombine/apint-mul1.ll
index cd23ff5a865..93fa5b0504c 100644
--- a/llvm/test/Transforms/InstCombine/apint-mul1.ll
+++ b/llvm/test/Transforms/InstCombine/apint-mul1.ll
@@ -24,7 +24,7 @@ define <2 x i17> @test2(<2 x i17> %X) {
define <2 x i17> @test3(<2 x i17> %X) {
; CHECK-LABEL: @test3(
-; CHECK-NEXT: [[Y:%.*]] = mul <2 x i17> [[X:%.*]], <i17 1024, i17 256>
+; CHECK-NEXT: [[Y:%.*]] = shl <2 x i17> [[X:%.*]], <i17 10, i17 8>
; CHECK-NEXT: ret <2 x i17> [[Y]]
;
%Y = mul <2 x i17> %X, <i17 1024, i17 256>
diff --git a/llvm/test/Transforms/InstCombine/apint-mul2.ll b/llvm/test/Transforms/InstCombine/apint-mul2.ll
index d961a645dac..16239ec3fcd 100644
--- a/llvm/test/Transforms/InstCombine/apint-mul2.ll
+++ b/llvm/test/Transforms/InstCombine/apint-mul2.ll
@@ -26,7 +26,7 @@ define <2 x i177> @test2(<2 x i177> %X) {
define <2 x i177> @test3(<2 x i177> %X) {
; CHECK-LABEL: @test3(
-; CHECK-NEXT: [[Y:%.*]] = mul <2 x i177> [[X:%.*]], <i177 1427247692705959881058285969449495136382746624, i177 45671926166590716193865151022383844364247891968>
+; CHECK-NEXT: [[Y:%.*]] = shl <2 x i177> [[X:%.*]], <i177 150, i177 155>
; CHECK-NEXT: ret <2 x i177> [[Y]]
;
%C = shl <2 x i177> <i177 1, i177 1>, <i177 150, i177 155>
OpenPOWER on IntegriCloud