diff --git a/llvm/test/Reduce/do-not-remove-terminator.ll b/llvm/test/Reduce/do-not-remove-terminator.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Reduce/do-not-remove-terminator.ll @@ -0,0 +1,19 @@ +; RUN: llvm-reduce --test FileCheck --test-arg --check-prefixes=CHECK-INTERESTINGNESS --test-arg %s --test-arg --input-file %s -o %t +; RUN: cat %t | FileCheck --check-prefixes=CHECK-FINAL %s + +; Make sure we do not remove the terminator of the entry block. The interesting +; check only requires the result to define the function @test. + +; Test case for PR43798. + +; CHECK-INTERESTINGNESS: define i32 @test + +; CHECK-FINAL: define i32 @test +; CHECK-FINAL-NEXT: entry: +; CHECK-FINAL-NEXT: ret i32 + +define i32 @test(i32 %x) { +entry: + %add = add i32 %x, %x + ret i32 %add +} diff --git a/llvm/test/Reduce/remove-funcs.ll b/llvm/test/Reduce/remove-funcs.ll --- a/llvm/test/Reduce/remove-funcs.ll +++ b/llvm/test/Reduce/remove-funcs.ll @@ -20,6 +20,7 @@ ; CHECK-FINAL-NEXT: entry: ; CHECK-FINAL-NEXT: %call2 = call i32 @interesting() +; CHECK-FINAL-NEXT: ret i32 5 ; CHECK-FINAL-NEXT: } define i32 @uninteresting2() { diff --git a/llvm/test/Reduce/remove-instructions.ll b/llvm/test/Reduce/remove-instructions.ll --- a/llvm/test/Reduce/remove-instructions.ll +++ b/llvm/test/Reduce/remove-instructions.ll @@ -4,8 +4,12 @@ ; RUN: cat %t | FileCheck -implicit-check-not=uninteresting %s ; REQUIRES: plugins -; We're testing all direct uses of %interesting are conserved +; We're testing all direct uses of %interesting are conserved. The terminator +; (ret) must also be preserved. + ; CHECK-COUNT-5: %interesting +; CHECK: ret + define i32 @main() #0 { entry: %uninteresting1 = alloca i32, align 4 @@ -18,6 +22,5 @@ store i32 %uninteresting3, i32* %interesting, align 4 %1 = load i32, i32* %interesting, align 4 store i32 %1, i32* %uninteresting2, align 4 - ; CHECK-NOT: ret ret i32 0 } diff --git a/llvm/tools/llvm-reduce/deltas/ReduceInstructions.cpp b/llvm/tools/llvm-reduce/deltas/ReduceInstructions.cpp --- a/llvm/tools/llvm-reduce/deltas/ReduceInstructions.cpp +++ b/llvm/tools/llvm-reduce/deltas/ReduceInstructions.cpp @@ -24,10 +24,14 @@ std::set InstToKeep; for (auto &F : *Program) - for (auto &BB : F) - for (auto &Inst : BB) + for (auto &BB : F) { + // Removing the terminator would make the block invalid. Only iterate over + // instructions before the terminator. + InstToKeep.insert(BB.getTerminator()); + for (auto &Inst : make_range(BB.begin(), std::prev(BB.end()))) if (O.shouldKeep()) InstToKeep.insert(&Inst); + } std::vector InstToDelete; for (auto &F : *Program) @@ -49,7 +53,8 @@ int InstCount = 0; for (auto &F : *Program) for (auto &BB : F) - InstCount += BB.getInstList().size(); + // Well-formed blocks have terminators, which we cannot remove. + InstCount += BB.getInstList().size() - 1; outs() << "Number of instructions: " << InstCount << "\n"; return InstCount;