This is an attempt to be slightly more consistent about what checks each function does, by deferring most of them to using canCoerceMustAliasedTypeToLoad. The expected benefit of this approach is demonstrated by the new optimizations exposed represented by the additional test examples.
This tries to handle zeroinitializer consistently, by preferring using
helper functions instead of re-implementing some of the same checks.
This lets us forward zeros successfully in a few more cases.
And since casting a zero should always be possible (without needing a
bitcast), make sure the canCoerce check reflects that, and that all
relevant users are handling that.