[SROA] For non-speculatable `load`s of `select`s -- split block, insert then/else...
authorRoman Lebedev <lebedev.ri@gmail.com>
Thu, 8 Dec 2022 13:50:19 +0000 (16:50 +0300)
committerRoman Lebedev <lebedev.ri@gmail.com>
Thu, 8 Dec 2022 13:51:32 +0000 (16:51 +0300)
commit03e6d9d9d1d48e43f3efc35eb75369b90d4510d5
treea8d7508781a371f654fee4fae32d28998aa4c75c
parent527e453a5bf9e1ab1504199c1b71539b34f25f50
[SROA] For non-speculatable `load`s of `select`s -- split block, insert then/else blocks, form two-entry PHI node

Currently, SROA is CFG-preserving.
Not doing so does not affect any pipeline test. (???)
Internally, SROA requires Dominator Tree, and uses it solely for the final `-mem2reg` call.

By design, we can't really SROA alloca if their address escapes somehow,
but we have logic to deal with `load` of `select`/`PHI`,
where at least one of the possible addresses prevents promotion,
by speculating the `load`s and `select`ing between loaded values.

As one would expect, that requires ensuring that the speculation is actually legal.
Even ignoring complexity bailouts, that logic does not deal with everything,
e.g. `isSafeToLoadUnconditionally()` does not recurse into hands of `select`.
There can also be cases where the load is genuinely non-speculate.

So if we can't prove that the load can be speculated,
unfold the select, produce two-entry phi node, and perform predicated load.

Now, that transformation must obviously update Dominator Tree,
since we require it later on. Doing so is trivial.
Additionally, we don't want to do this for the final SROA invocation (D136806).

In the end, this ends up having negative (!) compile-time cost:
https://llvm-compile-time-tracker.com/compare.php?from=c6d7e80ec4c17a415673b1cfd25924f98ac83608&to=ddf9600365093ea50d7e278696cbfa01641c959d&stat=instructions:u

Though indeed, this only deals with `select`s, `PHI`s are still using speculation.

Should we update some more analysis?

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D138238
54 files changed:
llvm/include/llvm/Transforms/Scalar.h
llvm/include/llvm/Transforms/Scalar/SROA.h
llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
llvm/lib/Passes/PassBuilder.cpp
llvm/lib/Passes/PassBuilderPipelines.cpp
llvm/lib/Passes/PassRegistry.def
llvm/lib/Transforms/Scalar/SROA.cpp
llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
llvm/test/Transforms/SROA/2009-02-20-InstCombine-SROA.ll
llvm/test/Transforms/SROA/address-spaces.ll
llvm/test/Transforms/SROA/addrspacecast.ll
llvm/test/Transforms/SROA/alignment.ll
llvm/test/Transforms/SROA/alloca-address-space.ll
llvm/test/Transforms/SROA/assume.ll
llvm/test/Transforms/SROA/basictest.ll
llvm/test/Transforms/SROA/big-endian.ll
llvm/test/Transforms/SROA/dbg-addr-diamond.ll
llvm/test/Transforms/SROA/dbg-inline.ll
llvm/test/Transforms/SROA/dbg-single-piece.ll
llvm/test/Transforms/SROA/dead-inst.ll
llvm/test/Transforms/SROA/fca.ll
llvm/test/Transforms/SROA/ignore-droppable.ll
llvm/test/Transforms/SROA/invariant-group.ll
llvm/test/Transforms/SROA/irregular-type.ll
llvm/test/Transforms/SROA/lifetime-intrinsic.ll
llvm/test/Transforms/SROA/mem-par-metadata-sroa-cast.ll
llvm/test/Transforms/SROA/mem-par-metadata-sroa.ll
llvm/test/Transforms/SROA/non-capturing-call-readonly.ll
llvm/test/Transforms/SROA/non-integral-pointers.ll
llvm/test/Transforms/SROA/phi-and-select.ll
llvm/test/Transforms/SROA/phi-catchswitch.ll
llvm/test/Transforms/SROA/phi-gep.ll
llvm/test/Transforms/SROA/phi-speculate-different-load-types.ll
llvm/test/Transforms/SROA/phi-with-duplicate-pred.ll
llvm/test/Transforms/SROA/pointer-offset-size.ll
llvm/test/Transforms/SROA/ppcf128-no-fold.ll
llvm/test/Transforms/SROA/pr26972.ll
llvm/test/Transforms/SROA/pr37267.ll
llvm/test/Transforms/SROA/preserve-nonnull.ll
llvm/test/Transforms/SROA/scalable-vectors.ll
llvm/test/Transforms/SROA/select-gep.ll
llvm/test/Transforms/SROA/select-load.ll
llvm/test/Transforms/SROA/slice-order-independence.ll
llvm/test/Transforms/SROA/slice-width.ll
llvm/test/Transforms/SROA/sroa-common-type-fail-promotion.ll
llvm/test/Transforms/SROA/std-clamp.ll
llvm/test/Transforms/SROA/tbaa-struct.ll
llvm/test/Transforms/SROA/tbaa-struct2.ll
llvm/test/Transforms/SROA/tbaa-subload.ll
llvm/test/Transforms/SROA/vector-conversion.ll
llvm/test/Transforms/SROA/vector-lifetime-intrinsic.ll
llvm/test/Transforms/SROA/vector-promotion-different-size.ll
llvm/test/Transforms/SROA/vector-promotion.ll
llvm/test/Transforms/SROA/vectors-of-pointers.ll