diff --git a/llvm/test/tools/llvm-reduce/remove-bbs-sequence.ll b/llvm/test/tools/llvm-reduce/remove-bbs-sequence.ll new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-reduce/remove-bbs-sequence.ll @@ -0,0 +1,30 @@ +; RUN: llvm-reduce --delta-passes=basic-blocks --test %python --test-arg %p/remove-bbs-sequence.py %s -o %t +; RUN: cat %t | FileCheck %s + +; The interestingness test is that the CFG contains a loop. Verify that the +; unnecessary bb2 and bb3 are removed while still maintaining a loop. + +define void @main() { + bb0: + br label %bb1 + bb1: + br label %bb2 + bb2: + br label %bb3 + bb3: + %phi = phi i32 [ undef, %bb2 ] + br label %bb4 + bb4: + br label %bb1 +} + +; CHECK:define void @main() { +; CHECK-NEXT: bb0: +; CHECK-NEXT: br label %bb1 +; CHECK-EMPTY: +; CHECK-NEXT: bb1: +; CHECK-NEXT: br label %bb4 +; CHECK-EMPTY: +; CHECK-NEXT: bb4: +; CHECK-NEXT: br label %bb1 +; CHECK-NEXT:} diff --git a/llvm/test/tools/llvm-reduce/remove-bbs-sequence.py b/llvm/test/tools/llvm-reduce/remove-bbs-sequence.py new file mode 100755 --- /dev/null +++ b/llvm/test/tools/llvm-reduce/remove-bbs-sequence.py @@ -0,0 +1,15 @@ +import subprocess +import sys + +opt = subprocess.run( [ 'opt', '-passes=print','-disable-output', sys.argv[1]], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) + +stdout = opt.stdout.decode() + +pattern = 'Loop at depth 1 containing' + +if (pattern in opt.stderr.decode()): + print('This is interesting!') + sys.exit(0) +else: + print('This is NOT interesting!') + sys.exit(1) diff --git a/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp b/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp --- a/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceBasicBlocks.cpp @@ -47,6 +47,19 @@ Term->eraseFromParent(); if (ChunkSuccessors.empty()) { + // Scan forward in BB list to try find a block that is kept. + Function &F = *BB.getParent(); + Function::iterator FI = BB.getIterator(); + FI++; + while (FI != F.end()) { + auto &FIB = *FI; + if (BBsToKeep.count(&FIB) && !isa(FIB.begin())) { + BranchInst::Create(&FIB, &BB); + return; + } + FI++; + } + // If that fails then resort to replacing with a ret. auto *FnRetTy = BB.getParent()->getReturnType(); ReturnInst::Create(BB.getContext(), FnRetTy->isVoidTy() ? nullptr : UndefValue::get(FnRetTy),