[SimpleLoopUnswitch] Drop make.implicit metadata in case of non-trivial unswitching
authorMax Kazantsev <mkazantsev@azul.com>
Fri, 31 Jul 2020 04:10:00 +0000 (11:10 +0700)
committerMax Kazantsev <mkazantsev@azul.com>
Fri, 31 Jul 2020 04:33:02 +0000 (11:33 +0700)
commitd889e17eca8e8c43c6e4a2439fae5a1a40823623
tree518a053d564dc143dd2136a2c255bf534b65adb5
parent836991d3676fda06d0f07c816ba855c8a0c3e0aa
[SimpleLoopUnswitch] Drop make.implicit metadata in case of non-trivial unswitching

Non-trivial unswitching simply moves terminator being unswitch from the loop
up to the switch block. It also preserves all metadata that was there. It might not
be a correct thing to do for `make.implicit` metadata. Consider case:
```
for (...) {
  cond = // computed in loop
  if (cond) return X;
  if (p == null) throw_npe(); !make implicit
}
```
Before the unswitching, if `p` is null and we reach this check, we are guaranteed
to go to `throw_npe()` block. Now we unswitch on `p == null` condition:
```
if (p == null) !make implicit {
  for (...) {
    if (cond) return X;
    throw_npe()
  }
} else {
  for (...) {
    if (cond) return X;
  }
}
```
Now, following `true` branch of `p == null` does not always lead us to
`throw_npe()` because the loop has side exit. Now, if we run ImplicitNullCheck
pass on this code, it may end up making the unswitch condition implicit. This may
lead us to turning normal path to `return X` into signal-throwing path, which is
not efficient.

Note that this does not happen during trivial unswitch: it guarantees that we do not
have side exits before condition being unswitched.

This patch fixes this situation by unconditional dropping of `make.implicit` metadata
when we perform non-trivial unswitch. We could preserve it if we could prove that the
condition always executes. This can be done as a follow-up.

Differential Revision: https://reviews.llvm.org/D84916
Reviewed By: asbirlea
llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
llvm/test/Transforms/SimpleLoopUnswitch/implicit-null-checks.ll [new file with mode: 0644]