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