InstCombine performs simple forwarding from stores to loads, but currently only handles the case where the load and store have the same size. This extends it to also handle a store of a constant with a larger size followed by a load with a smaller size.
This is implemented through ConstantFoldLoadThroughBitcast() which is fairly primitive (e.g. does not allow storing a large integer and then loading a small one), but at least can forward the first element of a vector store. Unfortunately it seems that we currently don't have a generic helper for "read a constant value as a different type", it's all tangled up with other logic in either ConstantFolding or VNCoercion.
Of course, GVN is the pass that implements this in full generality, but store to load forwarding in InstCombine is fairly important to sidestep phase ordering issues.
Maybe we should have some test cases with types when DataLayout::typeSizeEqualsStoreSize returns false. I actually think the result would be wrong here if for example using i4 (or i13) instead of i32, because we don't really know which bits that are loaded.
So there might be a bug in ConstantFoldLoadThroughBitcast, that it does not bail out if typeSizeEqualsStoreSize is false for the DestTy, that would be exposed by adding such test cases here.
(Maybe even typeAllocSize is of importance and not only typeStoreSize, or can we ignore alignment for the scalar data type?)