InstCombine pulls reverses up and out of operations, e.g.
`binop(reverse(x), reverse(y)) -> reverse(binop(x,y))`. This reduces the
overall number of reverses, and also allows the `reverse(reverse(x))`
combine to kick in much more.
This implements the same canonicalization in VPlan which allows for more
vectorization due to cost model improvements, and generally handles more
cases when there's predication involved.
If we have a reversed load and reversed store whose stores are now
eliminated, we will be left with just two reversed masks on the load and
store. But with EVL tail folding this will leave behind a
`splice.right(ops(splice.left(...)))` pair on the value from memory.
InstCombine can fold away a pair of `vp.reverse(ops(vp.reverse(...)))`,
but it can't fold a pair of splices. So to prevent regressions we also
have to pull splice.lefts like `ops(splice.left(poison, x, evl)) ->
splice.left(poison, ops(x), evl)`. The `splice.right(splice.left(x)) ->
x` VPlan transform will then kick in and remove it. We don't need to
pull splice.rights since they are only emitted at stores.