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