[llvm] r181141 - LoopVectorize: We don't need an identity element for min/max reductions
Arnold Schwaighofer
aschwaighofer at apple.com
Sat May 4 18:54:43 PDT 2013
Author: arnolds
Date: Sat May 4 20:54:42 2013
New Revision: 181141
URL: http://llvm.org/viewvc/llvm-project?rev=181141&view=rev
Log:
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
Modified:
llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
llvm/trunk/test/Transforms/LoopVectorize/minmax_reduction.ll
Modified: llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp?rev=181141&r1=181140&r2=181141&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp (original)
+++ llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp Sat May 4 20:54:42 2013
@@ -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(Loo
/// 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::getReductionI
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(LoopV
// 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);
-
- // This vector is the Identity vector where the first element is the
- // incoming scalar reduction.
- Value *VectorStart = Builder.CreateInsertElement(Identity,
- RdxDesc.StartValue, Zero);
+ 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.
+ VectorStart = Builder.CreateInsertElement(Identity,
+ RdxDesc.StartValue, Zero);
+ }
// Fix the vector-loop phi.
// We created the induction variable so we know that the
Modified: llvm/trunk/test/Transforms/LoopVectorize/minmax_reduction.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopVectorize/minmax_reduction.ll?rev=181141&r1=181140&r2=181141&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopVectorize/minmax_reduction.ll (original)
+++ llvm/trunk/test/Transforms/LoopVectorize/minmax_reduction.ll Sat May 4 20:54:42 2013
@@ -6,8 +6,11 @@ target datalayout = "e-p:64:64:64-i1:8:8
; 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
More information about the llvm-commits
mailing list