[PATCH] StructurizeCFG: Fix verification failure with some loops.

Tom Stellard tom at stellard.net
Mon Nov 18 07:02:16 PST 2013


On Sat, Nov 16, 2013 at 10:34:34PM -0800, Matt Arsenault wrote:
> If the beginning of the loop was also the entry block
> of the function, branches were inserted to the entry block
> which isn't allowed. If this occurs, create a new dummy
> function entry block that branches to the start of the loop.
> 
> 
> http://llvm-reviews.chandlerc.com/D2197
> 
> Files:
>   lib/Transforms/Scalar/StructurizeCFG.cpp
>   test/Transforms/StructurizeCFG/no-branch-to-entry.ll
> 
> Index: lib/Transforms/Scalar/StructurizeCFG.cpp
> ===================================================================
> --- lib/Transforms/Scalar/StructurizeCFG.cpp
> +++ lib/Transforms/Scalar/StructurizeCFG.cpp
> @@ -779,6 +779,20 @@
>      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);
> +  }
> +
>    // Create an extra loop end node
>    LoopEnd = needPrefix(false);
>    BasicBlock *Next = needPostfix(LoopEnd, ExitUseAllowed);
> Index: test/Transforms/StructurizeCFG/no-branch-to-entry.ll
> ===================================================================
> --- /dev/null
> +++ test/Transforms/StructurizeCFG/no-branch-to-entry.ll
> @@ -0,0 +1,31 @@
> +; RUN: opt -S -o - -structurizecfg < %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
> +}

Same question as the other patch.  Is it possible to write tests that
don't have infinite loops?

-Tom



More information about the llvm-commits mailing list