mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-14 14:24:05 +00:00
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
This commit is contained in:
@ -498,8 +498,7 @@ public:
|
|||||||
|
|
||||||
/// This function returns the identity element (or neutral element) for
|
/// This function returns the identity element (or neutral element) for
|
||||||
/// the operation K.
|
/// the operation K.
|
||||||
static Constant *getReductionIdentity(ReductionKind K, Type *Tp,
|
static Constant *getReductionIdentity(ReductionKind K, Type *Tp);
|
||||||
MinMaxReductionKind MinMaxK);
|
|
||||||
private:
|
private:
|
||||||
/// Check if a single basic block loop is vectorizable.
|
/// Check if a single basic block loop is vectorizable.
|
||||||
/// At this point we know that this is a loop with a constant trip count
|
/// 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
|
/// This function returns the identity element (or neutral element) for
|
||||||
/// the operation K.
|
/// the operation K.
|
||||||
Constant*
|
Constant*
|
||||||
LoopVectorizationLegality::getReductionIdentity(ReductionKind K, Type *Tp,
|
LoopVectorizationLegality::getReductionIdentity(ReductionKind K, Type *Tp) {
|
||||||
MinMaxReductionKind MinMaxK) {
|
|
||||||
switch (K) {
|
switch (K) {
|
||||||
case RK_IntegerXor:
|
case RK_IntegerXor:
|
||||||
case RK_IntegerAdd:
|
case RK_IntegerAdd:
|
||||||
@ -1521,24 +1519,6 @@ LoopVectorizationLegality::getReductionIdentity(ReductionKind K, Type *Tp,
|
|||||||
case RK_FloatAdd:
|
case RK_FloatAdd:
|
||||||
// Adding zero to a number does not change it.
|
// Adding zero to a number does not change it.
|
||||||
return ConstantFP::get(Tp, 0.0L);
|
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:
|
default:
|
||||||
llvm_unreachable("Unknown reduction kind");
|
llvm_unreachable("Unknown reduction kind");
|
||||||
}
|
}
|
||||||
@ -1761,16 +1741,23 @@ InnerLoopVectorizer::vectorizeLoop(LoopVectorizationLegality *Legal) {
|
|||||||
|
|
||||||
// Find the reduction identity variable. Zero for addition, or, xor,
|
// Find the reduction identity variable. Zero for addition, or, xor,
|
||||||
// one for multiplication, -1 for And.
|
// one for multiplication, -1 for And.
|
||||||
|
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 =
|
Constant *Iden =
|
||||||
LoopVectorizationLegality::getReductionIdentity(RdxDesc.Kind,
|
LoopVectorizationLegality::getReductionIdentity(RdxDesc.Kind,
|
||||||
VecTy->getScalarType(),
|
VecTy->getScalarType());
|
||||||
RdxDesc.MinMaxKind);
|
Identity = ConstantVector::getSplat(VF, Iden);
|
||||||
Constant *Identity = ConstantVector::getSplat(VF, Iden);
|
|
||||||
|
|
||||||
// This vector is the Identity vector where the first element is the
|
// This vector is the Identity vector where the first element is the
|
||||||
// incoming scalar reduction.
|
// incoming scalar reduction.
|
||||||
Value *VectorStart = Builder.CreateInsertElement(Identity,
|
VectorStart = Builder.CreateInsertElement(Identity,
|
||||||
RdxDesc.StartValue, Zero);
|
RdxDesc.StartValue, Zero);
|
||||||
|
}
|
||||||
|
|
||||||
// Fix the vector-loop phi.
|
// Fix the vector-loop phi.
|
||||||
// We created the induction variable so we know that the
|
// We created the induction variable so we know that the
|
||||||
|
@ -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.
|
; 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: @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: icmp sgt <2 x i32>
|
||||||
; CHECK: select <2 x i1>
|
; CHECK: select <2 x i1>
|
||||||
; CHECK: middle.block
|
; CHECK: middle.block
|
||||||
|
Reference in New Issue
Block a user