[llvm] r310181 - [InstCombine] refactor trunc(binop) transforms; NFCI

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 5 08:19:18 PDT 2017


Author: spatel
Date: Sat Aug  5 08:19:18 2017
New Revision: 310181

URL: http://llvm.org/viewvc/llvm-project?rev=310181&view=rev
Log:
[InstCombine] refactor trunc(binop) transforms; NFCI

In addition to moving the shift transforms over, we may want to
detect too-wide rotate patterns here (PR34046). 

Modified:
    llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
    llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=310181&r1=310180&r2=310181&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Sat Aug  5 08:19:18 2017
@@ -443,24 +443,49 @@ static Instruction *foldVecTruncToExtElt
   return ExtractElementInst::Create(VecInput, IC.Builder.getInt32(Elt));
 }
 
-/// Try to narrow the width of bitwise logic instructions with constants.
-Instruction *InstCombiner::shrinkBitwiseLogic(TruncInst &Trunc) {
+/// Try to narrow the width of math or bitwise logic instructions by pulling a
+/// truncate ahead of binary operators.
+/// TODO: Transforms for truncated shifts should be moved into here.
+Instruction *InstCombiner::narrowBinOp(TruncInst &Trunc) {
   Type *SrcTy = Trunc.getSrcTy();
   Type *DestTy = Trunc.getType();
   if (isa<IntegerType>(SrcTy) && !shouldChangeType(SrcTy, DestTy))
     return nullptr;
 
-  BinaryOperator *LogicOp;
-  Constant *C;
-  if (!match(Trunc.getOperand(0), m_OneUse(m_BinOp(LogicOp))) ||
-      !LogicOp->isBitwiseLogicOp() ||
-      !match(LogicOp->getOperand(1), m_Constant(C)))
+  BinaryOperator *BinOp;
+  if (!match(Trunc.getOperand(0), m_OneUse(m_BinOp(BinOp))))
     return nullptr;
 
-  // trunc (logic X, C) --> logic (trunc X, C')
-  Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy);
-  Value *NarrowOp0 = Builder.CreateTrunc(LogicOp->getOperand(0), DestTy);
-  return BinaryOperator::Create(LogicOp->getOpcode(), NarrowOp0, NarrowC);
+  switch (BinOp->getOpcode()) {
+  case Instruction::And:
+  case Instruction::Or:
+  case Instruction::Xor:
+  case Instruction::Add:
+  case Instruction::Mul: {
+    Constant *C;
+    if (match(BinOp->getOperand(1), m_Constant(C))) {
+      // trunc (binop X, C) --> binop (trunc X, C')
+      Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy);
+      Value *TruncX = Builder.CreateTrunc(BinOp->getOperand(0), DestTy);
+      return BinaryOperator::Create(BinOp->getOpcode(), TruncX, NarrowC);
+    }
+    break;
+  }
+  case Instruction::Sub: {
+    Constant *C;
+    if (match(BinOp->getOperand(0), m_Constant(C))) {
+      // trunc (binop C, X) --> binop (trunc C', X)
+      Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy);
+      Value *TruncX = Builder.CreateTrunc(BinOp->getOperand(1), DestTy);
+      return BinaryOperator::Create(BinOp->getOpcode(), NarrowC, TruncX);
+    }
+    break;
+  }
+
+  default: break;
+  }
+
+  return nullptr;
 }
 
 /// Try to narrow the width of a splat shuffle. This could be generalized to any
@@ -558,33 +583,6 @@ Instruction *InstCombiner::visitTrunc(Tr
     return new ICmpInst(ICmpInst::ICMP_NE, Src, Zero);
   }
 
-  if ((!isa<IntegerType>(SrcTy) || shouldChangeType(SrcTy, DestTy)) &&
-      Src->hasOneUse()) {
-    // Add/sub/mul can always be narrowed if we're killing the high bits.
-    // If one operand is a constant, then we're not generating more
-    // instructions to perform the narrower math op.
-    Value *X;
-    Constant *C;
-    if (match(Src, m_Add(m_Value(X), m_Constant(C)))) {
-      // trunc(add X, C) --> add(trunc X, C')
-      Value *TruncX = Builder.CreateTrunc(X, DestTy);
-      Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy);
-      return BinaryOperator::CreateAdd(TruncX, NarrowC);
-    }
-    if (match(Src, m_Mul(m_Value(X), m_Constant(C)))) {
-      // trunc(mul X, C) --> mul(trunc X, C')
-      Value *TruncX = Builder.CreateTrunc(X, DestTy);
-      Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy);
-      return BinaryOperator::CreateMul(TruncX, NarrowC);
-    }
-    if (match(Src, m_Sub(m_Constant(C), m_Value(X)))) {
-      // trunc(sub C, X) --> sub(C', trunc X)
-      Value *TruncX = Builder.CreateTrunc(X, DestTy);
-      Constant *NarrowC = ConstantExpr::getTrunc(C, DestTy);
-      return BinaryOperator::CreateSub(NarrowC, TruncX);
-    }
-  }
-
   // FIXME: Maybe combine the next two transforms to handle the no cast case
   // more efficiently. Support vector types. Cleanup code by using m_OneUse.
 
@@ -643,7 +641,7 @@ Instruction *InstCombiner::visitTrunc(Tr
     }
   }
 
-  if (Instruction *I = shrinkBitwiseLogic(CI))
+  if (Instruction *I = narrowBinOp(CI))
     return I;
 
   if (Instruction *I = shrinkSplatShuffle(CI, Builder))

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h?rev=310181&r1=310180&r2=310181&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h Sat Aug  5 08:19:18 2017
@@ -439,7 +439,7 @@ private:
   Instruction *scalarizePHI(ExtractElementInst &EI, PHINode *PN);
   Value *EvaluateInDifferentElementOrder(Value *V, ArrayRef<int> Mask);
   Instruction *foldCastedBitwiseLogic(BinaryOperator &I);
-  Instruction *shrinkBitwiseLogic(TruncInst &Trunc);
+  Instruction *narrowBinOp(TruncInst &Trunc);
   Instruction *optimizeBitCastFromPhi(CastInst &CI, PHINode *PN);
 
   /// Determine if a pair of casts can be replaced by a single cast.




More information about the llvm-commits mailing list