[LoopVectorize] Simplify scalar cost calculation in getInstructionCost
authorDavid Sherwood <david.sherwood@arm.com>
Wed, 10 Mar 2021 08:34:19 +0000 (08:34 +0000)
committerDavid Sherwood <david.sherwood@arm.com>
Tue, 27 Apr 2021 14:26:15 +0000 (15:26 +0100)
commit4afeda9157cffd2daa83f8075d73f1e11ea34c81
treef6456662403ecc86678905d1542fef7bb4d17b34
parentc20e4fbfa6d154616c2dd41e828a02facd000d71
[LoopVectorize] Simplify scalar cost calculation in getInstructionCost

This patch simplifies the calculation of certain costs in
getInstructionCost when isScalarAfterVectorization() returns a true value.
There are a few places where we multiply a cost by a number N, i.e.

  unsigned N = isScalarAfterVectorization(I, VF) ? VF.getKnownMinValue() : 1;
  return N * TTI.getArithmeticInstrCost(...

After some investigation it seems that there are only these cases that occur
in practice:

1. VF is a scalar, in which case N = 1.
2. VF is a vector. We can only get here if: a) the instruction is a
GEP/bitcast/PHI with scalar uses, or b) this is an update to an induction
variable that remains scalar.

I have changed the code so that N is assumed to always be 1. For GEPs
the cost is always 0, since this is calculated later on as part of the
load/store cost. PHI nodes are costed separately and were never previously
multiplied by VF. For all other cases I have added an assert that none of
the users needs scalarising, which didn't fire in any unit tests.

Only one test required fixing and I believe the original cost for the scalar
add instruction to have been wrong, since only one copy remains after
vectorisation.

I have also added a new test for the case when a pointer PHI feeds directly
into a store that will be scalarised as we were previously never testing it.

Differential Revision: https://reviews.llvm.org/D99718
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
llvm/test/Transforms/LoopVectorize/AArch64/no_vector_instructions.ll
llvm/test/Transforms/LoopVectorize/AArch64/predication_costs.ll