//=======- AliasSetTrackerTest.cpp - Unit test for the Alias Set Tracker -===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/Analysis/TypeBasedAliasAnalysis.h" #include "llvm/AsmParser/Parser.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/Support/SourceMgr.h" #include "gtest/gtest.h" using namespace llvm; TEST(AliasSetTracker, AliasUnknownInst) { StringRef Assembly = R"( @a = common global i32 0, align 4 @b = common global float 0.000000e+00, align 4 ; Function Attrs: nounwind ssp uwtable define i32 @read_a() #0 { %1 = load i32, i32* @a, align 4, !tbaa !3 ret i32 %1 } ; Function Attrs: nounwind ssp uwtable define void @write_b() #0 { store float 1.000000e+01, float* @b, align 4, !tbaa !7 ret void } ; Function Attrs: nounwind ssp uwtable define void @test() #0 { %1 = call i32 @read_a(), !tbaa !3 call void @write_b(), !tbaa !7 ret void } !3 = !{!4, !4, i64 0} !4 = !{!"int", !5, i64 0} !5 = !{!"omnipotent char", !6, i64 0} !6 = !{!"Simple C/C++ TBAA"} !7 = !{!8, !8, i64 0} !8 = !{!"float", !5, i64 0} )"; // Parse the IR. The two calls in @test can not access aliasing elements. LLVMContext Context; SMDiagnostic Error; auto M = parseAssemblyString(Assembly, Error, Context); ASSERT_TRUE(M) << "Bad assembly?"; // Initialize the alias result. Triple Trip(M->getTargetTriple()); TargetLibraryInfoImpl TLII(Trip); TargetLibraryInfo TLI(TLII); AAResults AA(TLI); TypeBasedAAResult TBAAR; AA.addAAResult(TBAAR); // Initialize the alias set tracker for the @test function. Function *Test = M->getFunction("test"); ASSERT_NE(Test, nullptr); AliasSetTracker AST(AA); for (auto &BB : *Test) AST.add(BB); // There should be 2 disjoint alias sets. 1 from each call. ASSERT_EQ((int)AST.getAliasSets().size(), 2); // Directly test aliasesUnknownInst. // Now every call instruction should only alias one alias set. for (auto &Inst : *Test->begin()) { bool FoundAS = false; for (AliasSet &AS : AST) { if (!Inst.mayReadOrWriteMemory()) continue; if (!AS.aliasesUnknownInst(&Inst, AA)) continue; ASSERT_NE(FoundAS, true); FoundAS = true; } } }