[llvm] r340820 - [CloneFunction] Constant fold terminators before checking single predecessor

Hans Wennborg via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 30 01:35:58 PDT 2018


Merged to 7.0 in r341037.

On Tue, Aug 28, 2018 at 2:40 PM, Mikael Holmen via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: uabelho
> Date: Tue Aug 28 05:40:11 2018
> New Revision: 340820
>
> URL: http://llvm.org/viewvc/llvm-project?rev=340820&view=rev
> Log:
> [CloneFunction] Constant fold terminators before checking single predecessor
>
> Summary:
> This fixes PR31105.
>
> There is code trying to delete dead code that does so by e.g. checking if
> the single predecessor of a block is the block itself.
>
> That check fails on a block like this
>  bb:
>    br i1 undef, label %bb, label %bb
> since that has two (identical) predecessors.
>
> However, after the check for dead blocks there is a call to
> ConstantFoldTerminator on the basic block, and that call simplifies the
> block to
>  bb:
>    br label %bb
>
> Therefore we now do the call to ConstantFoldTerminator before the check if
> the block is dead, so it can realize that it really is.
>
> The original behavior lead to the block not being removed, but it was
> simplified as above, and then we did a call to
>     Dest->replaceAllUsesWith(&*I);
> with old and new being equal, and an assertion triggered.
>
> Reviewers: chandlerc, fhahn
>
> Reviewed By: fhahn
>
> Subscribers: eraman, llvm-commits
>
> Differential Revision: https://reviews.llvm.org/D51280
>
> Added:
>     llvm/trunk/test/Transforms/Inline/infinite-loop-two-predecessors.ll
> Modified:
>     llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
>
> Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=340820&r1=340819&r2=340820&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Tue Aug 28 05:40:11 2018
> @@ -636,6 +636,22 @@ void llvm::CloneAndPruneIntoFromInst(Fun
>    Function::iterator Begin = cast<BasicBlock>(VMap[StartingBB])->getIterator();
>    Function::iterator I = Begin;
>    while (I != NewFunc->end()) {
> +    // We need to simplify conditional branches and switches with a constant
> +    // operand. We try to prune these out when cloning, but if the
> +    // simplification required looking through PHI nodes, those are only
> +    // available after forming the full basic block. That may leave some here,
> +    // and we still want to prune the dead code as early as possible.
> +    //
> +    // Do the folding before we check if the block is dead since we want code
> +    // like
> +    //  bb:
> +    //    br i1 undef, label %bb, label %bb
> +    // to be simplified to
> +    //  bb:
> +    //    br label %bb
> +    // before we call I->getSinglePredecessor().
> +    ConstantFoldTerminator(&*I);
> +
>      // Check if this block has become dead during inlining or other
>      // simplifications. Note that the first block will appear dead, as it has
>      // not yet been wired up properly.
> @@ -646,13 +662,6 @@ void llvm::CloneAndPruneIntoFromInst(Fun
>        continue;
>      }
>
> -    // We need to simplify conditional branches and switches with a constant
> -    // operand. We try to prune these out when cloning, but if the
> -    // simplification required looking through PHI nodes, those are only
> -    // available after forming the full basic block. That may leave some here,
> -    // and we still want to prune the dead code as early as possible.
> -    ConstantFoldTerminator(&*I);
> -
>      BranchInst *BI = dyn_cast<BranchInst>(I->getTerminator());
>      if (!BI || BI->isConditional()) { ++I; continue; }
>
>
> Added: llvm/trunk/test/Transforms/Inline/infinite-loop-two-predecessors.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/infinite-loop-two-predecessors.ll?rev=340820&view=auto
> ==============================================================================
> --- llvm/trunk/test/Transforms/Inline/infinite-loop-two-predecessors.ll (added)
> +++ llvm/trunk/test/Transforms/Inline/infinite-loop-two-predecessors.ll Tue Aug 28 05:40:11 2018
> @@ -0,0 +1,32 @@
> +; RUN: opt -S -o - %s -inline | FileCheck %s
> +
> +define void @f1() {
> +bb.0:
> +  br i1 false, label %bb.2, label %bb.1
> +
> +bb.1:                                             ; preds = %bb.0
> +  br label %bb.2
> +
> +bb.2:                                             ; preds = %bb.0, %bb.1
> +  %tmp0 = phi i1 [ true, %bb.1 ], [ false, %bb.0 ]
> +  br i1 %tmp0, label %bb.4, label %bb.3
> +
> +bb.3:                                             ; preds = %bb.3, %bb.3
> +  br i1 undef, label %bb.3, label %bb.3
> +
> +bb.4:                                             ; preds = %bb.2
> +  ret void
> +}
> +
> +define void @f2() {
> +bb.0:
> +  call void @f1()
> +  ret void
> +}
> +
> +; f1 should be inlined into f2 and simplified/collapsed to nothing.
> +
> +; CHECK-LABEL: define void @f2() {
> +; CHECK-NEXT:  bb.0:
> +; CHECK-NEXT:    ret void
> +; CHECK-NEXT:  }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list