Restrict `vector.type_cast` to only cast to alignable multi-dim vectors

Thanks for surfacing, the op documentation is wrong and not in line with its usage, I will clean it up next week.

This op in isolation is however just a symptom of a larger problem that needs a deeper resolution.
There have been various discussions / posts about why memref is “not a pointer” with detailed explanations about the type of behavior you describe.

The issue you are seeing is not limited to vector.type_cast, it also applies to other things at the memref / value interface where we do not yet model the data layout in MLIR, here is an example.
Interestingly we had a recent conversation internally for the case of i1.

The TL;DR is that we are not taking into account the LLVM data layout yet and this is wrong.
The proper way to make progress here is to finally start making use of the DataLayout support in MLIR that @ftynse introduced a while back.

A solution that would register as good in my opinion would need to:

  1. be retargeable to various HW (e.g. some HW require 1KB alignment to do things implicitly (i.e. without explicit memref.reshape / vector.reshape / vector.shape_cast))
  2. work with sub-byte granularity (i4, i2, i1)
  3. be retargetable across backends: LLVM is but one backend we use, SPIR-V is another and there may be others.

The “power-of-2” constraint is a simple approximation for LLVM alignment, this may make sense in the short term to remove some effect of surprise once the op doc is fixed.