diff --git a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp --- a/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp +++ b/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp @@ -972,20 +972,7 @@ handleLoops(false, LoopEnd); } - // If the start of the loop is the entry block, we can't branch to it so - // insert a new dummy entry block. - Function *LoopFunc = LoopStart->getParent(); - if (LoopStart == &LoopFunc->getEntryBlock()) { - LoopStart->setName("entry.orig"); - - BasicBlock *NewEntry = - BasicBlock::Create(LoopStart->getContext(), - "entry", - LoopFunc, - LoopStart); - BranchInst::Create(LoopStart, NewEntry); - DT->setNewRoot(NewEntry); - } + assert(LoopStart != &LoopStart->getParent()->getEntryBlock()); // Create an extra loop end node LoopEnd = needPrefix(false); diff --git a/llvm/test/Transforms/StructurizeCFG/infinite-loop.ll b/llvm/test/Transforms/StructurizeCFG/infinite-loop.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/StructurizeCFG/infinite-loop.ll @@ -0,0 +1,59 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -o - -structurizecfg -verify-dom-info < %s | FileCheck %s + +; This test hits a limitation in StructurizeCFG: it doesn't handle infinite-loops. +; In this case, the IR remains unchanged. + +define void @infinite_loop_false(i32 addrspace(1)* %out, i1 %cond) { +; CHECK-LABEL: @infinite_loop_false( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[COND:%.*]], label [[FOR_END:%.*]], label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: store volatile i32 999, i32 addrspace(1)* [[OUT:%.*]], align 4 +; CHECK-NEXT: br label [[FOR_BODY]] +; CHECK: for.end: +; CHECK-NEXT: ret void +; +entry: + br i1 %cond, label %for.end, label %for.body + +for.body: + store volatile i32 999, i32 addrspace(1)* %out, align 4 + br label %for.body + +for.end: + ret void +} + +define void @infinite_loop_on_branch(i32 addrspace(1)* %out, i1 %cond) { +; CHECK-LABEL: @infinite_loop_on_branch( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: br label [[FOR_BODY:%.*]] +; CHECK: for.body: +; CHECK-NEXT: store volatile i32 999, i32 addrspace(1)* [[OUT:%.*]], align 4 +; CHECK-NEXT: br label [[FOR_BODY]] +; CHECK: if.else: +; CHECK-NEXT: store volatile i32 111, i32 addrspace(1)* [[OUT]], align 4 +; CHECK-NEXT: br label [[EXIT:%.*]] +; CHECK: exit: +; CHECK-NEXT: ret void +; +entry: + br i1 %cond, label %if.then, label %if.else + +if.then: + br label %for.body + +for.body: + store volatile i32 999, i32 addrspace(1)* %out, align 4 + br label %for.body + +if.else: + store volatile i32 111, i32 addrspace(1)* %out, align 4 + br label %exit + +exit: + ret void +} diff --git a/llvm/test/Transforms/StructurizeCFG/no-branch-to-entry.ll b/llvm/test/Transforms/StructurizeCFG/no-branch-to-entry.ll deleted file mode 100644 --- a/llvm/test/Transforms/StructurizeCFG/no-branch-to-entry.ll +++ /dev/null @@ -1,38 +0,0 @@ -; XFAIL: * - -; This test used to generate a region that caused it to delete the entry block, -; but it does not anymore after the changes to handling of infinite loops in the -; PostDominatorTree. -; TODO: This should be either replaced with another IR or deleted completely. - -; RUN: opt -S -o - -structurizecfg -verify-dom-info < %s | FileCheck %s - -; CHECK-LABEL: @no_branch_to_entry_undef( -; CHECK: entry: -; CHECK-NEXT: br label %entry.orig -define void @no_branch_to_entry_undef(i32 addrspace(1)* %out) { -entry: - br i1 undef, label %for.end, label %for.body - -for.body: ; preds = %entry, %for.body - store i32 999, i32 addrspace(1)* %out, align 4 - br label %for.body - -for.end: ; preds = %Flow - ret void -} - -; CHECK-LABEL: @no_branch_to_entry_true( -; CHECK: entry: -; CHECK-NEXT: br label %entry.orig -define void @no_branch_to_entry_true(i32 addrspace(1)* %out) { -entry: - br i1 true, label %for.end, label %for.body - -for.body: ; preds = %entry, %for.body - store i32 999, i32 addrspace(1)* %out, align 4 - br label %for.body - -for.end: ; preds = %Flow - ret void -}