213 lines · cpp
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-exception6//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,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 26MMRAMetadata 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 34TEST(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 55TEST(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 76TEST(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 90TEST(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 113TEST(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 prefix125 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 the156 // 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" in166 // 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 173TEST(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 sets183 MMRAMetadata Combined = MMRAMetadata::combine(Ctx, Foo0, Foo10);184 EXPECT_EQ(Combined, Foo10);185 }186 187 {188 // nothing is common189 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 common207 MMRAMetadata Combined = MMRAMetadata::combine(Ctx, BarFoo0, Foo10);208 EXPECT_EQ(Combined, Foo10);209 }210}211 212} // namespace213