| //=======- 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/AliasSetTracker.h" |
| #include "llvm/ADT/Triple.h" |
| #include "llvm/Analysis/AliasAnalysis.h" |
| #include "llvm/Analysis/TargetLibraryInfo.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; |
| } |
| } |
| } |