[llvm] r288273 - [InstCombine] allow more narrowing transforms for logic ops

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 30 12:48:54 PST 2016


Author: spatel
Date: Wed Nov 30 14:48:54 2016
New Revision: 288273

URL: http://llvm.org/viewvc/llvm-project?rev=288273&view=rev
Log:
[InstCombine] allow more narrowing transforms for logic ops

We had a limited version of this for scalar 'and'; this expands
the transform to 'or' and 'xor' and allows vectors types too.

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

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=288273&r1=288272&r2=288273&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Wed Nov 30 14:48:54 2016
@@ -443,6 +443,26 @@ 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) {
+  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)))
+    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);
+}
+
 Instruction *InstCombiner::visitTrunc(TruncInst &CI) {
   if (Instruction *Result = commonCastTransforms(CI))
     return Result;
@@ -531,17 +551,11 @@ Instruction *InstCombiner::visitTrunc(Tr
     }
   }
 
+  if (Instruction *I = shrinkBitwiseLogic(CI))
+    return I;
+
   if (Src->hasOneUse() && isa<IntegerType>(SrcTy) &&
       ShouldChangeType(SrcTy, DestTy)) {
-
-    // Transform "trunc (and X, cst)" -> "and (trunc X), cst" so long as the
-    // dest type is native.
-    if (match(Src, m_And(m_Value(A), m_ConstantInt(Cst)))) {
-      Value *NewTrunc = Builder->CreateTrunc(A, DestTy, A->getName() + ".tr");
-      return BinaryOperator::CreateAnd(NewTrunc,
-                                       ConstantExpr::getTrunc(Cst, DestTy));
-    }
-
     // Transform "trunc (shl X, cst)" -> "shl (trunc X), cst" so long as the
     // dest type is native and cst < dest size.
     if (match(Src, m_Shl(m_Value(A), m_ConstantInt(Cst))) &&

Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h?rev=288273&r1=288272&r2=288273&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineInternal.h Wed Nov 30 14:48:54 2016
@@ -380,6 +380,7 @@ private:
   Instruction *scalarizePHI(ExtractElementInst &EI, PHINode *PN);
   Value *EvaluateInDifferentElementOrder(Value *V, ArrayRef<int> Mask);
   Instruction *foldCastedBitwiseLogic(BinaryOperator &I);
+  Instruction *shrinkBitwiseLogic(TruncInst &Trunc);
   Instruction *optimizeBitCastFromPhi(CastInst &CI, PHINode *PN);
 
   /// Determine if a pair of casts can be replaced by a single cast.

Modified: llvm/trunk/test/Transforms/InstCombine/narrow.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/narrow.ll?rev=288273&r1=288272&r2=288273&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/narrow.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/narrow.ll Wed Nov 30 14:48:54 2016
@@ -19,12 +19,12 @@ define i1 @test1(i32 %A, i32 %B) {
   ret i1 %ELIM3
 }
 
-; TODO: The next 6 (3 logic ops * (scalar+vector)) tests show potential cases for narrowing a bitwise logic op.
+; The next 6 (3 logic ops * (scalar+vector)) tests show potential cases for narrowing a bitwise logic op.
 
 define i32 @shrink_xor(i64 %a) {
 ; CHECK-LABEL: @shrink_xor(
-; CHECK-NEXT:    [[XOR:%.*]] = xor i64 %a, 1
-; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[XOR]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i64 %a to i32
+; CHECK-NEXT:    [[TRUNC:%.*]] = xor i32 [[TMP1]], 1
 ; CHECK-NEXT:    ret i32 [[TRUNC]]
 ;
   %xor = xor i64 %a, 1
@@ -36,8 +36,8 @@ define i32 @shrink_xor(i64 %a) {
 
 define <2 x i32> @shrink_xor_vec(<2 x i64> %a) {
 ; CHECK-LABEL: @shrink_xor_vec(
-; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i64> %a, <i64 2, i64 2>
-; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <2 x i64> [[XOR]] to <2 x i32>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i64> %a to <2 x i32>
+; CHECK-NEXT:    [[TRUNC:%.*]] = xor <2 x i32> [[TMP1]], <i32 2, i32 2>
 ; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]
 ;
   %xor = xor <2 x i64> %a, <i64 2, i64 2>
@@ -49,8 +49,8 @@ define <2 x i32> @shrink_xor_vec(<2 x i6
 
 define i3 @shrink_or(i6 %a) {
 ; CHECK-LABEL: @shrink_or(
-; CHECK-NEXT:    [[OR:%.*]] = or i6 %a, 1
-; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i6 [[OR]] to i3
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc i6 %a to i3
+; CHECK-NEXT:    [[TRUNC:%.*]] = or i3 [[TMP1]], 1
 ; CHECK-NEXT:    ret i3 [[TRUNC]]
 ;
   %or = or i6 %a, 33
@@ -62,8 +62,8 @@ define i3 @shrink_or(i6 %a) {
 
 define <2 x i8> @shrink_or_vec(<2 x i16> %a) {
 ; CHECK-LABEL: @shrink_or_vec(
-; CHECK-NEXT:    [[OR:%.*]] = or <2 x i16> %a, <i16 -1, i16 256>
-; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <2 x i16> [[OR]] to <2 x i8>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i16> %a to <2 x i8>
+; CHECK-NEXT:    [[TRUNC:%.*]] = or <2 x i8> [[TMP1]], <i8 -1, i8 0>
 ; CHECK-NEXT:    ret <2 x i8> [[TRUNC]]
 ;
   %or = or <2 x i16> %a, <i16 -1, i16 256>
@@ -71,7 +71,7 @@ define <2 x i8> @shrink_or_vec(<2 x i16>
   ret <2 x i8> %trunc
 }
 
-; We discriminate against weird types?
+; We discriminate against weird types.
 
 define i31 @shrink_and(i64 %a) {
 ; CHECK-LABEL: @shrink_and(
@@ -88,8 +88,8 @@ define i31 @shrink_and(i64 %a) {
 
 define <2 x i32> @shrink_and_vec(<2 x i33> %a) {
 ; CHECK-LABEL: @shrink_and_vec(
-; CHECK-NEXT:    [[AND:%.*]] = and <2 x i33> %a, <i33 -4294967296, i33 6>
-; CHECK-NEXT:    [[TRUNC:%.*]] = trunc <2 x i33> [[AND]] to <2 x i32>
+; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i33> %a to <2 x i32>
+; CHECK-NEXT:    [[TRUNC:%.*]] = and <2 x i32> [[TMP1]], <i32 0, i32 6>
 ; CHECK-NEXT:    ret <2 x i32> [[TRUNC]]
 ;
   %and = and <2 x i33> %a, <i33 4294967296, i33 6>




More information about the llvm-commits mailing list