This patch adds the 'vector.load' and 'vector.store' ops to the Vector

dialect [1]. These operations model *contiguous* vector loads and stores

from/to memory. Their semantics are similar to the 'affine.vector_load' and

'affine.vector_store' counterparts but without the affine constraints. The

most relevant feature is that these new vector operations may perform a vector

load/store on memrefs with a non-vector element type, unlike 'std.load' and

'std.store' ops. This opens the representation to model more generic vector

load/store scenarios: unaligned vector loads/stores, perform scalar and vector

memory access on the same memref, decouple memory allocation constraints from

memory accesses, etc [1]. These operations will also facilitate the progressive

lowering of both Affine vector loads/stores and Vector transfer reads/writes

for those that read/write contiguous slices from/to memory.

In particular, this patch adds the 'vector.load' and 'vector.store' ops to the

Vector dialect, implements their lowering to the LLVM dialect, and changes the

lowering of 'affine.vector_load' and 'affine.vector_store' ops to the new vector

ops. The lowering of Vector transfer reads/writes will be implemented in the

future, probably as an independent pass. The API of 'vector.maskedload' and

'vector.maskedstore' has also been changed slightly to align it with the

transfer read/write ops and the vector new ops. This will improve reusability

among all these operations. For example, the lowering of 'vector.load',

'vector.store', 'vector.maskedload' and 'vector.maskedstore' to the LLVM dialect

is implemented with a single template conversion pattern.

[1] https://llvm.discourse.group/t/memref-type-and-data-layout/