llvm-project
212 строк · 6.5 Кб
1//===- llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp ---------===//
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/IR/MemoryModelRelaxationAnnotations.h"
10#include "llvm/ADT/STLExtras.h"
11#include "llvm/IR/Metadata.h"
12#include "llvm/IR/Module.h"
13#include "gtest/gtest.h"
14
15using namespace llvm;
16
17namespace {
18
19void checkMMRA(const MMRAMetadata &MMRA,
20ArrayRef<MMRAMetadata::TagT> Expected) {
21EXPECT_EQ(MMRA.size(), Expected.size());
22for (const auto &E : Expected)
23EXPECT_TRUE(MMRA.hasTag(E.first, E.second));
24}
25
26MMRAMetadata createFromMD(LLVMContext &Ctx,
27ArrayRef<MMRAMetadata::TagT> Expected) {
28SmallVector<Metadata *> MD;
29for (const auto &Tag : Expected)
30MD.push_back(MMRAMetadata::getTagMD(Ctx, Tag));
31return MDTuple::get(Ctx, MD);
32}
33
34TEST(MMRATest, MDParse) {
35LLVMContext Ctx;
36
37// No nesting:
38// !{!"foo", "!bar"}
39MDNode *FooBar =
40MDTuple::get(Ctx, {MDString::get(Ctx, "foo"), MDString::get(Ctx, "bar")});
41MMRAMetadata FooBarMMRA(FooBar);
42
43checkMMRA(FooBarMMRA, {{"foo", "bar"}});
44
45// Nested:
46// !{!{!"foo", "!bar"}, !{!"bux", !"qux"}}
47MDNode *BuxQux =
48MDTuple::get(Ctx, {MDString::get(Ctx, "bux"), MDString::get(Ctx, "qux")});
49MDNode *Nested = MDTuple::get(Ctx, {FooBar, BuxQux});
50MMRAMetadata NestedMMRA(Nested);
51
52checkMMRA(NestedMMRA, {{"foo", "bar"}, {"bux", "qux"}});
53}
54
55TEST(MMRATest, GetMD) {
56LLVMContext Ctx;
57
58EXPECT_EQ(MMRAMetadata::getMD(Ctx, {}), nullptr);
59
60MDTuple *SingleMD = MMRAMetadata::getMD(Ctx, {{"foo", "bar"}});
61EXPECT_EQ(SingleMD->getNumOperands(), 2u);
62EXPECT_EQ(cast<MDString>(SingleMD->getOperand(0))->getString(), "foo");
63EXPECT_EQ(cast<MDString>(SingleMD->getOperand(1))->getString(), "bar");
64
65MDTuple *MultiMD = MMRAMetadata::getMD(Ctx, {{"foo", "bar"}, {"bux", "qux"}});
66EXPECT_EQ(MultiMD->getNumOperands(), 2u);
67
68MDTuple *FooBar = cast<MDTuple>(MultiMD->getOperand(0));
69EXPECT_EQ(cast<MDString>(FooBar->getOperand(0))->getString(), "foo");
70EXPECT_EQ(cast<MDString>(FooBar->getOperand(1))->getString(), "bar");
71MDTuple *BuxQux = cast<MDTuple>(MultiMD->getOperand(1));
72EXPECT_EQ(cast<MDString>(BuxQux->getOperand(0))->getString(), "bux");
73EXPECT_EQ(cast<MDString>(BuxQux->getOperand(1))->getString(), "qux");
74}
75
76TEST(MMRATest, Utility) {
77LLVMContext Ctx;
78MMRAMetadata MMRA =
79createFromMD(Ctx, {{"foo", "0"}, {"foo", "1"}, {"bar", "x"}});
80
81EXPECT_TRUE(MMRA.hasTagWithPrefix("foo"));
82EXPECT_TRUE(MMRA.hasTagWithPrefix("bar"));
83EXPECT_FALSE(MMRA.hasTagWithPrefix("x"));
84
85EXPECT_TRUE(MMRA.hasTag("foo", "0"));
86EXPECT_TRUE(MMRA.hasTag("foo", "1"));
87EXPECT_TRUE(MMRA.hasTag("bar", "x"));
88}
89
90TEST(MMRATest, Operators) {
91LLVMContext Ctx;
92
93MMRAMetadata A = createFromMD(Ctx, {{"foo", "0"}, {"bar", "x"}});
94MMRAMetadata B = createFromMD(Ctx, {{"foo", "0"}, {"bar", "y"}});
95
96// ensure we have different objects by creating copies.
97EXPECT_EQ(MMRAMetadata(A), MMRAMetadata(A));
98EXPECT_TRUE((bool)A);
99
100EXPECT_EQ(MMRAMetadata(B), MMRAMetadata(B));
101EXPECT_TRUE((bool)B);
102
103EXPECT_NE(A, B);
104
105EXPECT_EQ(MMRAMetadata(), MMRAMetadata());
106EXPECT_NE(A, MMRAMetadata());
107EXPECT_NE(B, MMRAMetadata());
108
109MMRAMetadata Empty;
110EXPECT_FALSE((bool)Empty);
111}
112
113TEST(MMRATest, Compatibility) {
114LLVMContext Ctx;
115
116MMRAMetadata Foo0 = createFromMD(Ctx, {{"foo", "0"}});
117MMRAMetadata Foo1 = createFromMD(Ctx, {{"foo", "1"}});
118MMRAMetadata Foo10 = createFromMD(Ctx, {{"foo", "0"}, {"foo", "1"}});
119
120MMRAMetadata Bar = createFromMD(Ctx, {{"bar", "y"}});
121
122MMRAMetadata Empty;
123
124// Other set has no tag with same prefix
125EXPECT_TRUE(Foo0.isCompatibleWith(Bar));
126EXPECT_TRUE(Bar.isCompatibleWith(Foo0));
127
128EXPECT_TRUE(Foo0.isCompatibleWith(Empty));
129EXPECT_TRUE(Empty.isCompatibleWith(Foo0));
130
131EXPECT_TRUE(Empty.isCompatibleWith(MMRAMetadata()));
132EXPECT_TRUE(MMRAMetadata().isCompatibleWith(Empty));
133
134// Other set has conflicting tags.
135EXPECT_FALSE(Foo1.isCompatibleWith(Foo0));
136EXPECT_FALSE(Foo0.isCompatibleWith(Foo1));
137
138// Both have common tags.
139EXPECT_TRUE(Foo0.isCompatibleWith(Foo0));
140EXPECT_TRUE(Foo0.isCompatibleWith(Foo10));
141EXPECT_TRUE(Foo10.isCompatibleWith(Foo0));
142
143EXPECT_TRUE(Foo1.isCompatibleWith(Foo1));
144EXPECT_TRUE(Foo1.isCompatibleWith(Foo10));
145EXPECT_TRUE(Foo10.isCompatibleWith(Foo1));
146
147// Try with more prefixes now:
148MMRAMetadata Multiple0 =
149createFromMD(Ctx, {{"foo", "y"}, {"foo", "x"}, {"bar", "z"}});
150MMRAMetadata Multiple1 =
151createFromMD(Ctx, {{"foo", "z"}, {"foo", "x"}, {"bar", "y"}});
152MMRAMetadata Multiple2 =
153createFromMD(Ctx, {{"foo", "z"}, {"foo", "x"}, {"bux", "y"}});
154
155// Multiple0 and Multiple1 are not compatible because "bar" is getting in the
156// way.
157EXPECT_FALSE(Multiple0.isCompatibleWith(Multiple1));
158EXPECT_FALSE(Multiple1.isCompatibleWith(Multiple0));
159
160EXPECT_TRUE(Multiple0.isCompatibleWith(Empty));
161EXPECT_TRUE(Empty.isCompatibleWith(Multiple0));
162EXPECT_TRUE(Multiple1.isCompatibleWith(Empty));
163EXPECT_TRUE(Empty.isCompatibleWith(Multiple1));
164
165// Multiple2 is compatible with both 1/0 because there is always "foo:x" in
166// common, and the other prefixes are unique to each set.
167EXPECT_TRUE(Multiple2.isCompatibleWith(Multiple0));
168EXPECT_TRUE(Multiple0.isCompatibleWith(Multiple2));
169EXPECT_TRUE(Multiple2.isCompatibleWith(Multiple1));
170EXPECT_TRUE(Multiple1.isCompatibleWith(Multiple2));
171}
172
173TEST(MMRATest, Combine) {
174LLVMContext Ctx;
175
176MMRAMetadata Foo0 = createFromMD(Ctx, {{"foo", "0"}});
177MMRAMetadata Foo10 = createFromMD(Ctx, {{"foo", "0"}, {"foo", "1"}});
178MMRAMetadata Bar0 = createFromMD(Ctx, {{"bar", "0"}});
179MMRAMetadata BarFoo0 = createFromMD(Ctx, {{"bar", "0"}, {"foo", "0"}});
180
181{
182// foo is common to both sets
183MMRAMetadata Combined = MMRAMetadata::combine(Ctx, Foo0, Foo10);
184EXPECT_EQ(Combined, Foo10);
185}
186
187{
188// nothing is common
189MMRAMetadata Combined = MMRAMetadata::combine(Ctx, Foo0, Bar0);
190EXPECT_TRUE(Combined.empty());
191}
192
193{
194// only foo is common.
195MMRAMetadata Combined = MMRAMetadata::combine(Ctx, BarFoo0, Foo0);
196EXPECT_EQ(Combined, Foo0);
197}
198
199{
200// only bar is common.
201MMRAMetadata Combined = MMRAMetadata::combine(Ctx, BarFoo0, Bar0);
202EXPECT_EQ(Combined, Bar0);
203}
204
205{
206// only foo is common
207MMRAMetadata Combined = MMRAMetadata::combine(Ctx, BarFoo0, Foo10);
208EXPECT_EQ(Combined, Foo10);
209}
210}
211
212} // namespace
213