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