Potentially incorrect calculation of widest type in loop vectorizer

When choosing a vectorization factor, we upper bound its maximum value by

llvm::bit_floor(Legal->getMaxSafeVectorWidthInBits() / WidestType);

Thus we shouldn’t underestimate WidestType because otherwise we might end up choosing an over-optimistic VF that leads to the splitting of illegally typed vectors during lowering.

However, this seems to be the case in the following minimal example, where the widest type is inferred to be 8 bits:

void foo(char *a)
{
  for (int i = 0; i < 100; i++)
    a[i] = i < 50;
}

The loop body before vectorization contains the following phi corresponding to the loop index

%indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ %indvars.iv.ph, %for.body.preheader16 ]

The VPlan will include a corresponding WidenInduction recipe that will end up generating

%vec.ind = phi <32 x i64> [ <i64 0, i64 1, ...>, %vector.ph ], [ %vec.ind.next, %vector.ph ]

While this recipe is normally optimized away (by removeDeadRecipes()), the use of the index in the comparison prevents this from happening. So the widest element type being generated actually ends being 64 bits.

The reason that we compute the widest type to be 8 bits is that we only consider loads, stores, and reduction phi nodes in LoopVectorizationCostModel::collectElementTypesForWidening(), and the phi node in question does not fall into any of these categories. But should we not take into account that the loop may contain vector operations involving only induction variables and constants, as is the case in this example?