[SimpleLoopUnswitch] Fix exponential unswitch
authorNikita Popov <npopov@redhat.com>
Wed, 20 Sep 2023 09:41:42 +0000 (11:41 +0200)
committerTobias Hieta <tobias@hieta.se>
Wed, 27 Sep 2023 15:53:17 +0000 (17:53 +0200)
commit2839aa915066531621ade9c976f0594b797c1b5c
tree1f023d9bc25e7f0dc8c9a5d000fbf6684606900d
parent773f136d6faa5b5120107cd5b79b16ee3a307d3a
[SimpleLoopUnswitch] Fix exponential unswitch

When unswitching via invariant condition injection, we currently
mark the condition in the old loop, so that it does not get
unswitched again. However, if there are multiple branches for
which conditions can be injected, then we can do that for both
the old and new loop. This means that the number of unswitches
increases exponentially.

Change the handling to be more similar to partial unswitching,
where we instead mark the whole loop, rather than a single
condition. This means that we will only generate a linear number
of loops.

TBH I think even that is still highly undesirable, and we should
probably be unswitching all candidates at the same time, so that
we end up with only two loops. But at least this mitigates the
worst case.

The test case is a reduced variant that generates 1700 lines of IR
without this patch and 290 with it.

Fixes https://github.com/llvm/llvm-project/issues/66868.

(cherry picked from commit 8362cae71b80bc43c8c680cdfb13c495705a622f)
llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp
llvm/test/Transforms/SimpleLoopUnswitch/inject-invariant-conditions-exponential.ll [new file with mode: 0644]
llvm/test/Transforms/SimpleLoopUnswitch/inject-invariant-conditions.ll