diff --git a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp --- a/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp @@ -2370,7 +2370,9 @@ ConstantInt *ContinueReplacement = Direction ? ConstantInt::getFalse(BI->getContext()) : ConstantInt::getTrue(BI->getContext()); - for (Value *Invariant : Invariants) + for (Value *Invariant : Invariants) { + assert(!isa(Invariant) && + "Should not be replacing constant values!"); // Use make_early_inc_range here as set invalidates the iterator. for (Use &U : llvm::make_early_inc_range(Invariant->uses())) { Instruction *UserI = dyn_cast(U.getUser()); @@ -2385,6 +2387,7 @@ DT.dominates(ClonedPH, UserI->getParent())) U.set(UnswitchedReplacement); } + } } // We can change which blocks are exit blocks of all the cloned sibling @@ -2727,6 +2730,9 @@ Cond = CondNext; BI->setCondition(Cond); + if (isa(Cond)) + continue; + if (L.isLoopInvariant(BI->getCondition())) { UnswitchCandidates.push_back({BI, {BI->getCondition()}}); continue; diff --git a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-invariant-select-bug.ll b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-invariant-select-bug.ll --- a/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-invariant-select-bug.ll +++ b/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-invariant-select-bug.ll @@ -1,31 +1,22 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -passes='simple-loop-unswitch' -S < %s | FileCheck %s -; FIXME: We should not replace `true` with `false` here! +; If we try to replace uses of `true` outside of `@foo`, we'll see it here. define i1 @bar() { ; CHECK-LABEL: @bar( -; CHECK-NEXT: ret i1 false +; CHECK-NEXT: ret i1 true ; ret i1 true } -; FIXME: We shouldn't unswitch this loop! +; We shouldn't unswitch this loop. define void @foo() { ; CHECK-LABEL: @foo( ; CHECK-NEXT: entry: -; CHECK-NEXT: br i1 true, label [[ENTRY_SPLIT_US:%.*]], label [[ENTRY_SPLIT:%.*]] -; CHECK: entry.split.us: -; CHECK-NEXT: br label [[HEADER_US:%.*]] -; CHECK: header.us: -; CHECK-NEXT: [[VAL_US:%.*]] = select i1 true, i1 true, i1 false -; CHECK-NEXT: br label [[EXIT_SPLIT_US:%.*]] -; CHECK: exit.split.us: -; CHECK-NEXT: br label [[EXIT:%.*]] -; CHECK: entry.split: ; CHECK-NEXT: br label [[HEADER:%.*]] ; CHECK: header: -; CHECK-NEXT: [[VAL:%.*]] = select i1 false, i1 false, i1 false -; CHECK-NEXT: br label [[HEADER]] +; CHECK-NEXT: [[VAL:%.*]] = select i1 true, i1 true, i1 false +; CHECK-NEXT: br i1 true, label [[EXIT:%.*]], label [[HEADER]] ; CHECK: exit: ; CHECK-NEXT: ret void ;