[llvm] r324603 - [InstCombine] Improve mul(x, pow2) -> shl combine for vector constants

Simon Pilgrim via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 8 06:10:01 PST 2018


Author: rksimon
Date: Thu Feb  8 06:10:01 2018
New Revision: 324603

URL: http://llvm.org/viewvc/llvm-project?rev=324603&view=rev
Log:
[InstCombine] Improve mul(x, pow2) -> shl combine for vector constants

Refactor getLogBase2Vector into getLogBase2 to accept all scalars/vectors. Generalize from ConstantDataVector to support all constant vectors.

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
    llvm/trunk/test/Transforms/InstCombine/apint-mul1.ll
    llvm/trunk/test/Transforms/InstCombine/apint-mul2.ll

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=324603&r1=324602&r2=324603&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Thu Feb  8 06:10:01 2018
@@ -132,18 +132,30 @@ static bool IsMultiple(const APInt &C1,
 
 /// \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(Bina
     }
 
     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);
 

Modified: llvm/trunk/test/Transforms/InstCombine/apint-mul1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/apint-mul1.ll?rev=324603&r1=324602&r2=324603&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/apint-mul1.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/apint-mul1.ll Thu Feb  8 06:10:01 2018
@@ -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>

Modified: llvm/trunk/test/Transforms/InstCombine/apint-mul2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/apint-mul2.ll?rev=324603&r1=324602&r2=324603&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/apint-mul2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/apint-mul2.ll Thu Feb  8 06:10:01 2018
@@ -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>




More information about the llvm-commits mailing list