diff --git a/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp b/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp --- a/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp +++ b/llvm/unittests/Transforms/Utils/CodeExtractorTest.cpp @@ -8,6 +8,7 @@ #include "llvm/Transforms/Utils/CodeExtractor.h" #include "llvm/AsmParser/Parser.h" +#include "llvm/Analysis/AssumptionCache.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Instructions.h" @@ -225,4 +226,55 @@ EXPECT_FALSE(verifyFunction(*Func)); } +TEST(CodeExtractor, ExtractAndInvalidateAssumptionCache) { + LLVMContext Ctx; + SMDiagnostic Err; + std::unique_ptr M(parseAssemblyString( + "target datalayout = \"e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128\" " + "target triple = \"aarch64\" " + " " + "%b = type { i64 } " + "declare void @g(i8*) " + " " + "declare void @llvm.assume(i1) #0 " + " " + "define void @test() { " + "entry: " + " br label %label " + " " + "label: " + " %0 = load %b*, %b** inttoptr (i64 8 to %b**), align 8 " + " %1 = getelementptr inbounds %b, %b* %0, i64 undef, i32 0 " + " %2 = load i64, i64* %1, align 8 " + " %3 = icmp ugt i64 %2, 1 " + " br i1 %3, label %if.then, label %if.else " + " " + "if.then: " + " unreachable " + " " + "if.else: " + " call void @g(i8* undef) " + " store i64 undef, i64* null, align 536870912 " + " %4 = icmp eq i64 %2, 0 " + " call void @llvm.assume(i1 %4) " + " unreachable " + "}" + " " + "attributes #0 = { nounwind willreturn } " + " ", + Err, Ctx)); + + assert(M && "Could not parse module?"); + Function *Func = M->getFunction("test"); + SmallVector Blocks{ getBlockByName(Func, "if.else") }; + AssumptionCache AC(*Func); + CodeExtractor CE(Blocks, nullptr, false, nullptr, nullptr, &AC); + EXPECT_TRUE(CE.isEligible()); + + Function *Outlined = CE.extractCodeRegion(); + EXPECT_TRUE(Outlined); + EXPECT_FALSE(verifyFunction(*Outlined)); + EXPECT_FALSE(verifyFunction(*Func)); + EXPECT_FALSE(CE.verifyAssumptionCache(*Func, &AC)); +} } // end anonymous namespace