Index: llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp =================================================================== --- llvm/lib/Transforms/Scalar/SimpleLoopUnswitch.cpp +++ 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; Index: llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-invariant-select-bug.ll =================================================================== --- llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-invariant-select-bug.ll +++ llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-invariant-select-bug.ll @@ -1,15 +1,25 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; REQUIRES: asserts -; XFAIL: * -; RUN: opt -passes='simple-loop-unswitch' -S < %s -disable-output +; RUN: opt -passes='simple-loop-unswitch' -S < %s | FileCheck %s ; 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 true +; ret i1 true } ; We shouldn't unswitch this loop. define void @foo() { +; CHECK-LABEL: @foo( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[HEADER:%.*]] +; CHECK: 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 +; entry: br label %header