aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/Transforms/SimpleLoopUnswitch
AgeCommit message (Collapse)AuthorFilesLines
2026-01-04[IR] Reland Optimize PHINode::removeIncomingValue() and ↵Mingjie Xu3-14/+14
PHINode::removeIncomingValueIf() to use the swapping strategy. (#174274) Reland #171963, #172639 and #173444, they are reverted in 86b9f90b9574b3a7d15d28a91f6316459dcfa046 because of introducing non-determinism in compiles. The non-determinism has been fixed in 9b8addffa70cee5b2acc5454712d9cf78ce45710.
2025-12-29Revert 159f1c048e08a8780d92858cfc80e723c90235e3 (#173893)Walter Lee3-14/+14
This causes non-determinism in compiles. From nikic: "FYI the non-determinism is also visible on llvm-opt-benchmark. Maybe repeatedly running test cases from https://github.com/dtcxzyw/llvm-opt-benchmark/commit/299446d99f04024d5f569ce1f7e9338c9bcf55fe could reproduce the issue..." Also revert dependent 796fafeff92fe5d2d20594859e92607116e30a16 and e135447bda617125688b71d33480d131d1076a72.
2025-12-17[IR] Optimize PHINode::removeIncomingValue() by swapping removed incoming ↵Mingjie Xu3-14/+14
value with the last incoming value. (#171963) Current implementation uses `std::copy` to shift all incoming values after the removed index. This patch optimizes `PHINode::removeIncomingValue()` by replacing the linear shift of incoming values with a swap-with-last strategy. After this change, the relative order of incoming values after removal is not preserved. This improves compile-time for PHI nodes with many predecessors. Depends: https://github.com/llvm/llvm-project/pull/171955 https://github.com/llvm/llvm-project/pull/171956 https://github.com/llvm/llvm-project/pull/171960 https://github.com/llvm/llvm-project/pull/171962
2025-11-04[SLU][profcheck] Propagate profile for branches on injected conditions. ↵Mircea Trofin1-70/+72
(#164476) This patch addresses the profile of 2 branches: - one that compares the 2 limits, for which we have no information (the C1, C2, see https://reviews.llvm.org/D136233) - one that is conditioned on a condition for which we have a profile, so we reuse it Issue #147390
2025-11-04[SLU][profcheck] create likely branch weights for guard->branch (#164271)Mircea Trofin1-10/+16
The `llvm.experimental.guard` intrinsic is a `call`, so its metadata - if present - would be one value (as per `Verifier::visitProfMetadata`). That wouldn't be a correct `branch_weights` metadata. Likely, `GI->getMetadata(LLVMContext::MD_prof)` was always `nullptr`. We can bias away from deopt instead. Issue #147390
2025-11-04[NFC][SLU] Update SimpleLoopUnswitch/guards.ll (#166285)Mircea Trofin1-111/+190
When running UTC on SLU/guards.ll (without LLVM changes), there are a number of changes in the UTC-generated checks. Submitting those first to simplify the diff of PR #164271, as most of the changes in the latter were actually these.
2025-11-03[SLU][profcheck] Use the original branch weigths in ↵Mircea Trofin1-32/+43
`buildPartialInvariantUnswitchConditionalBranch` (#164270) A new branch is created on the same condition as a branch for which we have a profile. We can reuse that profile in this case. Issue #147390
2025-10-30[SLU][profcheck] Estimate branch weights in partial unswitch cases (#164035)Mircea Trofin3-3/+254
In the case of a partial unswitch, we take the invariant part of an expression consisting of either conjunctions or disjunctions, and hoist it out of the loop, conditioning a branch on it (==the invariant part). We can't correctly calculate the branch probability of this new branch, but can use the probability of the existing branch as a bound. That would preserve block frequencies better than allowing for the default, static (50-50) probability for that branch. Issue #147390
2025-10-17[SimpleLoopUnswitch] Don't use BlockFrequencyInfo to skip cold loops (#159522)Luke Lau2-125/+0
In https://reviews.llvm.org/D129599, non-trivial switching was disabled for cold loops in the interest of code size. This added a dependency on BlockFrequencyInfo with PGO, but in loop passes this is only available on a lossy basis: see https://reviews.llvm.org/D86156 LICM moved away from BFI so as of today SimpleLoopUnswitch is the only remaining loop pass that uses BFI, for the sole reason to prevent code size increases in PGO builds. It doesn't use BFI if there's no profile summary available. After some investigation on llvm-test-suite it turns out that the lossy BFI causes very significant deviations in block frequency, since when new loops are deleted/created during the loop pass manager it can return frequencies for different loops altogether. This results in unswitchable loops being mistakenly skipped because they are thought to be cold. This patch removes the use of BFI from SimpleLoopUnswitch and thus the last remaining use of BFI in a loop pass. To recover the original intent of not unswitching cold code, PGOForceFunctionAttrs can be used to annotate functions which can be optimized for code size, since SimpleLoopUnswitch will respect OptSize: https://reviews.llvm.org/D94559 This isn't 100% the same behaviour since the previous behaviour checked for coldness at the loop level and this is now at the function level. We could expand PGOForceFunctionAttrs to be more granular at the loop level, https://github.com/llvm/llvm-project/issues/159595 tracks this idea.
2025-10-16[SimpleLoopUnswitch] Regenerate UTC test. NFCLuke Lau1-1/+1
To remove a confusing diff in https://github.com/llvm/llvm-project/pull/159522
2025-09-05[SimpleLoopUnswitch] Adjust cost multiplier accounting for parent loop sizeAntonio Frighetto1-0/+54
When estimating the cost to avoid exponential unswitches of non-trivial invariant conditions, also consider the parent loop basic blocks size, ensuring this does not grow unexpectedly. Fixes: https://github.com/llvm/llvm-project/issues/138509.
2025-08-18Revert "[SimpleLoopUnswitch] Record loops from unswitching non-trivial ↵Antonio Frighetto14-381/+502
conditions" This reverts commit e9de32fd159d30cfd6fcc861b57b7e99ec2742ab due to multiple performance regressions observed across downstream Numba benchmarks (https://github.com/llvm/llvm-project/issues/138509#issuecomment-3193855772). While avoiding non-trivial unswitches on newly-cloned loops helps mitigate the pathological case reported in https://github.com/llvm/llvm-project/issues/138509, it may as well make the IR less friendly to vectorization / loop- canonicalization (in the test reported, previously no select with loop-carried dependence existed in the new specialized loops), leading the abovementioned approach to be reconsidered.
2025-07-24[SimpleLoopUnswitch] Record loops from unswitching non-trivial conditionsAntonio Frighetto14-502/+381
Track newly-cloned loops coming from unswitching non-trivial invariant conditions, so as to prevent conditions in such cloned blocks from being unswitched again. Fixes: https://github.com/llvm/llvm-project/issues/138509.
2025-03-14[RemoveDIs] Remove "try-debuginfo-iterators..." test flags (#130298)Jeremy Morse1-1/+0
These date back to when the non-intrinsic format of variable locations was still being tested and was behind a compile-time flag, so not all builds / bots would correctly run them. The solution at the time, to get at least some test coverage, was to have tests opt-in to non-intrinsic debug-info if it was built into LLVM. Nowadays, non-intrinsic format is the default and has been on for more than a year, there's no need for this flag to exist. (I've downgraded the flag from "try" to explicitly requesting non-intrinsic format in some places, so that we can deal with tests that are explicitly about non-intrinsic format in their own commit).
2025-01-29[IR] Convert from nocapture to captures(none) (#123181)Nikita Popov1-1/+1
This PR removes the old `nocapture` attribute, replacing it with the new `captures` attribute introduced in #116990. This change is intended to be essentially NFC, replacing existing uses of `nocapture` with `captures(none)` without adding any new analysis capabilities. Making use of non-`none` values is left for a followup. Some notes: * `nocapture` will be upgraded to `captures(none)` by the bitcode reader. * `nocapture` will also be upgraded by the textual IR reader. This is to make it easier to use old IR files and somewhat reduce the test churn in this PR. * Helper APIs like `doesNotCapture()` will check for `captures(none)`. * MLIR import will convert `captures(none)` into an `llvm.nocapture` attribute. The representation in the LLVM IR dialect should be updated separately.
2024-12-05[InstCombine] Infer nusw + nneg -> nuw for getelementptr (#111144)Nikita Popov1-1/+1
If the gep is nusw (usually via inbounds) and the offset is non-negative, we can infer nuw. Proof: https://alive2.llvm.org/ce/z/ihztLy
2024-12-03[llvm] Remove `br i1 undef` from some regression tests [NFC] (#118419)Lee Wei8-35/+61
This PR removes tests with `br i1 undef` under `llvm/tests/Transforms/ObjCARC, Reassociate, SCCP, SLPVectorizer...`. After this PR, I'll continue to fix tests under `llvm/tests/CodeGen`, which has more UB tests than `llvm/tests/Transforms`.
2024-11-27[SimpleLoopUnswitch] Use loop-mssa in more tests (NFC)Nikita Popov25-30/+26
We had a lot of -verify-memoryssa tests that did not actually use MemorySSA, because they were not using the loop-mssa adaptor.
2024-11-27[SimpleLoopUnswitch] Fix LCSSA phi node invalidationNikita Popov1-0/+92
Fixes https://github.com/llvm/llvm-project/issues/117537.
2024-11-18[InstCombine] Re-queue users of phi when nsw/nuw flags of add are inferred ↵Yingwei Zheng1-17/+6
(#113933) This patch re-queue users of phi when one of its incoming add instructions is updated. If an add instruction is updated, the analysis results of phis may be improved. Thus we may further fold some users of this phi node. See the following case: ``` define i8 @trunc_in_loop_exit_block() { ; CHECK-LABEL: @trunc_in_loop_exit_block( ; CHECK-NEXT: entry: ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: ; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] ; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[ENTRY]] ], [ [[IV_NEXT]], [[LOOP_LATCH]] ] ; CHECK-NEXT: [[CMP:%.*]] = icmp samesign ult i32 [[IV]], 100 ; CHECK-NEXT: br i1 [[CMP]], label [[LOOP_LATCH]], label [[EXIT:%.*]] ; CHECK: loop.latch: ; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i32 [[IV]], 1 ; CHECK-NEXT: br label [[LOOP]] ; CHECK: exit: ; CHECK-NEXT: [[TRUNC:%.*]] = trunc i32 [[PHI]] to i8 ; CHECK-NEXT: ret i8 [[TRUNC]] ; entry: br label %loop loop: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] %phi = phi i32 [ 1, %entry ], [ %iv.next, %loop.latch ] %cmp = icmp ult i32 %iv, 100 br i1 %cmp, label %loop.latch, label %exit loop.latch: %iv.next = add i32 %iv, 1 br label %loop exit: %trunc = trunc i32 %phi to i8 ret i8 %trunc } ``` `%iv u< 100` -> infer `nsw/nuw` for `%iv.next = add i32 %iv, 1` -> `%iv` is non-negative -> infer `samesign` for `%cmp = icmp ult i32 %iv, 100`. Without re-queuing users of phi nodes, we cannot improve `%cmp` in one iteration. Address review comment https://github.com/llvm/llvm-project/pull/112642#discussion_r1804712271. This patch also fixes some non-fixpoint issues in tests.
2024-11-06[LLVM][IR] Use splat syntax when printing Constant[Data]Vector. (#112548)Paul Walker1-1/+1
2024-10-28[InstCombine] Add function attribute `instcombine-no-verify-fixpoint` (#113822)Yingwei Zheng1-3/+3
This patch introduces a function attribute `instcombine-no-verify-fixpoint` to avoids disabling fix-point verification for unrelated tests in the same file. Address comment https://github.com/llvm/llvm-project/pull/112642#discussion_r1804714387.
2024-07-19[DebugInfo][SimpleLoopUnswitch] Fix missing debug location updates for new ↵Shan Huang1-0/+95
terminators (#98789) Fix #98787 .
2024-07-15[DebugInfo][SimpleLoopUnswitch] Fix missing debug location updates (#97662)Shan Huang1-0/+75
Fix #97559 . For the change at line 1253, I propagate the debug location of the terminator (i.e., the insertion point) to the new phi. because `MergeBB` is generated by splitting `ExitBB` several lines above, it only has the terminator, which could provide a reasonable debug location. For the change at line 2348, I switch the order of moving and cloning `TI`. Because `NewTI` cloned from `TI` is inserted into the original place where `TI` is, `NewTI` should preserve the origianl debug location. At the same time, doing this allows us to propagate the debug location to the new branch instruction replacing `NewTI` (the change at line 2446).
2024-06-14 [RemoveDIs] Print IR with debug records by default (#91724)Stephen Tozer1-2/+2
This patch makes the final major change of the RemoveDIs project, changing the default IR output from debug intrinsics to debug records. This is expected to break a large number of tests: every single one that tests for uses or declarations of debug intrinsics and does not explicitly disable writing records. If this patch has broken your downstream tests (or upstream tests on a configuration I wasn't able to run): 1. If you need to immediately unblock a build, pass `--write-experimental-debuginfo=false` to LLVM's option processing for all failing tests (remember to use `-mllvm` for clang/flang to forward arguments to LLVM). 2. For most test failures, the changes are trivial and mechanical, enough that they can be done by script; see the migration guide for a guide on how to do this: https://llvm.org/docs/RemoveDIsDebugInfo.html#test-updates 3. If any tests fail for reasons other than FileCheck check lines that need updating, such as assertion failures, that is most likely a real bug with this patch and should be reported as such. For more information, see the recent PSA: https://discourse.llvm.org/t/psa-ir-output-changing-from-debug-intrinsics-to-debug-records/79578
2024-05-03[StandardInstrumentation] Annotate loops with the function name (#90756)annamthomas1-1/+1
When analyzing pass debug output it is helpful to have the function name along with the loop name.
2024-04-29[LoopUnswitch] Allow i1 truncs in loop unswitch (#89738)Matthew Devereau2-0/+223
With the addition of #84628, truncs to i1 are being emitted as conditions to branch instructions. This caused significant regressions in cases which were previously improved by loop unswitch. Adding truncs to i1 restore the previous performance seen.
2024-03-06[SCEV] Extend type hint in analysis output to all backedge kindsPhilip Reames1-1/+1
This extends the work from 7755c26 to all of the different backend taken count kinds that we print for the scev analysis printer. As before, the goal is to cut down on confusion as i4 -1 is a very different (unsigned) value from i32 -1.
2024-01-24[MSSAUpdater] Handle simplified accesses when updating phis (#78272)Nikita Popov1-0/+104
This is a followup to #76819. After those changes, we can still run into an assertion failure for a slight variation of the test case: When fixing up MemoryPhis, we map the incoming access to the access of the cloned instruction -- which may now no longer exist. Fix this by reusing the getNewDefiningAccessForClone() helper, which will look upwards for a new defining access in that case.
2024-01-08[MSSA] Don't require clone creation to succeed (#76819)Nikita Popov1-0/+117
Sometimes, we create a MemoryAccess for an instruction, which is later simplified (e.g. via devirtualization) such that the new instruction has no memory effects anymore. If we later clone the instruction (e.g. during unswitching), then MSSA will not create a MemoryAccess for the new instruction, triggering an assert. Disable the assertion (by passing CreationMustSucceed=false) and adjust getDefiningAccessForClone() to work correctly in that case. This PR implements the alternative suggestion by alinas from https://github.com/llvm/llvm-project/pull/76142.
2023-12-06[ValueTracking] Add dominating condition support in computeKnownBits() (#73662)Nikita Popov1-2/+5
This adds support for using dominating conditions in computeKnownBits() when called from InstCombine. The implementation uses a DomConditionCache, which stores which branches may provide information that is relevant for a given value. DomConditionCache is similar to AssumptionCache, but does not try to do any kind of automatic tracking. Relevant branches have to be explicitly registered and invalidated values explicitly removed. The necessary tracking is done inside InstCombine. The reason why this doesn't just do exactly the same thing as AssumptionCache is that a lot more transforms touch branches and branch conditions than assumptions. AssumptionCache is an immutable analysis and mostly gets away with this because only a handful of places have to register additional assumptions (mostly as a result of cloning). This is very much not the case for branches. This change regresses compile-time by about ~0.2%. It also improves stage2-O0-g builds by about ~0.2%, which indicates that this change results in additional optimizations inside clang itself. Fixes https://github.com/llvm/llvm-project/issues/74242.
2023-11-28[SimpleLoopUnswitch] Regenerate test checks (NFC)Nikita Popov1-49/+64
2023-11-24[DebugInfo][RemoveDIs] Support cloning and remapping DPValues (#72546)Jeremy Morse1-0/+108
This patch adds support for CloneBasicBlock duplicating the DPValues attached to instructions, and adds facilities to remap them into their new context. The plumbing to achieve this is fairly straightforwards and mechanical. I've also added illustrative uses to LoopUnrollRuntime, SimpleLoopUnswitch and SimplifyCFG. The former only updates for the epilogue right now so I've added CHECK lines just for the end of an unrolled loop (further updates coming later). SimpleLoopUnswitch had no debug-info tests so I've added a new one. The two modified parts of SimplifyCFG are covered by the two modified SimplifyCFG tests. These are scenarios where we have to do extra cloning for copying of DPValues because they're no longer instructions, and remap them too.
2023-10-30[InstCombine] Infer nneg on zext when forming from non-negative sext (#70706)Philip Reames1-1/+1
Builds on #67982 which recently introduced the nneg flag on a zext instruction. InstCombine is one of our largest canonicalizers of zext from non-negative sext instructions, so set the flag there.
2023-10-30Regenerate a set of auto-update tests [nfc]Philip Reames1-2/+2
To reduce the spurious test delta in an upcoming change.
2023-09-21[SimpleLoopUnswitch] Fix exponential unswitchNikita Popov2-20/+295
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.
2023-09-20[SimpleLoopUnswitch] Fix reversed branch during condition injectionNikita Popov1-1/+1
The in-loop successor is only on the left after a potential condition inversion. As we re-use the old condition as-is, we should also reuse the old successors as-is. Fixes https://github.com/llvm/llvm-project/issues/63962.
2023-07-07SimpleLoopUnswitch: Restore uniform unswitch testMatt Arsenault1-0/+77
This was supposed to document the new PM limitation but was deleted in fb4113ef0c8b2c5e5e2817e9ca14fb57a6d252be Switch to generated checks since that's more reliable than XFAIL, and just preserve the preferred results as comments.
2023-07-07TTI: Pass function to hasBranchDivergence in a few passesMatt Arsenault1-22/+73
https://reviews.llvm.org/D152033
2023-06-19[BBUtils] Don't add 'then' block to a loop if it's terminated with unreachableDmitry Makogon2-6/+0
SplitBlockAndInsertIfThen utility creates two new blocks, they're called ThenBlock and Tail (true and false destinations of a conditional branch correspondingly). The function has a bool parameter Unreachable, and if it's set, then ThenBlock is terminated with an unreachable. At the end of the function the new blocks are added to the loop of the split block. However, in case ThenBlock is terminated with an unreachable, it cannot belong to any loop. Differential Revision: https://reviews.llvm.org/D152434
2023-06-14[SimpleLoopUnswitch] Unswitch AND/OR conditions of selectsJoshua Cao3-53/+127
If a select's condition is a AND/OR, we can unswitch invariant operands. This patch uses existing logic from unswitching AND/OR's for branch conditions. This patch fixes the Cost computation for unswitching selects to have the cost of the entire loop, since unswitching selects do not remove branches. This is required for this patch because otherwise, there are cases where unswitching selects of AND/OR is beating out unswitching of branches. This patch also prevents unswitching of logical AND/OR selects. This should instead be done by unswitching of AND/OR branch conditions. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D151677
2023-06-14[SimpleLoopUnswitch][NFC] Add tests for and/or conditions of selectsJoshua Cao1-0/+172
2023-06-09[SimpleLoopUnswitch] Verify LoopInfo in turnGuardIntoBranch under a flagDmitry Makogon2-2/+2
A follow-up for 64397d8. Only do verification if VerifyLoopInfo is set.
2023-06-08[SimpleLoopUnswitch] Verify LoopInfo after turning guards to branchesDmitry Makogon2-0/+4
SplitBlockAndInsertIfThen doesn't correctly update LoopInfo when called with Unreachable=true, which is the case when we turn guards to branches in SimpleLoopUnswitch. This adds LoopInfo verification before returning from turnGuardIntoBranch.
2023-06-02SimpleLoopUnswitch: Add missing test coverage for divergent target checkMatt Arsenault2-0/+174
No tests failed when I removed the hasBranchDivergence check, so add one.
2023-05-17[NFC][Py Reformat] Reformat lit.local.cfg python files in llvmTobias Hieta1-1/+1
This is a follow-up to b71edfaa4ec3c998aadb35255ce2f60bba2940b0 since I forgot the lit.local.cfg files in that one. Reformatting is done with `black`. If you end up having problems merging this commit because you have made changes to a python file, the best way to handle that is to run git checkout --ours <yourfile> and then reformat it with black. If you run into any problems, post to discourse about it and we will try to help. RFC Thread below: https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style Reviewed By: barannikov88, kwk Differential Revision: https://reviews.llvm.org/D150762
2023-05-15[SimpleLoopUnswitch] Skip trivial select conds for selectsJoshua Cao1-0/+59
Fixes https://github.com/llvm/llvm-project/issues/62715 If a select's condition is a trivial select: ``` %s = select %cond, i1 true, i1 false ``` Unswitch on %cond, rather than %s. This fixes crashes where there is a disparity in finding candidates and and the transformation logic.
2023-05-11[SimpleLoopUnswitch][reland 2] unswitch selectsJoshua Cao4-66/+414
The old LoopUnswitch pass unswitched selects, but the changes were never ported to the new SimpleLoopUnswitch. We unswitch by turning: ``` S = select %cond, %a, %b ``` into: ``` head: br %cond, label %then, label %tail then: br label %tail tail: S = phi [ %a, %then ], [ %b, %head ] ``` Unswitch selects are always nontrivial, since the successors do not exit the loop and the loop body always needs to be cloned. Unswitch selects always need to freeze the conditional if the conditional could be poison or undef. Selects don't propagate poison/undef, and branches on poison/undef causes UB. Reland 1 - Fix the insertion of freeze instructions. The original implementation inserts a dead freeze instruction that is not used by the unswitched branch. Reland 2 - Include https://reviews.llvm.org/D149560 in the same patch, which was originally reverted along with this patch. The patch prevents unswitching of selects with a vector conditional. This could have been caught in SimpleLoopUnswitch/crash.ll if it included tests for nontrivial unswitching. This reland also adds a run for the test file with nontrivial unswitching. Reviewed By: nikic, kachkov98, vitalybuka Differential Revision: https://reviews.llvm.org/D138526
2023-05-10Revert "[SimpleLoopUnswitch] unswitch selects"Benjamin Kramer3-375/+69
This reverts commit 21f226fc4591db6e98faf380137a42067c909582. Crashes on this test case: define void @test2() nounwind { entry: br label %bb.nph bb.nph: ; preds = %entry %and.i13521 = and <4 x i1> undef, undef br label %for.body for.body: ; preds = %for.body, %bb.nph %or.i = select <4 x i1> %and.i13521, <4 x i32> undef, <4 x i32> undef br i1 false, label %for.body, label %for.end for.end: ; preds = %for.body, %entry ret void }
2023-05-10[SimpleLoopUnswitch] unswitch selectsJoshua Cao3-69/+375
The old LoopUnswitch pass unswitched selects, but the changes were never ported to the new SimpleLoopUnswitch. We unswitch by turning: ``` S = select %cond, %a, %b ``` into: ``` head: br %cond, label %then, label %tail then: br label %tail tail: S = phi [ %a, %then ], [ %b, %head ] ``` Unswitch selects are always nontrivial, since the successors do not exit the loop and the loop body always needs to be cloned. Unswitch selects always need to freeze the conditional if the conditional could be poison or undef. Selects don't propagate poison/undef, and branches on poison/undef causes UB. Reviewed By: nikic, kachkov98, vitalybuka Differential Revision: https://reviews.llvm.org/D138526