xref: /llvm-project/polly/unittests/DeLICM/DeLICMTest.cpp (revision d5ee355f89605f0475a18b60fd27837d73dd7852)
1c28c5846SMichael Kruse //===- DeLICMTest.cpp ----------------------------------------------------===//
2c28c5846SMichael Kruse //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c28c5846SMichael Kruse //
7c28c5846SMichael Kruse //===----------------------------------------------------------------------===//
8c28c5846SMichael Kruse 
9c28c5846SMichael Kruse #include "polly/DeLICM.h"
10046c9787STobias Grosser #include "polly/Support/ISLTools.h"
11c28c5846SMichael Kruse #include "gtest/gtest.h"
12c28c5846SMichael Kruse #include <isl/map.h>
13c28c5846SMichael Kruse #include <isl/set.h>
14c28c5846SMichael Kruse #include <isl/stream.h>
15c28c5846SMichael Kruse #include <isl/union_map.h>
16c28c5846SMichael Kruse #include <isl/union_set.h>
17c28c5846SMichael Kruse #include <memory>
18c28c5846SMichael Kruse 
19c28c5846SMichael Kruse using namespace llvm;
20c28c5846SMichael Kruse using namespace polly;
21c28c5846SMichael Kruse 
22c28c5846SMichael Kruse namespace {
23c28c5846SMichael Kruse 
24c28c5846SMichael Kruse /// Get the universes of all spaces in @p USet.
unionSpace(const isl::union_set & USet)25deaef15fSTobias Grosser isl::union_set unionSpace(const isl::union_set &USet) {
26bad3ebbaSRiccardo Mori   auto Result = isl::union_set::empty(USet.ctx());
27046c9787STobias Grosser   for (isl::set Set : USet.get_set_list()) {
28046c9787STobias Grosser     isl::space Space = Set.get_space();
29046c9787STobias Grosser     isl::set Universe = isl::set::universe(Space);
30b55aedd0Spatacca     Result = Result.unite(Universe);
31046c9787STobias Grosser   }
32c28c5846SMichael Kruse   return Result;
33c28c5846SMichael Kruse }
34c28c5846SMichael Kruse 
completeLifetime(isl::union_set Universe,isl::union_map OccupiedAndKnown,isl::union_set & Occupied,isl::union_map & Known,isl::union_set & Undef)35a8e885d8SMichael Kruse void completeLifetime(isl::union_set Universe, isl::union_map OccupiedAndKnown,
36a8e885d8SMichael Kruse                       isl::union_set &Occupied, isl::union_map &Known,
37deaef15fSTobias Grosser                       isl::union_set &Undef) {
380ba8c4a8STobias Grosser   auto ParamSpace = Universe.get_space();
39a8e885d8SMichael Kruse 
407c7978a1Spatacca   if (!Undef.is_null() && Occupied.is_null()) {
417c7978a1Spatacca     assert(Occupied.is_null());
420ba8c4a8STobias Grosser     Occupied = Universe.subtract(Undef);
43a8b0be81SMichael Kruse   }
44a8b0be81SMichael Kruse 
457c7978a1Spatacca   if (!OccupiedAndKnown.is_null()) {
467c7978a1Spatacca     assert(Known.is_null());
47a8e885d8SMichael Kruse 
48bad3ebbaSRiccardo Mori     Known = isl::union_map::empty(ParamSpace.ctx());
49a8b0be81SMichael Kruse 
507c7978a1Spatacca     if (Occupied.is_null())
51a8e885d8SMichael Kruse       Occupied = OccupiedAndKnown.domain();
52a8b0be81SMichael Kruse 
53046c9787STobias Grosser     for (isl::map Map : OccupiedAndKnown.get_map_list()) {
54d3d3d6b7STobias Grosser       if (!Map.has_tuple_name(isl::dim::out))
55046c9787STobias Grosser         continue;
56*d5ee355fSRiccardo Mori       Known = Known.unite(Map);
57046c9787STobias Grosser     }
58a8e885d8SMichael Kruse   }
59a8e885d8SMichael Kruse 
607c7978a1Spatacca   if (Undef.is_null()) {
617c7978a1Spatacca     assert(!Occupied.is_null());
620ba8c4a8STobias Grosser     Undef = Universe.subtract(Occupied);
63a8e885d8SMichael Kruse   }
64a8e885d8SMichael Kruse 
657c7978a1Spatacca   if (Known.is_null()) { // By default, nothing is known.
66bad3ebbaSRiccardo Mori     Known = isl::union_map::empty(ParamSpace.ctx());
67c28c5846SMichael Kruse   }
68b745b740SMichael Kruse 
69b745b740SMichael Kruse   // Conditions that must hold when returning.
707c7978a1Spatacca   assert(!Occupied.is_null());
717c7978a1Spatacca   assert(!Undef.is_null());
727c7978a1Spatacca   assert(!Known.is_null());
73c28c5846SMichael Kruse }
74c28c5846SMichael Kruse 
75c28c5846SMichael Kruse typedef struct {
76c28c5846SMichael Kruse   const char *OccupiedStr;
77c28c5846SMichael Kruse   const char *UndefStr;
78c28c5846SMichael Kruse   const char *WrittenStr;
795e645697SMichael Kruse } KnowledgeStr;
80c28c5846SMichael Kruse 
parseSetOrNull(isl_ctx * Ctx,const char * Str)810d106966SMichael Kruse isl::union_set parseSetOrNull(isl_ctx *Ctx, const char *Str) {
820d106966SMichael Kruse   if (!Str)
839b41d095Spatacca     return {};
840d106966SMichael Kruse   return isl::union_set(Ctx, Str);
850d106966SMichael Kruse }
860d106966SMichael Kruse 
parseMapOrNull(isl_ctx * Ctx,const char * Str)87a8e885d8SMichael Kruse isl::union_map parseMapOrNull(isl_ctx *Ctx, const char *Str) {
88a8e885d8SMichael Kruse   if (!Str)
899b41d095Spatacca     return {};
90a8e885d8SMichael Kruse   return isl::union_map(Ctx, Str);
91a8e885d8SMichael Kruse }
92a8e885d8SMichael Kruse 
checkIsConflictingNonsymmetricCommon(isl_ctx * Ctx,isl::union_map ExistingOccupiedAndKnown,isl::union_set ExistingUnused,isl::union_map ExistingWritten,isl::union_map ProposedOccupiedAndKnown,isl::union_set ProposedUnused,isl::union_map ProposedWritten)93a8e885d8SMichael Kruse bool checkIsConflictingNonsymmetricCommon(
94a8e885d8SMichael Kruse     isl_ctx *Ctx, isl::union_map ExistingOccupiedAndKnown,
95a8e885d8SMichael Kruse     isl::union_set ExistingUnused, isl::union_map ExistingWritten,
96a8e885d8SMichael Kruse     isl::union_map ProposedOccupiedAndKnown, isl::union_set ProposedUnused,
97a8e885d8SMichael Kruse     isl::union_map ProposedWritten) {
98a8e885d8SMichael Kruse   // Determine universe (set of all possible domains).
99bad3ebbaSRiccardo Mori   auto Universe = isl::union_set::empty(Ctx);
1007c7978a1Spatacca   if (!ExistingOccupiedAndKnown.is_null())
1010ba8c4a8STobias Grosser     Universe = Universe.unite(ExistingOccupiedAndKnown.domain());
1027c7978a1Spatacca   if (!ExistingUnused.is_null())
1030ba8c4a8STobias Grosser     Universe = Universe.unite(ExistingUnused);
1047c7978a1Spatacca   if (!ExistingWritten.is_null())
1050ba8c4a8STobias Grosser     Universe = Universe.unite(ExistingWritten.domain());
1067c7978a1Spatacca   if (!ProposedOccupiedAndKnown.is_null())
1070ba8c4a8STobias Grosser     Universe = Universe.unite(ProposedOccupiedAndKnown.domain());
1087c7978a1Spatacca   if (!ProposedUnused.is_null())
1090ba8c4a8STobias Grosser     Universe = Universe.unite(ProposedUnused);
1107c7978a1Spatacca   if (!ProposedWritten.is_null())
1110ba8c4a8STobias Grosser     Universe = Universe.unite(ProposedWritten.domain());
112a8e885d8SMichael Kruse 
113a8e885d8SMichael Kruse   Universe = unionSpace(Universe);
114a8e885d8SMichael Kruse 
115a8e885d8SMichael Kruse   // Add a space the universe that does not occur anywhere else to ensure
116a8e885d8SMichael Kruse   // robustness. Use &NewId to ensure that this Id is unique.
1170ba8c4a8STobias Grosser   isl::id NewId = isl::id::alloc(Ctx, "Unrelated", &NewId);
118a8e885d8SMichael Kruse   // The space must contains at least one dimension to allow order
119a8e885d8SMichael Kruse   // modifications.
1200ba8c4a8STobias Grosser   auto NewSpace = isl::space(Ctx, 0, 1);
1210ba8c4a8STobias Grosser   NewSpace = NewSpace.set_tuple_id(isl::dim::set, NewId);
1220ba8c4a8STobias Grosser   auto NewSet = isl::set::universe(NewSpace);
123b55aedd0Spatacca   Universe = Universe.unite(NewSet);
124a8e885d8SMichael Kruse 
125a8e885d8SMichael Kruse   // Using the universe, fill missing data.
126a8e885d8SMichael Kruse   isl::union_set ExistingOccupied;
127a8e885d8SMichael Kruse   isl::union_map ExistingKnown;
128a8e885d8SMichael Kruse   completeLifetime(Universe, ExistingOccupiedAndKnown, ExistingOccupied,
129a8e885d8SMichael Kruse                    ExistingKnown, ExistingUnused);
130a8e885d8SMichael Kruse 
131a8e885d8SMichael Kruse   isl::union_set ProposedOccupied;
132a8e885d8SMichael Kruse   isl::union_map ProposedKnown;
133a8e885d8SMichael Kruse   completeLifetime(Universe, ProposedOccupiedAndKnown, ProposedOccupied,
134a8e885d8SMichael Kruse                    ProposedKnown, ProposedUnused);
135a8e885d8SMichael Kruse 
136a8e885d8SMichael Kruse   auto Result = isConflicting(ExistingOccupied, ExistingUnused, ExistingKnown,
137a8e885d8SMichael Kruse                               ExistingWritten, ProposedOccupied, ProposedUnused,
138a8e885d8SMichael Kruse                               ProposedKnown, ProposedWritten);
139a8e885d8SMichael Kruse 
140a8e885d8SMichael Kruse   // isConflicting does not require ExistingOccupied nor ProposedUnused and are
141a8e885d8SMichael Kruse   // implicitly assumed to be the remainder elements. Test the implicitness as
142a8e885d8SMichael Kruse   // well.
143a8e885d8SMichael Kruse   EXPECT_EQ(Result,
144a8e885d8SMichael Kruse             isConflicting(ExistingOccupied, ExistingUnused, ExistingKnown,
145a8e885d8SMichael Kruse                           ExistingWritten, ProposedOccupied, {}, ProposedKnown,
146a8e885d8SMichael Kruse                           ProposedWritten));
147a8e885d8SMichael Kruse   EXPECT_EQ(Result,
148a8e885d8SMichael Kruse             isConflicting({}, ExistingUnused, ExistingKnown, ExistingWritten,
149a8e885d8SMichael Kruse                           ProposedOccupied, ProposedUnused, ProposedKnown,
150a8e885d8SMichael Kruse                           ProposedWritten));
151a8e885d8SMichael Kruse   EXPECT_EQ(Result, isConflicting({}, ExistingUnused, ExistingKnown,
152a8e885d8SMichael Kruse                                   ExistingWritten, ProposedOccupied, {},
153a8e885d8SMichael Kruse                                   ProposedKnown, ProposedWritten));
154a8e885d8SMichael Kruse 
155a8e885d8SMichael Kruse   return Result;
156a8e885d8SMichael Kruse }
157a8e885d8SMichael Kruse 
checkIsConflictingNonsymmetricKnown(KnowledgeStr Existing,KnowledgeStr Proposed)158a8e885d8SMichael Kruse bool checkIsConflictingNonsymmetricKnown(KnowledgeStr Existing,
159a8e885d8SMichael Kruse                                          KnowledgeStr Proposed) {
160a8e885d8SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
161a8e885d8SMichael Kruse                                                         &isl_ctx_free);
162a8e885d8SMichael Kruse 
163a8e885d8SMichael Kruse   // Parse knowledge.
164a8e885d8SMichael Kruse   auto ExistingOccupiedAndKnown =
165a8e885d8SMichael Kruse       parseMapOrNull(Ctx.get(), Existing.OccupiedStr);
166a8e885d8SMichael Kruse   auto ExistingUnused = parseSetOrNull(Ctx.get(), Existing.UndefStr);
167a8e885d8SMichael Kruse   auto ExistingWritten = parseMapOrNull(Ctx.get(), Existing.WrittenStr);
168a8e885d8SMichael Kruse 
169a8e885d8SMichael Kruse   auto ProposedOccupiedAndKnown =
170a8e885d8SMichael Kruse       parseMapOrNull(Ctx.get(), Proposed.OccupiedStr);
171a8e885d8SMichael Kruse   auto ProposedUnused = parseSetOrNull(Ctx.get(), Proposed.UndefStr);
172a8e885d8SMichael Kruse   auto ProposedWritten = parseMapOrNull(Ctx.get(), Proposed.WrittenStr);
173a8e885d8SMichael Kruse 
174a8e885d8SMichael Kruse   return checkIsConflictingNonsymmetricCommon(
175a8e885d8SMichael Kruse       Ctx.get(), ExistingOccupiedAndKnown, ExistingUnused, ExistingWritten,
176a8e885d8SMichael Kruse       ProposedOccupiedAndKnown, ProposedUnused, ProposedWritten);
177a8e885d8SMichael Kruse }
178a8e885d8SMichael Kruse 
checkIsConflictingNonsymmetric(KnowledgeStr Existing,KnowledgeStr Proposed)1795e645697SMichael Kruse bool checkIsConflictingNonsymmetric(KnowledgeStr Existing,
1805e645697SMichael Kruse                                     KnowledgeStr Proposed) {
181c28c5846SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
182c28c5846SMichael Kruse                                                         &isl_ctx_free);
183c28c5846SMichael Kruse 
184c28c5846SMichael Kruse   // Parse knowledge.
1850d106966SMichael Kruse   auto ExistingOccupied = parseSetOrNull(Ctx.get(), Existing.OccupiedStr);
1860d106966SMichael Kruse   auto ExistingUnused = parseSetOrNull(Ctx.get(), Existing.UndefStr);
1870d106966SMichael Kruse   auto ExistingWritten = parseSetOrNull(Ctx.get(), Existing.WrittenStr);
188c28c5846SMichael Kruse 
1890d106966SMichael Kruse   auto ProposedOccupied = parseSetOrNull(Ctx.get(), Proposed.OccupiedStr);
1900d106966SMichael Kruse   auto ProposedUnused = parseSetOrNull(Ctx.get(), Proposed.UndefStr);
1910d106966SMichael Kruse   auto ProposedWritten = parseSetOrNull(Ctx.get(), Proposed.WrittenStr);
192c28c5846SMichael Kruse 
193a8e885d8SMichael Kruse   return checkIsConflictingNonsymmetricCommon(
19472018edaSTobias Grosser       Ctx.get(), isl::union_map::from_domain(ExistingOccupied), ExistingUnused,
195da3e8c4bSTobias Grosser       isl::union_map::from_domain(ExistingWritten),
19672018edaSTobias Grosser       isl::union_map::from_domain(ProposedOccupied), ProposedUnused,
197da3e8c4bSTobias Grosser       isl::union_map::from_domain(ProposedWritten));
198c28c5846SMichael Kruse }
199c28c5846SMichael Kruse 
checkIsConflicting(KnowledgeStr Existing,KnowledgeStr Proposed)2005e645697SMichael Kruse bool checkIsConflicting(KnowledgeStr Existing, KnowledgeStr Proposed) {
201c28c5846SMichael Kruse   auto Forward = checkIsConflictingNonsymmetric(Existing, Proposed);
202c28c5846SMichael Kruse   auto Backward = checkIsConflictingNonsymmetric(Proposed, Existing);
203c28c5846SMichael Kruse 
204c28c5846SMichael Kruse   // isConflicting should be symmetric.
205c28c5846SMichael Kruse   EXPECT_EQ(Forward, Backward);
206c28c5846SMichael Kruse 
207c28c5846SMichael Kruse   return Forward || Backward;
208c28c5846SMichael Kruse }
209c28c5846SMichael Kruse 
checkIsConflictingKnown(KnowledgeStr Existing,KnowledgeStr Proposed)210a8e885d8SMichael Kruse bool checkIsConflictingKnown(KnowledgeStr Existing, KnowledgeStr Proposed) {
211a8e885d8SMichael Kruse   auto Forward = checkIsConflictingNonsymmetricKnown(Existing, Proposed);
212a8e885d8SMichael Kruse   auto Backward = checkIsConflictingNonsymmetricKnown(Proposed, Existing);
213a8e885d8SMichael Kruse 
214a8e885d8SMichael Kruse   // checkIsConflictingKnown should be symmetric.
215a8e885d8SMichael Kruse   EXPECT_EQ(Forward, Backward);
216a8e885d8SMichael Kruse 
217a8e885d8SMichael Kruse   return Forward || Backward;
218a8e885d8SMichael Kruse }
219a8e885d8SMichael Kruse 
TEST(DeLICM,isConflicting)220c28c5846SMichael Kruse TEST(DeLICM, isConflicting) {
221c28c5846SMichael Kruse 
222c28c5846SMichael Kruse   // Check occupied vs. occupied.
223c28c5846SMichael Kruse   EXPECT_TRUE(
224c28c5846SMichael Kruse       checkIsConflicting({"{ Dom[i] }", nullptr, "{}"}, {nullptr, "{}", "{}"}));
225c28c5846SMichael Kruse   EXPECT_TRUE(checkIsConflicting({"{ Dom[i] }", nullptr, "{}"},
226c28c5846SMichael Kruse                                  {"{ Dom[i] }", nullptr, "{}"}));
227c28c5846SMichael Kruse   EXPECT_FALSE(checkIsConflicting({"{ Dom[0] }", nullptr, "{}"},
228c28c5846SMichael Kruse                                   {nullptr, "{ Dom[0] }", "{}"}));
229c28c5846SMichael Kruse   EXPECT_FALSE(checkIsConflicting({"{ Dom[i] : i != 0 }", nullptr, "{}"},
230c28c5846SMichael Kruse                                   {"{ Dom[0] }", nullptr, "{}"}));
231c28c5846SMichael Kruse 
232cd2be66bSMichael Kruse   // Check occupied vs. occupied with known values.
233cd2be66bSMichael Kruse   EXPECT_FALSE(checkIsConflictingKnown({"{ Dom[i] -> Val[] }", nullptr, "{}"},
234cd2be66bSMichael Kruse                                        {"{ Dom[i] -> Val[] }", nullptr, "{}"}));
235cd2be66bSMichael Kruse   EXPECT_TRUE(checkIsConflictingKnown({"{ Dom[i] -> ValA[] }", nullptr, "{}"},
236cd2be66bSMichael Kruse                                       {"{ Dom[i] -> ValB[] }", nullptr, "{}"}));
237cd2be66bSMichael Kruse   EXPECT_TRUE(checkIsConflictingKnown({"{ Dom[i] -> Val[] }", nullptr, "{}"},
238cd2be66bSMichael Kruse                                       {"{ Dom[i] -> [] }", nullptr, "{}"}));
239cd2be66bSMichael Kruse   EXPECT_FALSE(checkIsConflictingKnown({"{ Dom[0] -> Val[] }", nullptr, "{}"},
240cd2be66bSMichael Kruse                                        {nullptr, "{ Dom[0] }", "{}"}));
2418080011cSMichael Kruse   EXPECT_FALSE(checkIsConflictingKnown(
2428080011cSMichael Kruse       {"{ Dom[i] -> Val[]; Dom[i] -> Phi[] }", nullptr, "{}"},
2438080011cSMichael Kruse       {"{ Dom[i] -> Val[] }", nullptr, "{}"}));
244cd2be66bSMichael Kruse 
245cd2be66bSMichael Kruse   // An implementation using subtract would have exponential runtime on patterns
246cd2be66bSMichael Kruse   // such as this one.
247cd2be66bSMichael Kruse   EXPECT_TRUE(checkIsConflictingKnown(
248cd2be66bSMichael Kruse       {"{ Dom[i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15]"
249cd2be66bSMichael Kruse        "-> Val[] }",
250cd2be66bSMichael Kruse        nullptr, "{}"},
251cd2be66bSMichael Kruse       {"[p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,q0,"
252cd2be66bSMichael Kruse        "q1,q2,q3,q4,q5,q6,q7,q8,q9,q10,q11,q12,q13,q14,q15] -> {"
253cd2be66bSMichael Kruse        "Dom[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] -> Val[];"
254cd2be66bSMichael Kruse        "Dom[p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15] -> Val[];"
255cd2be66bSMichael Kruse        "Dom[q0,q1,q2,q3,q4,q5,q6,q7,q8,q9,q10,q11,q12,q13,q14,q15] -> Val[] }",
256cd2be66bSMichael Kruse        "{}", "{}"}));
257cd2be66bSMichael Kruse 
258c28c5846SMichael Kruse   // Check occupied vs. written.
259c28c5846SMichael Kruse   EXPECT_TRUE(
260c28c5846SMichael Kruse       checkIsConflicting({nullptr, "{}", "{}"}, {"{}", nullptr, "{ Dom[0] }"}));
261c28c5846SMichael Kruse   EXPECT_FALSE(
262c28c5846SMichael Kruse       checkIsConflicting({"{}", nullptr, "{}"}, {"{}", nullptr, "{ Dom[0] }"}));
263c28c5846SMichael Kruse 
264c28c5846SMichael Kruse   EXPECT_TRUE(checkIsConflicting({"{ Dom[i] }", nullptr, "{}"},
265c28c5846SMichael Kruse                                  {"{}", nullptr, "{ Dom[0] }"}));
266c28c5846SMichael Kruse   EXPECT_FALSE(checkIsConflicting({"{ DomA[i] }", nullptr, "{}"},
267c28c5846SMichael Kruse                                   {"{}", nullptr, "{ DomB[0] }"}));
268c28c5846SMichael Kruse 
269c28c5846SMichael Kruse   // Dom[1] represents the time between 0 and 1. Now Proposed writes at timestep
270c28c5846SMichael Kruse   // 0 such that will have a different value between 0 and 1. Hence it is
271c28c5846SMichael Kruse   // conflicting with Existing.
272c28c5846SMichael Kruse   EXPECT_TRUE(checkIsConflicting({"{ Dom[1] }", nullptr, "{}"},
273c28c5846SMichael Kruse                                  {"{}", nullptr, "{ Dom[0] }"}));
274c28c5846SMichael Kruse   EXPECT_FALSE(checkIsConflicting({"{ Dom[i] : i != 1 }", nullptr, "{}"},
275c28c5846SMichael Kruse                                   {"{}", nullptr, "{ Dom[0] }"}));
276c28c5846SMichael Kruse 
2773e519b94SMichael Kruse   // Check occupied vs. written with known values.
2783e519b94SMichael Kruse   EXPECT_FALSE(checkIsConflictingKnown({"{ Dom[i] -> Val[] }", nullptr, "{}"},
2793e519b94SMichael Kruse                                        {"{}", nullptr, "{ Dom[0] -> Val[] }"}));
2803e519b94SMichael Kruse   EXPECT_TRUE(checkIsConflictingKnown({"{ Dom[i] -> ValA[] }", nullptr, "{}"},
2813e519b94SMichael Kruse                                       {"{}", nullptr, "{ Dom[0] -> ValB[] }"}));
2823e519b94SMichael Kruse   EXPECT_TRUE(checkIsConflictingKnown({"{ Dom[i] -> Val[] }", nullptr, "{}"},
2833e519b94SMichael Kruse                                       {"{}", nullptr, "{ Dom[0] -> [] }"}));
2843e519b94SMichael Kruse   EXPECT_TRUE(checkIsConflictingKnown({"{ Dom[i] -> [] }", nullptr, "{}"},
2853e519b94SMichael Kruse                                       {"{}", nullptr, "{ Dom[0] -> Val[] }"}));
2863e519b94SMichael Kruse 
2873e519b94SMichael Kruse   // The same value can be known under multiple names, for instance a PHINode
2883e519b94SMichael Kruse   // has the same value as one of the incoming values. One matching pair
2893e519b94SMichael Kruse   // suffices.
2903e519b94SMichael Kruse   EXPECT_FALSE(checkIsConflictingKnown(
2913e519b94SMichael Kruse       {"{ Dom[i] -> Val[]; Dom[i] -> Phi[] }", nullptr, "{}"},
2923e519b94SMichael Kruse       {"{}", nullptr, "{ Dom[0] -> Val[] }"}));
2933e519b94SMichael Kruse   EXPECT_FALSE(checkIsConflictingKnown(
2943e519b94SMichael Kruse       {"{ Dom[i] -> Val[] }", nullptr, "{}"},
2953e519b94SMichael Kruse       {"{}", nullptr, "{ Dom[0] -> Val[]; Dom[0] -> Phi[] }"}));
2963e519b94SMichael Kruse 
297c28c5846SMichael Kruse   // Check written vs. written.
298c28c5846SMichael Kruse   EXPECT_TRUE(checkIsConflicting({"{}", nullptr, "{ Dom[0] }"},
299c28c5846SMichael Kruse                                  {"{}", nullptr, "{ Dom[0] }"}));
300c28c5846SMichael Kruse   EXPECT_FALSE(checkIsConflicting({"{}", nullptr, "{ Dom[-1] }"},
301c28c5846SMichael Kruse                                   {"{}", nullptr, "{ Dom[0] }"}));
302c28c5846SMichael Kruse   EXPECT_FALSE(checkIsConflicting({"{}", nullptr, "{ Dom[1] }"},
303c28c5846SMichael Kruse                                   {"{}", nullptr, "{ Dom[0] }"}));
3048431e996SMichael Kruse 
3058431e996SMichael Kruse   // Check written vs. written with known values.
3068431e996SMichael Kruse   EXPECT_FALSE(checkIsConflictingKnown({"{}", nullptr, "{ Dom[0] -> Val[] }"},
3078431e996SMichael Kruse                                        {"{}", nullptr, "{ Dom[0] -> Val[] }"}));
3088431e996SMichael Kruse   EXPECT_TRUE(checkIsConflictingKnown({"{}", nullptr, "{ Dom[0] -> ValA[] }"},
3098431e996SMichael Kruse                                       {"{}", nullptr, "{ Dom[0] -> ValB[] }"}));
3108431e996SMichael Kruse   EXPECT_TRUE(checkIsConflictingKnown({"{}", nullptr, "{ Dom[0] -> Val[] }"},
3118431e996SMichael Kruse                                       {"{}", nullptr, "{ Dom[0] -> [] }"}));
312e6d2bebbSMichael Kruse   EXPECT_FALSE(checkIsConflictingKnown(
313e6d2bebbSMichael Kruse       {"{}", nullptr, "{ Dom[0] -> Val[]}"},
314e6d2bebbSMichael Kruse       {"{}", nullptr, "{ Dom[0] -> Val[]; Dom[0] -> Phi[] }"}));
315c28c5846SMichael Kruse }
316c28c5846SMichael Kruse } // anonymous namespace
317