1 | //=======- AliasSetTrackerTest.cpp - Unit test for the Alias Set Tracker -===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/Analysis/AliasSetTracker.h" |
10 | #include "llvm/Analysis/AliasAnalysis.h" |
11 | #include "llvm/Analysis/TargetLibraryInfo.h" |
12 | #include "llvm/Analysis/TypeBasedAliasAnalysis.h" |
13 | #include "llvm/AsmParser/Parser.h" |
14 | #include "llvm/IR/LLVMContext.h" |
15 | #include "llvm/IR/Module.h" |
16 | #include "llvm/Support/SourceMgr.h" |
17 | #include "llvm/TargetParser/Triple.h" |
18 | #include "gtest/gtest.h" |
19 | |
20 | using namespace llvm; |
21 | |
22 | TEST(AliasSetTracker, AliasUnknownInst) { |
23 | StringRef Assembly = R"( |
24 | @a = common global i32 0, align 4 |
25 | @b = common global float 0.000000e+00, align 4 |
26 | |
27 | ; Function Attrs: nounwind ssp uwtable |
28 | define i32 @read_a() #0 { |
29 | %1 = load i32, i32* @a, align 4, !tbaa !3 |
30 | ret i32 %1 |
31 | } |
32 | |
33 | ; Function Attrs: nounwind ssp uwtable |
34 | define void @write_b() #0 { |
35 | store float 1.000000e+01, float* @b, align 4, !tbaa !7 |
36 | ret void |
37 | } |
38 | |
39 | ; Function Attrs: nounwind ssp uwtable |
40 | define void @test() #0 { |
41 | %1 = call i32 @read_a(), !tbaa !3 |
42 | call void @write_b(), !tbaa !7 |
43 | ret void |
44 | } |
45 | |
46 | !3 = !{!4, !4, i64 0} |
47 | !4 = !{!"int", !5, i64 0} |
48 | !5 = !{!"omnipotent char", !6, i64 0} |
49 | !6 = !{!"Simple C/C++ TBAA"} |
50 | !7 = !{!8, !8, i64 0} |
51 | !8 = !{!"float", !5, i64 0} |
52 | )" ; |
53 | |
54 | // Parse the IR. The two calls in @test can not access aliasing elements. |
55 | LLVMContext Context; |
56 | SMDiagnostic Error; |
57 | auto M = parseAssemblyString(AsmString: Assembly, Err&: Error, Context); |
58 | ASSERT_TRUE(M) << "Bad assembly?" ; |
59 | |
60 | // Initialize the alias result. |
61 | Triple Trip(M->getTargetTriple()); |
62 | TargetLibraryInfoImpl TLII(Trip); |
63 | TargetLibraryInfo TLI(TLII); |
64 | AAResults AA(TLI); |
65 | TypeBasedAAResult TBAAR; |
66 | AA.addAAResult(AAResult&: TBAAR); |
67 | |
68 | // Initialize the alias set tracker for the @test function. |
69 | Function *Test = M->getFunction(Name: "test" ); |
70 | ASSERT_NE(Test, nullptr); |
71 | BatchAAResults BAA(AA); |
72 | AliasSetTracker AST(BAA); |
73 | for (auto &BB : *Test) |
74 | AST.add(BB); |
75 | // There should be 2 disjoint alias sets. 1 from each call. |
76 | ASSERT_EQ((int)AST.getAliasSets().size(), 2); |
77 | |
78 | // Directly test aliasesUnknownInst. |
79 | // Now every call instruction should only alias one alias set. |
80 | BatchAAResults BatchAA(AA); |
81 | for (auto &Inst : *Test->begin()) { |
82 | bool FoundAS = false; |
83 | for (AliasSet &AS : AST) { |
84 | if (!Inst.mayReadOrWriteMemory()) |
85 | continue; |
86 | if (!isModOrRefSet(MRI: AS.aliasesUnknownInst(Inst: &Inst, AA&: BatchAA))) |
87 | continue; |
88 | ASSERT_NE(FoundAS, true); |
89 | FoundAS = true; |
90 | } |
91 | } |
92 | } |
93 | |