From c1738fdadd1c969f13bbf09fe9c36fff56ccd709 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Sun, 5 May 2013 01:54:42 +0000 Subject: [PATCH] LoopVectorize: We don't need an identity element for min/max reductions We can just use the initial element that feeds the reduction. max(max(x, y), z) == max(max(x,y), max(x,z)) radar://13723044 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181141 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Vectorize/LoopVectorize.cpp | 49 +++++++------------ .../LoopVectorize/minmax_reduction.ll | 5 +- 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/lib/Transforms/Vectorize/LoopVectorize.cpp b/lib/Transforms/Vectorize/LoopVectorize.cpp index 2250712a8e0..1c7397bfa66 100644 --- a/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -498,8 +498,7 @@ public: /// This function returns the identity element (or neutral element) for /// the operation K. - static Constant *getReductionIdentity(ReductionKind K, Type *Tp, - MinMaxReductionKind MinMaxK); + static Constant *getReductionIdentity(ReductionKind K, Type *Tp); private: /// Check if a single basic block loop is vectorizable. /// At this point we know that this is a loop with a constant trip count @@ -1501,8 +1500,7 @@ InnerLoopVectorizer::createEmptyLoop(LoopVectorizationLegality *Legal) { /// This function returns the identity element (or neutral element) for /// the operation K. Constant* -LoopVectorizationLegality::getReductionIdentity(ReductionKind K, Type *Tp, - MinMaxReductionKind MinMaxK) { +LoopVectorizationLegality::getReductionIdentity(ReductionKind K, Type *Tp) { switch (K) { case RK_IntegerXor: case RK_IntegerAdd: @@ -1521,24 +1519,6 @@ LoopVectorizationLegality::getReductionIdentity(ReductionKind K, Type *Tp, case RK_FloatAdd: // Adding zero to a number does not change it. return ConstantFP::get(Tp, 0.0L); - case RK_IntegerMinMax: - switch(MinMaxK) { - default: llvm_unreachable("Unknown min/max predicate"); - case MRK_UIntMin: - return ConstantInt::getAllOnesValue(Tp); - case MRK_UIntMax: - return ConstantInt::get(Tp, 0); - case MRK_SIntMin: { - unsigned BitWidth = Tp->getPrimitiveSizeInBits(); - return ConstantInt::get(Tp->getContext(), - APInt::getSignedMaxValue(BitWidth)); - } - case LoopVectorizationLegality::MRK_SIntMax: { - unsigned BitWidth = Tp->getPrimitiveSizeInBits(); - return ConstantInt::get(Tp->getContext(), - APInt::getSignedMinValue(BitWidth)); - } - } default: llvm_unreachable("Unknown reduction kind"); } @@ -1761,16 +1741,23 @@ InnerLoopVectorizer::vectorizeLoop(LoopVectorizationLegality *Legal) { // Find the reduction identity variable. Zero for addition, or, xor, // one for multiplication, -1 for And. - Constant *Iden = - LoopVectorizationLegality::getReductionIdentity(RdxDesc.Kind, - VecTy->getScalarType(), - RdxDesc.MinMaxKind); - Constant *Identity = ConstantVector::getSplat(VF, Iden); + Value *Identity; + Value *VectorStart; + if (RdxDesc.Kind == LoopVectorizationLegality::RK_IntegerMinMax) + // MinMax reduction have the start value as their identify. + VectorStart = Identity = Builder.CreateVectorSplat(VF, RdxDesc.StartValue, + "minmax.ident"); + else { + Constant *Iden = + LoopVectorizationLegality::getReductionIdentity(RdxDesc.Kind, + VecTy->getScalarType()); + Identity = ConstantVector::getSplat(VF, Iden); - // This vector is the Identity vector where the first element is the - // incoming scalar reduction. - Value *VectorStart = Builder.CreateInsertElement(Identity, - RdxDesc.StartValue, Zero); + // This vector is the Identity vector where the first element is the + // incoming scalar reduction. + VectorStart = Builder.CreateInsertElement(Identity, + RdxDesc.StartValue, Zero); + } // Fix the vector-loop phi. // We created the induction variable so we know that the diff --git a/test/Transforms/LoopVectorize/minmax_reduction.ll b/test/Transforms/LoopVectorize/minmax_reduction.ll index 99dd09386f5..36a8758e2cc 100644 --- a/test/Transforms/LoopVectorize/minmax_reduction.ll +++ b/test/Transforms/LoopVectorize/minmax_reduction.ll @@ -6,8 +6,11 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3 ; Signed tests. -; Turn this into a max reduction. +; Turn this into a max reduction. Make sure we use a splat to initialize the +; vector for the reduction. ; CHECK: @max_red +; CHECK: %[[VAR:.*]] = insertelement <2 x i32> undef, i32 %max, i32 0 +; CHECK: {{.*}} = shufflevector <2 x i32> %[[VAR]], <2 x i32> undef, <2 x i32> zeroinitializer ; CHECK: icmp sgt <2 x i32> ; CHECK: select <2 x i1> ; CHECK: middle.block