assert(Candidate.hasPendingInjection() && "Nothing to inject!");
BasicBlock *Preheader = L.getLoopPreheader();
assert(Preheader && "Loop is not in simplified form?");
+ assert(LI.getLoopFor(Candidate.TI->getParent()) == &L &&
+ "Unswitching branch of inner loop!");
auto Pred = Candidate.PendingInjection->Pred;
auto *LHS = Candidate.PendingInjection->LHS;
Value *LHS = nullptr, *RHS = nullptr;
BasicBlock *IfTrue = nullptr, *IfFalse = nullptr;
auto *BB = DTN->getBlock();
+ // Ignore inner loops.
+ if (LI.getLoopFor(BB) != &L)
+ continue;
auto *Term = BB->getTerminator();
if (!match(Term, m_Br(m_ICmp(Pred, m_Value(LHS), m_Value(RHS)),
m_BasicBlock(IfTrue), m_BasicBlock(IfFalse))))
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -simple-loop-unswitch-inject-invariant-conditions=true -passes='loop(simple-loop-unswitch<nontrivial>,loop-instsimplify)' -S | FileCheck %s
-; REQUIRES: asserts
-; XFAIL: *
define void @test() {
-; CHECK-LABEL: test
+; CHECK-LABEL: @test(
+; CHECK-NEXT: bb:
+; CHECK-NEXT: [[TMP:%.*]] = call i1 @llvm.experimental.widenable.condition()
+; CHECK-NEXT: [[TMP1:%.*]] = load atomic i32, ptr addrspace(1) poison unordered, align 8
+; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, ptr addrspace(1) poison unordered, align 8
+; CHECK-NEXT: br label [[BB3:%.*]]
+; CHECK: bb3:
+; CHECK-NEXT: [[TMP_FR:%.*]] = freeze i1 [[TMP]]
+; CHECK-NEXT: br i1 [[TMP_FR]], label [[BB3_SPLIT:%.*]], label [[BB3_SPLIT_US:%.*]]
+; CHECK: bb3.split.us:
+; CHECK-NEXT: br label [[BB4_US:%.*]]
+; CHECK: bb4.us:
+; CHECK-NEXT: [[TMP5_US:%.*]] = phi i32 [ poison, [[BB3_SPLIT_US]] ]
+; CHECK-NEXT: [[TMP6_US:%.*]] = phi i32 [ poison, [[BB3_SPLIT_US]] ]
+; CHECK-NEXT: [[TMP7_US:%.*]] = add nuw nsw i32 [[TMP6_US]], 2
+; CHECK-NEXT: [[TMP8_US:%.*]] = icmp ult i32 [[TMP7_US]], [[TMP2]]
+; CHECK-NEXT: br i1 [[TMP8_US]], label [[BB9_US:%.*]], label [[BB16_SPLIT_US:%.*]], !prof [[PROF0:![0-9]+]]
+; CHECK: bb9.us:
+; CHECK-NEXT: br label [[BB17_SPLIT_US:%.*]]
+; CHECK: bb16.split.us:
+; CHECK-NEXT: br label [[BB16:%.*]]
+; CHECK: bb17.split.us:
+; CHECK-NEXT: br label [[BB17:%.*]]
+; CHECK: bb3.split:
+; CHECK-NEXT: br label [[BB4:%.*]]
+; CHECK: bb4:
+; CHECK-NEXT: [[TMP5:%.*]] = phi i32 [ poison, [[BB3_SPLIT]] ], [ [[TMP14:%.*]], [[BB13:%.*]] ]
+; CHECK-NEXT: [[TMP6:%.*]] = phi i32 [ poison, [[BB3_SPLIT]] ], [ [[TMP5]], [[BB13]] ]
+; CHECK-NEXT: [[TMP7:%.*]] = add nuw nsw i32 [[TMP6]], 2
+; CHECK-NEXT: [[TMP8:%.*]] = icmp ult i32 [[TMP7]], [[TMP2]]
+; CHECK-NEXT: br i1 [[TMP8]], label [[BB9:%.*]], label [[BB16_SPLIT:%.*]], !prof [[PROF0]]
+; CHECK: bb9:
+; CHECK-NEXT: [[TMP10:%.*]] = icmp ult i32 [[TMP7]], [[TMP1]]
+; CHECK-NEXT: br i1 [[TMP10]], label [[BB12:%.*]], label [[BB17_SPLIT:%.*]], !prof [[PROF0]]
+; CHECK: bb12:
+; CHECK-NEXT: br i1 true, label [[BB15:%.*]], label [[BB13]]
+; CHECK: bb13:
+; CHECK-NEXT: [[TMP14]] = add nuw nsw i32 [[TMP5]], 1
+; CHECK-NEXT: br label [[BB4]]
+; CHECK: bb15:
+; CHECK-NEXT: br label [[BB3]]
+; CHECK: bb16.split:
+; CHECK-NEXT: br label [[BB16]]
+; CHECK: bb16:
+; CHECK-NEXT: ret void
+; CHECK: bb17.split:
+; CHECK-NEXT: br label [[BB17]]
+; CHECK: bb17:
+; CHECK-NEXT: ret void
+;
bb:
%tmp = call i1 @llvm.experimental.widenable.condition()
%tmp1 = load atomic i32, ptr addrspace(1) poison unordered, align 8