xref: /llvm-project/polly/unittests/Isl/IslTest.cpp (revision 5e111eb275eee3bec1123b4b85606328017e5ee5)
105cf9c22SMichael Kruse //===- IslTest.cpp ----------------------------------------------------===//
205cf9c22SMichael 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
605cf9c22SMichael Kruse //
705cf9c22SMichael Kruse //===----------------------------------------------------------------------===//
805cf9c22SMichael Kruse 
905cf9c22SMichael Kruse #include "polly/Support/GICHelper.h"
10be483ae6STobias Grosser #include "polly/Support/ISLOperators.h"
11d1508812SMichael Kruse #include "polly/Support/ISLTools.h"
1205cf9c22SMichael Kruse #include "gtest/gtest.h"
13d1508812SMichael Kruse #include "isl/stream.h"
1405cf9c22SMichael Kruse #include "isl/val.h"
1505cf9c22SMichael Kruse 
1605cf9c22SMichael Kruse using namespace llvm;
1705cf9c22SMichael Kruse using namespace polly;
1805cf9c22SMichael Kruse 
parseSpace(isl_ctx * Ctx,const char * Str)19deaef15fSTobias Grosser static isl::space parseSpace(isl_ctx *Ctx, const char *Str) {
20d1508812SMichael Kruse   isl_stream *Stream = isl_stream_new_str(Ctx, Str);
21d1508812SMichael Kruse   auto Obj = isl_stream_read_obj(Stream);
22d1508812SMichael Kruse 
23deaef15fSTobias Grosser   isl::space Result;
24d1508812SMichael Kruse   if (Obj.type == isl_obj_set)
250ba8c4a8STobias Grosser     Result = isl::manage(isl_set_get_space(static_cast<isl_set *>(Obj.v)));
26d1508812SMichael Kruse   else if (Obj.type == isl_obj_map)
270ba8c4a8STobias Grosser     Result = isl::manage(isl_map_get_space(static_cast<isl_map *>(Obj.v)));
28d1508812SMichael Kruse 
29d1508812SMichael Kruse   isl_stream_free(Stream);
30d1508812SMichael Kruse   if (Obj.type)
31d1508812SMichael Kruse     Obj.type->free(Obj.v);
32d1508812SMichael Kruse   return Result;
33d1508812SMichael Kruse }
34d1508812SMichael Kruse 
35d1508812SMichael Kruse #define SPACE(Str) parseSpace(Ctx.get(), Str)
36d1508812SMichael Kruse 
373cc57fa1STobias Grosser #define SET(Str) isl::set(Ctx.get(), Str)
383cc57fa1STobias Grosser #define MAP(Str) isl::map(Ctx.get(), Str)
39d1508812SMichael Kruse 
403cc57fa1STobias Grosser #define USET(Str) isl::union_set(Ctx.get(), Str)
413cc57fa1STobias Grosser #define UMAP(Str) isl::union_map(Ctx.get(), Str)
42d1508812SMichael Kruse 
43deaef15fSTobias Grosser namespace isl {
44deaef15fSTobias Grosser inline namespace noexceptions {
45deaef15fSTobias Grosser 
operator ==(const isl::space & LHS,const isl::space & RHS)46deaef15fSTobias Grosser static bool operator==(const isl::space &LHS, const isl::space &RHS) {
473cc57fa1STobias Grosser   return bool(LHS.is_equal(RHS));
483cc57fa1STobias Grosser }
493cc57fa1STobias Grosser 
operator ==(const isl::set & LHS,const isl::set & RHS)50deaef15fSTobias Grosser static bool operator==(const isl::set &LHS, const isl::set &RHS) {
513cc57fa1STobias Grosser   return bool(LHS.is_equal(RHS));
523cc57fa1STobias Grosser }
533cc57fa1STobias Grosser 
operator ==(const isl::map & LHS,const isl::map & RHS)54deaef15fSTobias Grosser static bool operator==(const isl::map &LHS, const isl::map &RHS) {
553cc57fa1STobias Grosser   return bool(LHS.is_equal(RHS));
56d1508812SMichael Kruse }
57d1508812SMichael Kruse 
operator ==(const isl::union_set & LHS,const isl::union_set & RHS)58deaef15fSTobias Grosser static bool operator==(const isl::union_set &LHS, const isl::union_set &RHS) {
593cc57fa1STobias Grosser   return bool(LHS.is_equal(RHS));
60d1508812SMichael Kruse }
61d1508812SMichael Kruse 
operator ==(const isl::union_map & LHS,const isl::union_map & RHS)62deaef15fSTobias Grosser static bool operator==(const isl::union_map &LHS, const isl::union_map &RHS) {
633cc57fa1STobias Grosser   return bool(LHS.is_equal(RHS));
643cc57fa1STobias Grosser }
653cc57fa1STobias Grosser 
operator ==(const isl::val & LHS,const isl::val & RHS)663cc57fa1STobias Grosser static bool operator==(const isl::val &LHS, const isl::val &RHS) {
673cc57fa1STobias Grosser   return bool(LHS.eq(RHS));
68d1508812SMichael Kruse }
69a1da86b2STobias Grosser 
operator ==(const isl::pw_aff & LHS,const isl::pw_aff & RHS)70be483ae6STobias Grosser static bool operator==(const isl::pw_aff &LHS, const isl::pw_aff &RHS) {
71be483ae6STobias Grosser   return bool(LHS.is_equal(RHS));
72be483ae6STobias Grosser }
73deaef15fSTobias Grosser } // namespace noexceptions
74deaef15fSTobias Grosser } // namespace isl
75d1508812SMichael Kruse 
7605cf9c22SMichael Kruse namespace {
7705cf9c22SMichael Kruse 
TEST(Isl,APIntToIslVal)7805cf9c22SMichael Kruse TEST(Isl, APIntToIslVal) {
7905cf9c22SMichael Kruse   isl_ctx *IslCtx = isl_ctx_alloc();
8005cf9c22SMichael Kruse 
8105cf9c22SMichael Kruse   {
8243720008STobias Grosser     APInt APZero(1, 0, true);
833cc57fa1STobias Grosser     auto IslZero = valFromAPInt(IslCtx, APZero, true);
843cc57fa1STobias Grosser     EXPECT_TRUE(IslZero.is_zero());
8543720008STobias Grosser   }
8643720008STobias Grosser 
8743720008STobias Grosser   {
8843720008STobias Grosser     APInt APNOne(1, -1, true);
893cc57fa1STobias Grosser     auto IslNOne = valFromAPInt(IslCtx, APNOne, true);
903cc57fa1STobias Grosser     EXPECT_TRUE(IslNOne.is_negone());
9143720008STobias Grosser   }
9243720008STobias Grosser 
9343720008STobias Grosser   {
9443720008STobias Grosser     APInt APZero(1, 0, false);
953cc57fa1STobias Grosser     auto IslZero = valFromAPInt(IslCtx, APZero, false);
963cc57fa1STobias Grosser     EXPECT_TRUE(IslZero.is_zero());
9743720008STobias Grosser   }
9843720008STobias Grosser 
9943720008STobias Grosser   {
10043720008STobias Grosser     APInt APOne(1, 1, false);
1013cc57fa1STobias Grosser     auto IslOne = valFromAPInt(IslCtx, APOne, false);
1023cc57fa1STobias Grosser     EXPECT_TRUE(IslOne.is_one());
10343720008STobias Grosser   }
10443720008STobias Grosser 
10543720008STobias Grosser   {
10643720008STobias Grosser     APInt APNTwo(2, -2, true);
1073cc57fa1STobias Grosser     auto IslNTwo = valFromAPInt(IslCtx, APNTwo, true);
1083cc57fa1STobias Grosser     auto IslNTwoCmp = isl::val(IslCtx, -2);
1093cc57fa1STobias Grosser     EXPECT_EQ(IslNTwo, IslNTwoCmp);
11043720008STobias Grosser   }
11143720008STobias Grosser 
11243720008STobias Grosser   {
11305cf9c22SMichael Kruse     APInt APNOne(32, -1, true);
1143cc57fa1STobias Grosser     auto IslNOne = valFromAPInt(IslCtx, APNOne, true);
1153cc57fa1STobias Grosser     EXPECT_TRUE(IslNOne.is_negone());
11605cf9c22SMichael Kruse   }
11705cf9c22SMichael Kruse 
11805cf9c22SMichael Kruse   {
11905cf9c22SMichael Kruse     APInt APZero(32, 0, false);
1203cc57fa1STobias Grosser     auto IslZero = valFromAPInt(IslCtx, APZero, false);
1213cc57fa1STobias Grosser     EXPECT_TRUE(IslZero.is_zero());
12205cf9c22SMichael Kruse   }
12305cf9c22SMichael Kruse 
12405cf9c22SMichael Kruse   {
12505cf9c22SMichael Kruse     APInt APOne(32, 1, false);
1263cc57fa1STobias Grosser     auto IslOne = valFromAPInt(IslCtx, APOne, false);
1273cc57fa1STobias Grosser     EXPECT_TRUE(IslOne.is_one());
12805cf9c22SMichael Kruse   }
12905cf9c22SMichael Kruse 
13005cf9c22SMichael Kruse   {
13105cf9c22SMichael Kruse     APInt APTwo(32, 2, false);
1323cc57fa1STobias Grosser     auto IslTwo = valFromAPInt(IslCtx, APTwo, false);
1333cc57fa1STobias Grosser     EXPECT_EQ(0, IslTwo.cmp_si(2));
13405cf9c22SMichael Kruse   }
13505cf9c22SMichael Kruse 
13605cf9c22SMichael Kruse   {
13705cf9c22SMichael Kruse     APInt APNOne(32, (1ull << 32) - 1, false);
1383cc57fa1STobias Grosser     auto IslNOne = valFromAPInt(IslCtx, APNOne, false);
139ce8272afSRiccardo Mori     auto IslRef = isl::val(IslCtx, 32).pow2().sub(1);
1403cc57fa1STobias Grosser     EXPECT_EQ(IslNOne, IslRef);
14105cf9c22SMichael Kruse   }
14205cf9c22SMichael Kruse 
14343720008STobias Grosser   {
14443720008STobias Grosser     APInt APLarge(130, 2, false);
14543720008STobias Grosser     APLarge = APLarge.shl(70);
1463cc57fa1STobias Grosser     auto IslLarge = valFromAPInt(IslCtx, APLarge, false);
1473cc57fa1STobias Grosser     auto IslRef = isl::val(IslCtx, 71);
1487164b7d3STobias Grosser     IslRef = IslRef.pow2();
1493cc57fa1STobias Grosser     EXPECT_EQ(IslLarge, IslRef);
15043720008STobias Grosser   }
15143720008STobias Grosser 
15205cf9c22SMichael Kruse   isl_ctx_free(IslCtx);
15305cf9c22SMichael Kruse }
15405cf9c22SMichael Kruse 
TEST(Isl,IslValToAPInt)15505cf9c22SMichael Kruse TEST(Isl, IslValToAPInt) {
15605cf9c22SMichael Kruse   isl_ctx *IslCtx = isl_ctx_alloc();
15705cf9c22SMichael Kruse 
15805cf9c22SMichael Kruse   {
1593cc57fa1STobias Grosser     auto IslNOne = isl::val(IslCtx, -1);
16005cf9c22SMichael Kruse     auto APNOne = APIntFromVal(IslNOne);
16176f8279eSTobias Grosser     // Compare with the two's complement of -1 in a 1-bit integer.
162aa6eb5cdSTobias Grosser     EXPECT_EQ(1, APNOne);
163aa6eb5cdSTobias Grosser     EXPECT_EQ(1u, APNOne.getBitWidth());
16476f8279eSTobias Grosser   }
16576f8279eSTobias Grosser 
16676f8279eSTobias Grosser   {
1673cc57fa1STobias Grosser     auto IslNTwo = isl::val(IslCtx, -2);
16876f8279eSTobias Grosser     auto APNTwo = APIntFromVal(IslNTwo);
16976f8279eSTobias Grosser     // Compare with the two's complement of -2 in a 2-bit integer.
170aa6eb5cdSTobias Grosser     EXPECT_EQ(2, APNTwo);
171aa6eb5cdSTobias Grosser     EXPECT_EQ(2u, APNTwo.getBitWidth());
17276f8279eSTobias Grosser   }
17376f8279eSTobias Grosser 
17476f8279eSTobias Grosser   {
1753cc57fa1STobias Grosser     auto IslNThree = isl::val(IslCtx, -3);
17676f8279eSTobias Grosser     auto APNThree = APIntFromVal(IslNThree);
17776f8279eSTobias Grosser     // Compare with the two's complement of -3 in a 3-bit integer.
178aa6eb5cdSTobias Grosser     EXPECT_EQ(5, APNThree);
179aa6eb5cdSTobias Grosser     EXPECT_EQ(3u, APNThree.getBitWidth());
18076f8279eSTobias Grosser   }
18176f8279eSTobias Grosser 
18276f8279eSTobias Grosser   {
1833cc57fa1STobias Grosser     auto IslNFour = isl::val(IslCtx, -4);
18476f8279eSTobias Grosser     auto APNFour = APIntFromVal(IslNFour);
18576f8279eSTobias Grosser     // Compare with the two's complement of -4 in a 3-bit integer.
186aa6eb5cdSTobias Grosser     EXPECT_EQ(4, APNFour);
187aa6eb5cdSTobias Grosser     EXPECT_EQ(3u, APNFour.getBitWidth());
18805cf9c22SMichael Kruse   }
18905cf9c22SMichael Kruse 
19005cf9c22SMichael Kruse   {
1913cc57fa1STobias Grosser     auto IslZero = isl::val(IslCtx, 0);
19205cf9c22SMichael Kruse     auto APZero = APIntFromVal(IslZero);
193aa6eb5cdSTobias Grosser     EXPECT_EQ(0, APZero);
194aa6eb5cdSTobias Grosser     EXPECT_EQ(1u, APZero.getBitWidth());
19505cf9c22SMichael Kruse   }
19605cf9c22SMichael Kruse 
19705cf9c22SMichael Kruse   {
1983cc57fa1STobias Grosser     auto IslOne = isl::val(IslCtx, 1);
19905cf9c22SMichael Kruse     auto APOne = APIntFromVal(IslOne);
200aa6eb5cdSTobias Grosser     EXPECT_EQ(1, APOne);
201aa6eb5cdSTobias Grosser     EXPECT_EQ(2u, APOne.getBitWidth());
20205cf9c22SMichael Kruse   }
20305cf9c22SMichael Kruse 
20405cf9c22SMichael Kruse   {
2053cc57fa1STobias Grosser     auto IslTwo = isl::val(IslCtx, 2);
20605cf9c22SMichael Kruse     auto APTwo = APIntFromVal(IslTwo);
207aa6eb5cdSTobias Grosser     EXPECT_EQ(2, APTwo);
208aa6eb5cdSTobias Grosser     EXPECT_EQ(3u, APTwo.getBitWidth());
20976f8279eSTobias Grosser   }
21076f8279eSTobias Grosser 
21176f8279eSTobias Grosser   {
2123cc57fa1STobias Grosser     auto IslThree = isl::val(IslCtx, 3);
21376f8279eSTobias Grosser     auto APThree = APIntFromVal(IslThree);
214aa6eb5cdSTobias Grosser     EXPECT_EQ(3, APThree);
215aa6eb5cdSTobias Grosser     EXPECT_EQ(3u, APThree.getBitWidth());
21676f8279eSTobias Grosser   }
21776f8279eSTobias Grosser 
21876f8279eSTobias Grosser   {
2193cc57fa1STobias Grosser     auto IslFour = isl::val(IslCtx, 4);
22076f8279eSTobias Grosser     auto APFour = APIntFromVal(IslFour);
221aa6eb5cdSTobias Grosser     EXPECT_EQ(4, APFour);
222aa6eb5cdSTobias Grosser     EXPECT_EQ(4u, APFour.getBitWidth());
22305cf9c22SMichael Kruse   }
22405cf9c22SMichael Kruse 
22505cf9c22SMichael Kruse   {
226ce8272afSRiccardo Mori     auto IslNOne = isl::val(IslCtx, 32).pow2().sub(1);
22705cf9c22SMichael Kruse     auto APNOne = APIntFromVal(IslNOne);
228aa6eb5cdSTobias Grosser     EXPECT_EQ((1ull << 32) - 1, APNOne);
229aa6eb5cdSTobias Grosser     EXPECT_EQ(33u, APNOne.getBitWidth());
23076f8279eSTobias Grosser   }
23176f8279eSTobias Grosser 
23276f8279eSTobias Grosser   {
2333cc57fa1STobias Grosser     auto IslLargeNum = isl::val(IslCtx, 60);
2347164b7d3STobias Grosser     IslLargeNum = IslLargeNum.pow2();
235ce8272afSRiccardo Mori     IslLargeNum = IslLargeNum.sub(1);
23676f8279eSTobias Grosser     auto APLargeNum = APIntFromVal(IslLargeNum);
237aa6eb5cdSTobias Grosser     EXPECT_EQ((1ull << 60) - 1, APLargeNum);
238aa6eb5cdSTobias Grosser     EXPECT_EQ(61u, APLargeNum.getBitWidth());
23976f8279eSTobias Grosser   }
24076f8279eSTobias Grosser 
24176f8279eSTobias Grosser   {
2423cc57fa1STobias Grosser     auto IslExp = isl::val(IslCtx, 500);
2437164b7d3STobias Grosser     auto IslLargePow2 = IslExp.pow2();
24476f8279eSTobias Grosser     auto APLargePow2 = APIntFromVal(IslLargePow2);
24576f8279eSTobias Grosser     EXPECT_TRUE(APLargePow2.isPowerOf2());
246aa6eb5cdSTobias Grosser     EXPECT_EQ(502u, APLargePow2.getBitWidth());
247*5e111eb2SKazu Hirata     EXPECT_EQ(502u, APLargePow2.getSignificantBits());
24876f8279eSTobias Grosser   }
24976f8279eSTobias Grosser 
25076f8279eSTobias Grosser   {
2513cc57fa1STobias Grosser     auto IslExp = isl::val(IslCtx, 500);
2527164b7d3STobias Grosser     auto IslLargeNPow2 = IslExp.pow2().neg();
25376f8279eSTobias Grosser     auto APLargeNPow2 = APIntFromVal(IslLargeNPow2);
254aa6eb5cdSTobias Grosser     EXPECT_EQ(501u, APLargeNPow2.getBitWidth());
255*5e111eb2SKazu Hirata     EXPECT_EQ(501u, APLargeNPow2.getSignificantBits());
256aa6eb5cdSTobias Grosser     EXPECT_EQ(500, (-APLargeNPow2).exactLogBase2());
25776f8279eSTobias Grosser   }
25876f8279eSTobias Grosser 
25976f8279eSTobias Grosser   {
2603cc57fa1STobias Grosser     auto IslExp = isl::val(IslCtx, 512);
2617164b7d3STobias Grosser     auto IslLargePow2 = IslExp.pow2();
26276f8279eSTobias Grosser     auto APLargePow2 = APIntFromVal(IslLargePow2);
26376f8279eSTobias Grosser     EXPECT_TRUE(APLargePow2.isPowerOf2());
264aa6eb5cdSTobias Grosser     EXPECT_EQ(514u, APLargePow2.getBitWidth());
265*5e111eb2SKazu Hirata     EXPECT_EQ(514u, APLargePow2.getSignificantBits());
26676f8279eSTobias Grosser   }
26776f8279eSTobias Grosser 
26876f8279eSTobias Grosser   {
2693cc57fa1STobias Grosser     auto IslExp = isl::val(IslCtx, 512);
2707164b7d3STobias Grosser     auto IslLargeNPow2 = IslExp.pow2().neg();
27176f8279eSTobias Grosser     auto APLargeNPow2 = APIntFromVal(IslLargeNPow2);
272aa6eb5cdSTobias Grosser     EXPECT_EQ(513u, APLargeNPow2.getBitWidth());
273*5e111eb2SKazu Hirata     EXPECT_EQ(513u, APLargeNPow2.getSignificantBits());
274aa6eb5cdSTobias Grosser     EXPECT_EQ(512, (-APLargeNPow2).exactLogBase2());
27505cf9c22SMichael Kruse   }
27605cf9c22SMichael Kruse 
27705cf9c22SMichael Kruse   isl_ctx_free(IslCtx);
27805cf9c22SMichael Kruse }
27905cf9c22SMichael Kruse 
TEST(Isl,Operators)280be483ae6STobias Grosser TEST(Isl, Operators) {
281be483ae6STobias Grosser   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> IslCtx(isl_ctx_alloc(),
282be483ae6STobias Grosser                                                            &isl_ctx_free);
283be483ae6STobias Grosser 
284be483ae6STobias Grosser   isl::val ValOne = isl::val(IslCtx.get(), 1);
285be483ae6STobias Grosser   isl::val ValTwo = isl::val(IslCtx.get(), 2);
286be483ae6STobias Grosser   isl::val ValThree = isl::val(IslCtx.get(), 3);
287be483ae6STobias Grosser   isl::val ValFour = isl::val(IslCtx.get(), 4);
288be483ae6STobias Grosser   isl::val ValNegOne = isl::val(IslCtx.get(), -1);
289be483ae6STobias Grosser   isl::val ValNegTwo = isl::val(IslCtx.get(), -2);
290be483ae6STobias Grosser   isl::val ValNegThree = isl::val(IslCtx.get(), -3);
291be483ae6STobias Grosser   isl::val ValNegFour = isl::val(IslCtx.get(), -4);
292be483ae6STobias Grosser 
293be483ae6STobias Grosser   isl::space Space = isl::space(IslCtx.get(), 0, 0);
294be483ae6STobias Grosser   isl::local_space LS = isl::local_space(Space);
295be483ae6STobias Grosser 
296be483ae6STobias Grosser   isl::pw_aff AffOne = isl::aff(LS, ValOne);
297be483ae6STobias Grosser   isl::pw_aff AffTwo = isl::aff(LS, ValTwo);
298be483ae6STobias Grosser   isl::pw_aff AffThree = isl::aff(LS, ValThree);
299be483ae6STobias Grosser   isl::pw_aff AffFour = isl::aff(LS, ValFour);
300be483ae6STobias Grosser   isl::pw_aff AffNegOne = isl::aff(LS, ValNegOne);
301be483ae6STobias Grosser   isl::pw_aff AffNegTwo = isl::aff(LS, ValNegTwo);
302be483ae6STobias Grosser   isl::pw_aff AffNegThree = isl::aff(LS, ValNegThree);
303be483ae6STobias Grosser   isl::pw_aff AffNegFour = isl::aff(LS, ValNegFour);
304be483ae6STobias Grosser 
305be483ae6STobias Grosser   // Addition
306be483ae6STobias Grosser   {
307be483ae6STobias Grosser     EXPECT_EQ(AffOne + AffOne, AffTwo);
308be483ae6STobias Grosser     EXPECT_EQ(AffOne + 1, AffTwo);
309be483ae6STobias Grosser     EXPECT_EQ(1 + AffOne, AffTwo);
310be483ae6STobias Grosser     EXPECT_EQ(AffOne + ValOne, AffTwo);
311be483ae6STobias Grosser     EXPECT_EQ(ValOne + AffOne, AffTwo);
312be483ae6STobias Grosser   }
313be483ae6STobias Grosser 
314be483ae6STobias Grosser   // Multiplication
315be483ae6STobias Grosser   {
316be483ae6STobias Grosser     EXPECT_EQ(AffTwo * AffTwo, AffFour);
317be483ae6STobias Grosser     EXPECT_EQ(AffTwo * 2, AffFour);
318be483ae6STobias Grosser     EXPECT_EQ(2 * AffTwo, AffFour);
319be483ae6STobias Grosser     EXPECT_EQ(AffTwo * ValTwo, AffFour);
320be483ae6STobias Grosser     EXPECT_EQ(ValTwo * AffTwo, AffFour);
321be483ae6STobias Grosser   }
322be483ae6STobias Grosser 
323be483ae6STobias Grosser   // Subtraction
324be483ae6STobias Grosser   {
325be483ae6STobias Grosser     EXPECT_EQ(AffTwo - AffOne, AffOne);
326be483ae6STobias Grosser     EXPECT_EQ(AffTwo - 1, AffOne);
327be483ae6STobias Grosser     EXPECT_EQ(2 - AffOne, AffOne);
328be483ae6STobias Grosser     EXPECT_EQ(AffTwo - ValOne, AffOne);
329be483ae6STobias Grosser     EXPECT_EQ(ValTwo - AffOne, AffOne);
330be483ae6STobias Grosser   }
331be483ae6STobias Grosser 
332be483ae6STobias Grosser   // Division
333be483ae6STobias Grosser   {
334be483ae6STobias Grosser     EXPECT_EQ(AffFour / AffTwo, AffTwo);
335be483ae6STobias Grosser     EXPECT_EQ(AffFour / 2, AffTwo);
336be483ae6STobias Grosser     EXPECT_EQ(4 / AffTwo, AffTwo);
337be483ae6STobias Grosser     EXPECT_EQ(AffFour / ValTwo, AffTwo);
338be483ae6STobias Grosser     EXPECT_EQ(AffFour / 2, AffTwo);
339be483ae6STobias Grosser 
340be483ae6STobias Grosser     // Dividend is negative (should be rounded towards zero)
341be483ae6STobias Grosser     EXPECT_EQ(AffNegFour / AffThree, AffNegOne);
342be483ae6STobias Grosser     EXPECT_EQ(AffNegFour / 3, AffNegOne);
343be483ae6STobias Grosser     EXPECT_EQ((-4) / AffThree, AffNegOne);
344be483ae6STobias Grosser     EXPECT_EQ(AffNegFour / ValThree, AffNegOne);
345be483ae6STobias Grosser     EXPECT_EQ(AffNegFour / 3, AffNegOne);
346be483ae6STobias Grosser 
347be483ae6STobias Grosser     // Divisor is negative (should be rounded towards zero)
348be483ae6STobias Grosser     EXPECT_EQ(AffFour / AffNegThree, AffNegOne);
349be483ae6STobias Grosser     EXPECT_EQ(AffFour / -3, AffNegOne);
350be483ae6STobias Grosser     EXPECT_EQ(4 / AffNegThree, AffNegOne);
351be483ae6STobias Grosser     EXPECT_EQ(AffFour / ValNegThree, AffNegOne);
352be483ae6STobias Grosser     EXPECT_EQ(AffFour / -3, AffNegOne);
353be483ae6STobias Grosser   }
354be483ae6STobias Grosser 
355be483ae6STobias Grosser   // Remainder
356be483ae6STobias Grosser   {
357be483ae6STobias Grosser     EXPECT_EQ(AffThree % AffTwo, AffOne);
358be483ae6STobias Grosser     EXPECT_EQ(AffThree % 2, AffOne);
359be483ae6STobias Grosser     EXPECT_EQ(3 % AffTwo, AffOne);
360be483ae6STobias Grosser     EXPECT_EQ(AffThree % ValTwo, AffOne);
361be483ae6STobias Grosser     EXPECT_EQ(ValThree % AffTwo, AffOne);
362be483ae6STobias Grosser 
363be483ae6STobias Grosser     // Dividend is negative (should be rounded towards zero)
364be483ae6STobias Grosser     EXPECT_EQ(AffNegFour % AffThree, AffNegOne);
365be483ae6STobias Grosser     EXPECT_EQ(AffNegFour % 3, AffNegOne);
366be483ae6STobias Grosser     EXPECT_EQ((-4) % AffThree, AffNegOne);
367be483ae6STobias Grosser     EXPECT_EQ(AffNegFour % ValThree, AffNegOne);
368be483ae6STobias Grosser     EXPECT_EQ(AffNegFour % 3, AffNegOne);
369be483ae6STobias Grosser 
370be483ae6STobias Grosser     // Divisor is negative (should be rounded towards zero)
371be483ae6STobias Grosser     EXPECT_EQ(AffFour % AffNegThree, AffOne);
372be483ae6STobias Grosser     EXPECT_EQ(AffFour % -3, AffOne);
373be483ae6STobias Grosser     EXPECT_EQ(4 % AffNegThree, AffOne);
374be483ae6STobias Grosser     EXPECT_EQ(AffFour % ValNegThree, AffOne);
375be483ae6STobias Grosser     EXPECT_EQ(AffFour % -3, AffOne);
376be483ae6STobias Grosser   }
377be483ae6STobias Grosser }
378be483ae6STobias Grosser 
TEST(Isl,Foreach)379209b4632SMichael Kruse TEST(Isl, Foreach) {
380209b4632SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
381209b4632SMichael Kruse                                                         &isl_ctx_free);
382209b4632SMichael Kruse 
38350eaa82cSMichael Kruse   isl::map TestMap{Ctx.get(), "{ [2] -> [7]; [5] -> [7] }"};
38450eaa82cSMichael Kruse   isl::union_map TestUMap{Ctx.get(), "{ A[i] -> [7]; B[i] -> [7] }"};
385209b4632SMichael Kruse 
38650eaa82cSMichael Kruse   isl::set TestSet{Ctx.get(), "{ [0,7]; [i,7]: i >= 2 }"};
38750eaa82cSMichael Kruse   isl::union_set TestUSet{Ctx.get(), "{ A[0,7]; B[i,7] }"};
38850eaa82cSMichael Kruse 
38950eaa82cSMichael Kruse   isl::set Seven{Ctx.get(), "{ [7] }"};
390209b4632SMichael Kruse 
391209b4632SMichael Kruse   {
392209b4632SMichael Kruse     auto NumBMaps = 0;
393a2fd4419STobias Grosser     isl::stat Stat =
39475aa1a9aSTobias Grosser         TestMap.foreach_basic_map([&](isl::basic_map BMap) -> isl::stat {
39550eaa82cSMichael Kruse           EXPECT_EQ(BMap.range(), Seven);
396209b4632SMichael Kruse           NumBMaps++;
397a2fd4419STobias Grosser           return isl::stat::ok();
398209b4632SMichael Kruse         });
399a2fd4419STobias Grosser 
400a2fd4419STobias Grosser     EXPECT_TRUE(Stat.is_ok());
40150eaa82cSMichael Kruse     EXPECT_EQ(2, NumBMaps);
402209b4632SMichael Kruse   }
403209b4632SMichael Kruse 
404209b4632SMichael Kruse   {
405209b4632SMichael Kruse     auto NumBSets = 0;
406a2fd4419STobias Grosser     isl::stat Stat =
40775aa1a9aSTobias Grosser         TestSet.foreach_basic_set([&](isl::basic_set BSet) -> isl::stat {
40850eaa82cSMichael Kruse           EXPECT_EQ(BSet.project_out(isl::dim::set, 0, 1), Seven);
409209b4632SMichael Kruse           NumBSets++;
410a2fd4419STobias Grosser           return isl::stat::ok();
411209b4632SMichael Kruse         });
412a2fd4419STobias Grosser     EXPECT_TRUE(Stat.is_ok());
41350eaa82cSMichael Kruse     EXPECT_EQ(2, NumBSets);
414209b4632SMichael Kruse   }
415209b4632SMichael Kruse 
416209b4632SMichael Kruse   {
417209b4632SMichael Kruse     auto NumMaps = 0;
418a2fd4419STobias Grosser     isl::stat Stat = TestUMap.foreach_map([&](isl::map Map) -> isl::stat {
41950eaa82cSMichael Kruse       EXPECT_EQ(Map.range(), Seven);
420209b4632SMichael Kruse       NumMaps++;
421a2fd4419STobias Grosser       return isl::stat::ok();
422209b4632SMichael Kruse     });
423a2fd4419STobias Grosser     EXPECT_TRUE(Stat.is_ok());
42450eaa82cSMichael Kruse     EXPECT_EQ(2, NumMaps);
425209b4632SMichael Kruse   }
426209b4632SMichael Kruse 
427209b4632SMichael Kruse   {
428209b4632SMichael Kruse     auto NumSets = 0;
429a2fd4419STobias Grosser     isl::stat Stat = TestUSet.foreach_set([&](isl::set Set) -> isl::stat {
43050eaa82cSMichael Kruse       EXPECT_EQ(Set.project_out(isl::dim::set, 0, 1), Seven);
431209b4632SMichael Kruse       NumSets++;
432a2fd4419STobias Grosser       return isl::stat::ok();
433209b4632SMichael Kruse     });
434a2fd4419STobias Grosser     EXPECT_TRUE(Stat.is_ok());
43550eaa82cSMichael Kruse     EXPECT_EQ(2, NumSets);
436209b4632SMichael Kruse   }
437209b4632SMichael Kruse 
438209b4632SMichael Kruse   {
4393cc57fa1STobias Grosser     auto UPwAff = isl::union_pw_aff(TestUSet, isl::val::zero(Ctx.get()));
440209b4632SMichael Kruse     auto NumPwAffs = 0;
441a2fd4419STobias Grosser     isl::stat Stat = UPwAff.foreach_pw_aff([&](isl::pw_aff PwAff) -> isl::stat {
4423cc57fa1STobias Grosser       EXPECT_TRUE(PwAff.is_cst());
443209b4632SMichael Kruse       NumPwAffs++;
444a2fd4419STobias Grosser       return isl::stat::ok();
445209b4632SMichael Kruse     });
446a2fd4419STobias Grosser     EXPECT_TRUE(Stat.is_ok());
44750eaa82cSMichael Kruse     EXPECT_EQ(2, NumPwAffs);
448209b4632SMichael Kruse   }
449209b4632SMichael Kruse 
450209b4632SMichael Kruse   {
451209b4632SMichael Kruse     auto NumBMaps = 0;
452a2fd4419STobias Grosser     EXPECT_TRUE(TestMap
453a2fd4419STobias Grosser                     .foreach_basic_map([&](isl::basic_map BMap) -> isl::stat {
45450eaa82cSMichael Kruse                       EXPECT_EQ(BMap.range(), Seven);
455209b4632SMichael Kruse                       NumBMaps++;
456a2fd4419STobias Grosser                       return isl::stat::error();
457a2fd4419STobias Grosser                     })
458a2fd4419STobias Grosser                     .is_error());
459209b4632SMichael Kruse     EXPECT_EQ(1, NumBMaps);
460209b4632SMichael Kruse   }
461209b4632SMichael Kruse 
462209b4632SMichael Kruse   {
463209b4632SMichael Kruse     auto NumMaps = 0;
464a2fd4419STobias Grosser     EXPECT_TRUE(TestUMap
465a2fd4419STobias Grosser                     .foreach_map([&](isl::map Map) -> isl::stat {
46650eaa82cSMichael Kruse                       EXPECT_EQ(Map.range(), Seven);
467209b4632SMichael Kruse                       NumMaps++;
468a2fd4419STobias Grosser                       return isl::stat::error();
469a2fd4419STobias Grosser                     })
470a2fd4419STobias Grosser                     .is_error());
471209b4632SMichael Kruse     EXPECT_EQ(1, NumMaps);
472209b4632SMichael Kruse   }
473209b4632SMichael Kruse 
474209b4632SMichael Kruse   {
4753cc57fa1STobias Grosser     auto TestPwAff = isl::pw_aff(TestSet, isl::val::zero(Ctx.get()));
476209b4632SMichael Kruse     auto NumPieces = 0;
477a2fd4419STobias Grosser     isl::stat Stat = TestPwAff.foreach_piece(
478a2fd4419STobias Grosser         [&](isl::set Domain, isl::aff Aff) -> isl::stat {
4793cc57fa1STobias Grosser           EXPECT_EQ(Domain, TestSet);
4803cc57fa1STobias Grosser           EXPECT_TRUE(Aff.is_cst());
481209b4632SMichael Kruse           NumPieces++;
482a2fd4419STobias Grosser           return isl::stat::error();
483209b4632SMichael Kruse         });
484a2fd4419STobias Grosser     EXPECT_TRUE(Stat.is_error());
485209b4632SMichael Kruse     EXPECT_EQ(1, NumPieces);
486209b4632SMichael Kruse   }
487209b4632SMichael Kruse }
488209b4632SMichael Kruse 
TEST(ISLTools,beforeScatter)489d1508812SMichael Kruse TEST(ISLTools, beforeScatter) {
490d1508812SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
491d1508812SMichael Kruse                                                         &isl_ctx_free);
492d1508812SMichael Kruse 
493d1508812SMichael Kruse   // Basic usage with isl_map
494d1508812SMichael Kruse   EXPECT_EQ(MAP("{ [] -> [i] : i <= 0 }"),
495d1508812SMichael Kruse             beforeScatter(MAP("{ [] -> [0] }"), false));
496d1508812SMichael Kruse   EXPECT_EQ(MAP("{ [] -> [i] : i < 0 }"),
497d1508812SMichael Kruse             beforeScatter(MAP("{ [] -> [0] }"), true));
498d1508812SMichael Kruse 
499d1508812SMichael Kruse   // Basic usage with isl_union_map
500d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ A[] -> [i] : i <= 0; B[] -> [i] : i <= 0 }"),
501d1508812SMichael Kruse             beforeScatter(UMAP("{ A[] -> [0]; B[] -> [0] }"), false));
502d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ A[] -> [i] : i < 0; B[] -> [i] : i < 0 }"),
503d1508812SMichael Kruse             beforeScatter(UMAP("{ A[] -> [0]; B[] -> [0] }"), true));
504d1508812SMichael Kruse 
505d1508812SMichael Kruse   // More than one dimension
506d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [i, j] : i < 0;  [] -> [i, j] : i = 0 and j <= 0 }"),
507d1508812SMichael Kruse             beforeScatter(UMAP("{ [] -> [0, 0] }"), false));
508d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [i, j] : i < 0;  [] -> [i, j] : i = 0 and j < 0 }"),
509d1508812SMichael Kruse             beforeScatter(UMAP("{ [] -> [0, 0] }"), true));
510d1508812SMichael Kruse 
511d1508812SMichael Kruse   // Functional
512d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [i] -> [j] : j <= i }"),
513d1508812SMichael Kruse             beforeScatter(UMAP("{ [i] -> [i] }"), false));
514d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [i] -> [j] : j < i }"),
515d1508812SMichael Kruse             beforeScatter(UMAP("{ [i] -> [i] }"), true));
516d1508812SMichael Kruse 
517d1508812SMichael Kruse   // Parametrized
518d1508812SMichael Kruse   EXPECT_EQ(UMAP("[i] -> { [] -> [j] : j <= i }"),
519d1508812SMichael Kruse             beforeScatter(UMAP("[i] -> { [] -> [i] }"), false));
520d1508812SMichael Kruse   EXPECT_EQ(UMAP("[i] -> { [] -> [j] : j < i }"),
521d1508812SMichael Kruse             beforeScatter(UMAP("[i] -> { [] -> [i] }"), true));
522d1508812SMichael Kruse 
523d1508812SMichael Kruse   // More than one range
524d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [i] : i <= 10 }"),
525d1508812SMichael Kruse             beforeScatter(UMAP("{ [] -> [0]; [] -> [10] }"), false));
526d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [i] : i < 10 }"),
527d1508812SMichael Kruse             beforeScatter(UMAP("{ [] -> [0]; [] -> [10] }"), true));
528d1508812SMichael Kruse 
529d1508812SMichael Kruse   // Edge case: empty
530d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [i] : 1 = 0 }"),
531d1508812SMichael Kruse             beforeScatter(UMAP("{ [] -> [i] : 1 = 0 }"), false));
532d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [i] : 1 = 0 }"),
533d1508812SMichael Kruse             beforeScatter(UMAP("{ [] -> [i] : 1 = 0 }"), true));
534d1508812SMichael Kruse }
535d1508812SMichael Kruse 
TEST(ISLTools,afterScatter)536d1508812SMichael Kruse TEST(ISLTools, afterScatter) {
537d1508812SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
538d1508812SMichael Kruse                                                         &isl_ctx_free);
539d1508812SMichael Kruse 
540d1508812SMichael Kruse   // Basic usage with isl_map
541d1508812SMichael Kruse   EXPECT_EQ(MAP("{ [] -> [i] : i >= 0 }"),
542d1508812SMichael Kruse             afterScatter(MAP("{ [] -> [0] }"), false));
543d1508812SMichael Kruse   EXPECT_EQ(MAP("{ [] -> [i] : i > 0 }"),
544d1508812SMichael Kruse             afterScatter(MAP("{ [] -> [0] }"), true));
545d1508812SMichael Kruse 
546d1508812SMichael Kruse   // Basic usage with isl_union_map
547d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ A[] -> [i] : i >= 0; B[] -> [i] : i >= 0 }"),
548d1508812SMichael Kruse             afterScatter(UMAP("{ A[] -> [0]; B[] -> [0] }"), false));
549d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ A[] -> [i] : i > 0; B[] -> [i] : i > 0 }"),
550d1508812SMichael Kruse             afterScatter(UMAP("{ A[] -> [0]; B[] -> [0] }"), true));
551d1508812SMichael Kruse 
552d1508812SMichael Kruse   // More than one dimension
553d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [i, j] : i > 0;  [] -> [i, j] : i = 0 and j >= 0 }"),
554d1508812SMichael Kruse             afterScatter(UMAP("{ [] -> [0, 0] }"), false));
555d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [i, j] : i > 0;  [] -> [i, j] : i = 0 and j > 0 }"),
556d1508812SMichael Kruse             afterScatter(UMAP("{ [] -> [0, 0] }"), true));
557d1508812SMichael Kruse 
558d1508812SMichael Kruse   // Functional
559d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [i] -> [j] : j >= i }"),
560d1508812SMichael Kruse             afterScatter(UMAP("{ [i] -> [i] }"), false));
561d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [i] -> [j] : j > i }"),
562d1508812SMichael Kruse             afterScatter(UMAP("{ [i] -> [i] }"), true));
563d1508812SMichael Kruse 
564d1508812SMichael Kruse   // Parametrized
565d1508812SMichael Kruse   EXPECT_EQ(UMAP("[i] -> { [] -> [j] : j >= i }"),
566d1508812SMichael Kruse             afterScatter(UMAP("[i] -> { [] -> [i] }"), false));
567d1508812SMichael Kruse   EXPECT_EQ(UMAP("[i] -> { [] -> [j] : j > i }"),
568d1508812SMichael Kruse             afterScatter(UMAP("[i] -> { [] -> [i] }"), true));
569d1508812SMichael Kruse 
570d1508812SMichael Kruse   // More than one range
571d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [i] : i >= 0 }"),
572d1508812SMichael Kruse             afterScatter(UMAP("{ [] -> [0]; [] -> [10] }"), false));
573d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [i] : i > 0 }"),
574d1508812SMichael Kruse             afterScatter(UMAP("{ [] -> [0]; [] -> [10] }"), true));
575d1508812SMichael Kruse 
576d1508812SMichael Kruse   // Edge case: empty
577d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ }"), afterScatter(UMAP("{ }"), false));
578d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ }"), afterScatter(UMAP("{ }"), true));
579d1508812SMichael Kruse }
580d1508812SMichael Kruse 
TEST(ISLTools,betweenScatter)581d1508812SMichael Kruse TEST(ISLTools, betweenScatter) {
582d1508812SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
583d1508812SMichael Kruse                                                         &isl_ctx_free);
584d1508812SMichael Kruse 
585d1508812SMichael Kruse   // Basic usage with isl_map
586d1508812SMichael Kruse   EXPECT_EQ(MAP("{ [] -> [i] : 0 < i < 10 }"),
587d1508812SMichael Kruse             betweenScatter(MAP("{ [] -> [0] }"), MAP("{ [] -> [10] }"), false,
588d1508812SMichael Kruse                            false));
589d1508812SMichael Kruse   EXPECT_EQ(
590d1508812SMichael Kruse       MAP("{ [] -> [i] : 0 <= i < 10 }"),
591d1508812SMichael Kruse       betweenScatter(MAP("{ [] -> [0] }"), MAP("{ [] -> [10] }"), true, false));
592d1508812SMichael Kruse   EXPECT_EQ(
593d1508812SMichael Kruse       MAP("{ [] -> [i] : 0 < i <= 10 }"),
594d1508812SMichael Kruse       betweenScatter(MAP("{ [] -> [0] }"), MAP("{ [] -> [10] }"), false, true));
595d1508812SMichael Kruse   EXPECT_EQ(
596d1508812SMichael Kruse       MAP("{ [] -> [i] : 0 <= i <= 10 }"),
597d1508812SMichael Kruse       betweenScatter(MAP("{ [] -> [0] }"), MAP("{ [] -> [10] }"), true, true));
598d1508812SMichael Kruse 
599d1508812SMichael Kruse   // Basic usage with isl_union_map
600d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ A[] -> [i] : 0 < i < 10; B[] -> [i] : 0 < i < 10 }"),
601d1508812SMichael Kruse             betweenScatter(UMAP("{ A[] -> [0]; B[] -> [0] }"),
602d1508812SMichael Kruse                            UMAP("{ A[] -> [10]; B[] -> [10] }"), false, false));
603d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ A[] -> [i] : 0 <= i < 10; B[] -> [i] : 0 <= i < 10 }"),
604d1508812SMichael Kruse             betweenScatter(UMAP("{ A[] -> [0]; B[] -> [0] }"),
605d1508812SMichael Kruse                            UMAP("{ A[] -> [10]; B[] -> [10] }"), true, false));
606d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ A[] -> [i] : 0 < i <= 10; B[] -> [i] : 0 < i <= 10 }"),
607d1508812SMichael Kruse             betweenScatter(UMAP("{ A[] -> [0]; B[] -> [0] }"),
608d1508812SMichael Kruse                            UMAP("{ A[] -> [10]; B[] -> [10] }"), false, true));
609d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ A[] -> [i] : 0 <= i <= 10; B[] -> [i] : 0 <= i <= 10 }"),
610d1508812SMichael Kruse             betweenScatter(UMAP("{ A[] -> [0]; B[] -> [0] }"),
611d1508812SMichael Kruse                            UMAP("{ A[] -> [10]; B[] -> [10] }"), true, true));
612d1508812SMichael Kruse }
613d1508812SMichael Kruse 
TEST(ISLTools,singleton)614d1508812SMichael Kruse TEST(ISLTools, singleton) {
615d1508812SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
616d1508812SMichael Kruse                                                         &isl_ctx_free);
617d1508812SMichael Kruse 
618d1508812SMichael Kruse   // No element found
619d1508812SMichael Kruse   EXPECT_EQ(SET("{ [] : 1 = 0 }"), singleton(USET("{ }"), SPACE("{ [] }")));
620d1508812SMichael Kruse   EXPECT_EQ(MAP("{ [] -> [] : 1 = 0  }"),
621d1508812SMichael Kruse             singleton(UMAP("{  }"), SPACE("{ [] -> [] }")));
622d1508812SMichael Kruse 
623d1508812SMichael Kruse   // One element found
624d1508812SMichael Kruse   EXPECT_EQ(SET("{ [] }"), singleton(USET("{ [] }"), SPACE("{ [] }")));
625d1508812SMichael Kruse   EXPECT_EQ(MAP("{ [] -> [] }"),
626d1508812SMichael Kruse             singleton(UMAP("{ [] -> [] }"), SPACE("{ [] -> [] }")));
627d1508812SMichael Kruse 
628d1508812SMichael Kruse   // Many elements found
629d1508812SMichael Kruse   EXPECT_EQ(SET("{ [i] : 0 <= i < 10 }"),
630d1508812SMichael Kruse             singleton(USET("{ [i] : 0 <= i < 10 }"), SPACE("{ [i] }")));
631d1508812SMichael Kruse   EXPECT_EQ(
632d1508812SMichael Kruse       MAP("{ [i] -> [i] : 0 <= i < 10 }"),
633d1508812SMichael Kruse       singleton(UMAP("{ [i] -> [i] : 0 <= i < 10 }"), SPACE("{ [i] -> [j] }")));
634d1508812SMichael Kruse 
635d1508812SMichael Kruse   // Different parameters
636d1508812SMichael Kruse   EXPECT_EQ(SET("[i] -> { [i] }"),
637d1508812SMichael Kruse             singleton(USET("[i] -> { [i] }"), SPACE("{ [i] }")));
638d1508812SMichael Kruse   EXPECT_EQ(MAP("[i] -> { [i] -> [i] }"),
639d1508812SMichael Kruse             singleton(UMAP("[i] -> { [i] -> [i] }"), SPACE("{ [i] -> [j] }")));
640d1508812SMichael Kruse }
641d1508812SMichael Kruse 
TEST(ISLTools,getNumScatterDims)642d1508812SMichael Kruse TEST(ISLTools, getNumScatterDims) {
643d1508812SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
644d1508812SMichael Kruse                                                         &isl_ctx_free);
645d1508812SMichael Kruse 
646d1508812SMichael Kruse   // Basic usage
64744596fe6SRiccardo Mori   EXPECT_EQ(0u, getNumScatterDims(UMAP("{ [] -> [] }")));
64844596fe6SRiccardo Mori   EXPECT_EQ(1u, getNumScatterDims(UMAP("{ [] -> [i] }")));
64944596fe6SRiccardo Mori   EXPECT_EQ(2u, getNumScatterDims(UMAP("{ [] -> [i,j] }")));
65044596fe6SRiccardo Mori   EXPECT_EQ(3u, getNumScatterDims(UMAP("{ [] -> [i,j,k] }")));
651d1508812SMichael Kruse 
652d1508812SMichael Kruse   // Different scatter spaces
65344596fe6SRiccardo Mori   EXPECT_EQ(0u, getNumScatterDims(UMAP("{ A[] -> []; [] -> []}")));
65444596fe6SRiccardo Mori   EXPECT_EQ(1u, getNumScatterDims(UMAP("{ A[] -> []; [] -> [i] }")));
65544596fe6SRiccardo Mori   EXPECT_EQ(2u, getNumScatterDims(UMAP("{ A[] -> [i]; [] -> [i,j] }")));
65644596fe6SRiccardo Mori   EXPECT_EQ(3u, getNumScatterDims(UMAP("{ A[] -> [i]; [] -> [i,j,k] }")));
657d1508812SMichael Kruse }
658d1508812SMichael Kruse 
TEST(ISLTools,getScatterSpace)659d1508812SMichael Kruse TEST(ISLTools, getScatterSpace) {
660d1508812SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
661d1508812SMichael Kruse                                                         &isl_ctx_free);
662d1508812SMichael Kruse 
663d1508812SMichael Kruse   // Basic usage
664d1508812SMichael Kruse   EXPECT_EQ(SPACE("{ [] }"), getScatterSpace(UMAP("{ [] -> [] }")));
665d1508812SMichael Kruse   EXPECT_EQ(SPACE("{ [i] }"), getScatterSpace(UMAP("{ [] -> [i] }")));
666d1508812SMichael Kruse   EXPECT_EQ(SPACE("{ [i,j] }"), getScatterSpace(UMAP("{ [] -> [i,j] }")));
667d1508812SMichael Kruse   EXPECT_EQ(SPACE("{ [i,j,k] }"), getScatterSpace(UMAP("{ [] -> [i,j,k] }")));
668d1508812SMichael Kruse 
669d1508812SMichael Kruse   // Different scatter spaces
670d1508812SMichael Kruse   EXPECT_EQ(SPACE("{ [] }"), getScatterSpace(UMAP("{ A[] -> []; [] -> [] }")));
671d1508812SMichael Kruse   EXPECT_EQ(SPACE("{ [i] }"),
672d1508812SMichael Kruse             getScatterSpace(UMAP("{ A[] -> []; [] -> [i] }")));
673d1508812SMichael Kruse   EXPECT_EQ(SPACE("{ [i,j] }"),
674d1508812SMichael Kruse             getScatterSpace(UMAP("{ A[] -> [i]; [] -> [i,j] }")));
675d1508812SMichael Kruse   EXPECT_EQ(SPACE("{ [i,j,k] }"),
676d1508812SMichael Kruse             getScatterSpace(UMAP("{ A[] -> [i]; [] -> [i,j,k] }")));
677d1508812SMichael Kruse }
678d1508812SMichael Kruse 
TEST(ISLTools,makeIdentityMap)679d1508812SMichael Kruse TEST(ISLTools, makeIdentityMap) {
680d1508812SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
681d1508812SMichael Kruse                                                         &isl_ctx_free);
682d1508812SMichael Kruse 
683d1508812SMichael Kruse   // Basic usage
684d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [i] -> [i] }"), makeIdentityMap(USET("{ [0] }"), false));
685d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [0] -> [0] }"), makeIdentityMap(USET("{ [0] }"), true));
686d1508812SMichael Kruse 
687d1508812SMichael Kruse   // Multiple spaces
688d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> []; [i] -> [i] }"),
689d1508812SMichael Kruse             makeIdentityMap(USET("{ []; [0] }"), false));
690d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> []; [0] -> [0] }"),
691d1508812SMichael Kruse             makeIdentityMap(USET("{ []; [0] }"), true));
692d1508812SMichael Kruse 
693d1508812SMichael Kruse   // Edge case: empty
694d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ }"), makeIdentityMap(USET("{ }"), false));
695d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ }"), makeIdentityMap(USET("{ }"), true));
696d1508812SMichael Kruse }
697d1508812SMichael Kruse 
TEST(ISLTools,reverseDomain)698d1508812SMichael Kruse TEST(ISLTools, reverseDomain) {
699d1508812SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
700d1508812SMichael Kruse                                                         &isl_ctx_free);
701d1508812SMichael Kruse 
702d1508812SMichael Kruse   // Basic usage
703d1508812SMichael Kruse   EXPECT_EQ(MAP("{ [B[] -> A[]] -> [] }"),
704d1508812SMichael Kruse             reverseDomain(MAP("{ [A[] -> B[]] -> [] }")));
705d1508812SMichael Kruse   EXPECT_EQ(UMAP("{ [B[] -> A[]] -> [] }"),
706d1508812SMichael Kruse             reverseDomain(UMAP("{ [A[] -> B[]] -> [] }")));
707d1508812SMichael Kruse }
708d1508812SMichael Kruse 
TEST(ISLTools,shiftDim)709d1508812SMichael Kruse TEST(ISLTools, shiftDim) {
710d1508812SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
711d1508812SMichael Kruse                                                         &isl_ctx_free);
712d1508812SMichael Kruse 
713d1508812SMichael Kruse   // Basic usage
714d1508812SMichael Kruse   EXPECT_EQ(SET("{ [1] }"), shiftDim(SET("{ [0] }"), 0, 1));
715d1508812SMichael Kruse   EXPECT_EQ(USET("{ [1] }"), shiftDim(USET("{ [0] }"), 0, 1));
716d1508812SMichael Kruse 
717d1508812SMichael Kruse   // From-end indexing
718d1508812SMichael Kruse   EXPECT_EQ(USET("{ [0,0,1] }"), shiftDim(USET("{ [0,0,0] }"), -1, 1));
719d1508812SMichael Kruse   EXPECT_EQ(USET("{ [0,1,0] }"), shiftDim(USET("{ [0,0,0] }"), -2, 1));
720d1508812SMichael Kruse   EXPECT_EQ(USET("{ [1,0,0] }"), shiftDim(USET("{ [0,0,0] }"), -3, 1));
721d1508812SMichael Kruse 
722d1508812SMichael Kruse   // Parametrized
723d1508812SMichael Kruse   EXPECT_EQ(USET("[n] -> { [n+1] }"), shiftDim(USET("[n] -> { [n] }"), 0, 1));
724174f4839SMichael Kruse 
725174f4839SMichael Kruse   // Union maps
726174f4839SMichael Kruse   EXPECT_EQ(MAP("{ [1] -> [] }"),
727174f4839SMichael Kruse             shiftDim(MAP("{ [0] -> [] }"), isl::dim::in, 0, 1));
728174f4839SMichael Kruse   EXPECT_EQ(UMAP("{ [1] -> [] }"),
729174f4839SMichael Kruse             shiftDim(UMAP("{ [0] -> [] }"), isl::dim::in, 0, 1));
730174f4839SMichael Kruse   EXPECT_EQ(MAP("{ [] -> [1] }"),
731174f4839SMichael Kruse             shiftDim(MAP("{ [] -> [0] }"), isl::dim::out, 0, 1));
732174f4839SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [1] }"),
733174f4839SMichael Kruse             shiftDim(UMAP("{ [] -> [0] }"), isl::dim::out, 0, 1));
734d1508812SMichael Kruse }
735d1508812SMichael Kruse 
TEST(DeLICM,computeReachingWrite)736f4dc133eSMichael Kruse TEST(DeLICM, computeReachingWrite) {
737f4dc133eSMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
738f4dc133eSMichael Kruse                                                         &isl_ctx_free);
739f4dc133eSMichael Kruse 
740f4dc133eSMichael Kruse   // Basic usage
741f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom[] : 0 < i }"),
742f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom[] -> [0] }"),
743f4dc133eSMichael Kruse                                  UMAP("{ Dom[] -> Elt[] }"), false, false,
744f4dc133eSMichael Kruse                                  false));
745f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom[] : 0 < i }"),
746f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom[] -> [0] }"),
747f4dc133eSMichael Kruse                                  UMAP("{ Dom[] -> Elt[] }"), false, false,
748f4dc133eSMichael Kruse                                  true));
749f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom[] : 0 <= i }"),
750f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom[] -> [0] }"),
751f4dc133eSMichael Kruse                                  UMAP("{ Dom[] -> Elt[] }"), false, true,
752f4dc133eSMichael Kruse                                  false));
753f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom[] : 0 <= i }"),
754f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom[] -> [0] }"),
755f4dc133eSMichael Kruse                                  UMAP("{ Dom[] -> Elt[] }"), false, true,
756f4dc133eSMichael Kruse                                  false));
757f4dc133eSMichael Kruse 
758f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom[] : i < 0 }"),
759f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom[] -> [0] }"),
760f4dc133eSMichael Kruse                                  UMAP("{ Dom[] -> Elt[] }"), true, false,
761f4dc133eSMichael Kruse                                  false));
762f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom[] :  i <= 0 }"),
763f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom[] -> [0] }"),
764f4dc133eSMichael Kruse                                  UMAP("{ Dom[] -> Elt[] }"), true, false,
765f4dc133eSMichael Kruse                                  true));
766f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom[] : i < 0 }"),
767f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom[] -> [0] }"),
768f4dc133eSMichael Kruse                                  UMAP("{ Dom[] -> Elt[] }"), true, true,
769f4dc133eSMichael Kruse                                  false));
770f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom[] : i <= 0 }"),
771f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom[] -> [0] }"),
772f4dc133eSMichael Kruse                                  UMAP("{ Dom[] -> Elt[] }"), true, true, true));
773f4dc133eSMichael Kruse 
774f4dc133eSMichael Kruse   // Two writes
775f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom1[] : 0 < i < 10; [Elt[] -> [i]] -> "
776f4dc133eSMichael Kruse                  "Dom2[] : 10 < i }"),
777f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom1[] -> [0]; Dom2[] -> [10] }"),
778f4dc133eSMichael Kruse                                  UMAP("{ Dom1[] -> Elt[]; Dom2[] -> Elt[] }"),
779f4dc133eSMichael Kruse                                  false, false, false));
780f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom1[] : 0 <= i < 10; [Elt[] -> [i]] -> "
781f4dc133eSMichael Kruse                  "Dom2[] : 10 <= i }"),
782f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom1[] -> [0]; Dom2[] -> [10] }"),
783f4dc133eSMichael Kruse                                  UMAP("{ Dom1[] -> Elt[]; Dom2[] -> Elt[] }"),
784f4dc133eSMichael Kruse                                  false, true, false));
785f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom1[] : 0 < i <= 10; [Elt[] -> [i]] -> "
786f4dc133eSMichael Kruse                  "Dom2[] : 10 < i }"),
787f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom1[] -> [0]; Dom2[] -> [10] }"),
788f4dc133eSMichael Kruse                                  UMAP("{ Dom1[] -> Elt[]; Dom2[] -> Elt[] }"),
789f4dc133eSMichael Kruse                                  false, false, true));
790f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom1[] : 0 <= i <= 10; [Elt[] -> [i]] -> "
791f4dc133eSMichael Kruse                  "Dom2[] : 10 <= i }"),
792f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom1[] -> [0]; Dom2[] -> [10] }"),
793f4dc133eSMichael Kruse                                  UMAP("{ Dom1[] -> Elt[]; Dom2[] -> Elt[] }"),
794f4dc133eSMichael Kruse                                  false, true, true));
795f4dc133eSMichael Kruse 
796f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom2[] : 0 < i < 10; [Elt[] -> [i]] -> "
797f4dc133eSMichael Kruse                  "Dom1[] : i < 0 }"),
798f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom1[] -> [0]; Dom2[] -> [10] }"),
799f4dc133eSMichael Kruse                                  UMAP("{ Dom1[] -> Elt[]; Dom2[] -> Elt[] }"),
800f4dc133eSMichael Kruse                                  true, false, false));
801f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom2[] : 0 <= i < 10; [Elt[] -> [i]] -> "
802f4dc133eSMichael Kruse                  "Dom1[] : i < 0 }"),
803f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom1[] -> [0]; Dom2[] -> [10] }"),
804f4dc133eSMichael Kruse                                  UMAP("{ Dom1[] -> Elt[]; Dom2[] -> Elt[] }"),
805f4dc133eSMichael Kruse                                  true, true, false));
806f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom2[] : 0 < i <= 10; [Elt[] -> [i]] -> "
807f4dc133eSMichael Kruse                  "Dom1[] : i <= 0 }"),
808f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom1[] -> [0]; Dom2[] -> [10] }"),
809f4dc133eSMichael Kruse                                  UMAP("{ Dom1[] -> Elt[]; Dom2[] -> Elt[] }"),
810f4dc133eSMichael Kruse                                  true, false, true));
811f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom2[] : 0 <= i <= 10; [Elt[] -> [i]] -> "
812f4dc133eSMichael Kruse                  "Dom1[] : i <= 0 }"),
813f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom1[] -> [0]; Dom2[] -> [10] }"),
814f4dc133eSMichael Kruse                                  UMAP("{ Dom1[] -> Elt[]; Dom2[] -> Elt[] }"),
815f4dc133eSMichael Kruse                                  true, true, true));
816f4dc133eSMichael Kruse 
817f4dc133eSMichael Kruse   // Domain in same space
818f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("{ [Elt[] -> [i]] -> Dom[1] : 0 < i <= 10; [Elt[] -> [i]] -> "
819f4dc133eSMichael Kruse                  "Dom[2] : 10 < i }"),
820f4dc133eSMichael Kruse             computeReachingWrite(UMAP("{ Dom[i] -> [10i - 10] }"),
821f4dc133eSMichael Kruse                                  UMAP("{ Dom[1] -> Elt[]; Dom[2] -> Elt[] }"),
822f4dc133eSMichael Kruse                                  false, false, true));
823f4dc133eSMichael Kruse 
824f4dc133eSMichael Kruse   // Parametric
825f4dc133eSMichael Kruse   EXPECT_EQ(UMAP("[p] -> { [Elt[] -> [i]] -> Dom[] : p < i }"),
826f4dc133eSMichael Kruse             computeReachingWrite(UMAP("[p] -> { Dom[] -> [p] }"),
827f4dc133eSMichael Kruse                                  UMAP("{ Dom[] -> Elt[] }"), false, false,
828f4dc133eSMichael Kruse                                  false));
829f4dc133eSMichael Kruse 
830f4dc133eSMichael Kruse   // More realistic example (from reduction_embedded.ll)
831f4dc133eSMichael Kruse   EXPECT_EQ(
832f4dc133eSMichael Kruse       UMAP("{ [Elt[] -> [i]] -> Dom[0] : 0 < i <= 3; [Elt[] -> [i]] -> Dom[1] "
833f4dc133eSMichael Kruse            ": 3 < i <= 6; [Elt[] -> [i]] -> Dom[2] : 6 < i <= 9; [Elt[] -> "
834f4dc133eSMichael Kruse            "[i]] -> Dom[3] : 9 < i <= 12; [Elt[] -> [i]] -> Dom[4] : 12 < i }"),
835f4dc133eSMichael Kruse       computeReachingWrite(UMAP("{ Dom[i] -> [3i] : 0 <= i <= 4 }"),
836f4dc133eSMichael Kruse                            UMAP("{ Dom[i] -> Elt[] : 0 <= i <= 4 }"), false,
837f4dc133eSMichael Kruse                            false, true));
838f4dc133eSMichael Kruse }
839f4dc133eSMichael Kruse 
TEST(DeLICM,computeArrayUnused)840ec67d364SMichael Kruse TEST(DeLICM, computeArrayUnused) {
841ec67d364SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
842ec67d364SMichael Kruse                                                         &isl_ctx_free);
843ec67d364SMichael Kruse 
844ec67d364SMichael Kruse   // The ReadEltInSameInst parameter doesn't matter in simple cases. To also
845ec67d364SMichael Kruse   // cover the parameter without duplicating the tests, this loops runs over
846ec67d364SMichael Kruse   // other in both settings.
847ec67d364SMichael Kruse   for (bool ReadEltInSameInst = false, Done = false; !Done;
848ec67d364SMichael Kruse        Done = ReadEltInSameInst, ReadEltInSameInst = true) {
849ec67d364SMichael Kruse     // Basic usage: one read, one write
850ec67d364SMichael Kruse     EXPECT_EQ(UMAP("{ Elt[] -> [i] : 0 < i < 10 }"),
851ec67d364SMichael Kruse               computeArrayUnused(UMAP("{ Read[] -> [0]; Write[] -> [10] }"),
852ec67d364SMichael Kruse                                  UMAP("{ Write[] -> Elt[] }"),
853ec67d364SMichael Kruse                                  UMAP("{ Read[] -> Elt[] }"), ReadEltInSameInst,
854ec67d364SMichael Kruse                                  false, false));
855ec67d364SMichael Kruse     EXPECT_EQ(UMAP("{ Elt[] -> [i] : 0 < i <= 10 }"),
856ec67d364SMichael Kruse               computeArrayUnused(UMAP("{ Read[] -> [0]; Write[] -> [10] }"),
857ec67d364SMichael Kruse                                  UMAP("{ Write[] -> Elt[] }"),
858ec67d364SMichael Kruse                                  UMAP("{ Read[] -> Elt[] }"), ReadEltInSameInst,
859ec67d364SMichael Kruse                                  false, true));
860ec67d364SMichael Kruse     EXPECT_EQ(UMAP("{ Elt[] -> [i] : 0 <= i < 10 }"),
861ec67d364SMichael Kruse               computeArrayUnused(UMAP("{ Read[] -> [0]; Write[] -> [10] }"),
862ec67d364SMichael Kruse                                  UMAP("{ Write[] -> Elt[] }"),
863ec67d364SMichael Kruse                                  UMAP("{ Read[] -> Elt[] }"), ReadEltInSameInst,
864ec67d364SMichael Kruse                                  true, false));
865ec67d364SMichael Kruse     EXPECT_EQ(UMAP("{ Elt[] -> [i] : 0 <= i <= 10 }"),
866ec67d364SMichael Kruse               computeArrayUnused(UMAP("{ Read[] -> [0]; Write[] -> [10] }"),
867ec67d364SMichael Kruse                                  UMAP("{ Write[] -> Elt[] }"),
868ec67d364SMichael Kruse                                  UMAP("{ Read[] -> Elt[] }"), ReadEltInSameInst,
869ec67d364SMichael Kruse                                  true, true));
870ec67d364SMichael Kruse 
871ec67d364SMichael Kruse     // Two reads
872ec67d364SMichael Kruse     EXPECT_EQ(UMAP("{ Elt[] -> [i] : 0 < i <= 10 }"),
873ec67d364SMichael Kruse               computeArrayUnused(
874ec67d364SMichael Kruse                   UMAP("{ Read[0] -> [-10]; Read[1] -> [0]; Write[] -> [10] }"),
875ec67d364SMichael Kruse                   UMAP("{ Write[] -> Elt[] }"), UMAP("{ Read[i] -> Elt[] }"),
876ec67d364SMichael Kruse                   ReadEltInSameInst, false, true));
877ec67d364SMichael Kruse 
878ec67d364SMichael Kruse     // Corner case: no writes
879ec67d364SMichael Kruse     EXPECT_EQ(UMAP("{}"),
880ec67d364SMichael Kruse               computeArrayUnused(UMAP("{ Read[] -> [0] }"), UMAP("{}"),
881ec67d364SMichael Kruse                                  UMAP("{ Read[] -> Elt[] }"), ReadEltInSameInst,
882ec67d364SMichael Kruse                                  false, false));
883ec67d364SMichael Kruse 
884ec67d364SMichael Kruse     // Corner case: no reads
885ec67d364SMichael Kruse     EXPECT_EQ(UMAP("{ Elt[] -> [i] : i <= 0 }"),
886ec67d364SMichael Kruse               computeArrayUnused(UMAP("{ Write[] -> [0] }"),
887ec67d364SMichael Kruse                                  UMAP("{ Write[] -> Elt[] }"), UMAP("{}"),
888ec67d364SMichael Kruse                                  ReadEltInSameInst, false, true));
889ade14269SMichael Kruse 
890f281ae59SMichael Kruse     // Two writes
891f281ae59SMichael Kruse     EXPECT_EQ(
892f281ae59SMichael Kruse         UMAP("{ Elt[] -> [i] : i <= 10 }"),
893f281ae59SMichael Kruse         computeArrayUnused(UMAP("{ WriteA[] -> [0];  WriteB[] -> [10] }"),
894f281ae59SMichael Kruse                            UMAP("{ WriteA[] -> Elt[]; WriteB[] -> Elt[] }"),
895f281ae59SMichael Kruse                            UMAP("{}"), ReadEltInSameInst, false, true));
896f281ae59SMichael Kruse 
897f281ae59SMichael Kruse     // Two unused zones
898f281ae59SMichael Kruse     // read,write,read,write
899f281ae59SMichael Kruse     EXPECT_EQ(
900f281ae59SMichael Kruse         UMAP("{ Elt[] -> [i] : 0 < i <= 10; Elt[] -> [i] : 20 < i <= 30 }"),
901f281ae59SMichael Kruse         computeArrayUnused(UMAP("{ ReadA[] -> [0]; WriteA[] -> [10]; ReadB[] "
902f281ae59SMichael Kruse                                 "-> [20]; WriteB[] -> [30] }"),
903f281ae59SMichael Kruse                            UMAP("{ WriteA[] -> Elt[]; WriteB[] -> Elt[] }"),
904f281ae59SMichael Kruse                            UMAP("{ ReadA[] -> Elt[];  ReadB[] -> Elt[] }"),
905f281ae59SMichael Kruse                            ReadEltInSameInst, false, true));
906f281ae59SMichael Kruse 
907f281ae59SMichael Kruse     // write, write
908f281ae59SMichael Kruse     EXPECT_EQ(
909f281ae59SMichael Kruse         UMAP("{ Elt[] -> [i] : i <= 10 }"),
910f281ae59SMichael Kruse         computeArrayUnused(
911f281ae59SMichael Kruse             UMAP("{ WriteA[] -> [0];  WriteB[] -> [10];  Read[] -> [20] }"),
912f281ae59SMichael Kruse             UMAP("{ WriteA[] -> Elt[]; WriteB[] -> Elt[] }"),
913f281ae59SMichael Kruse             UMAP("{ Read[] -> Elt[] }"), ReadEltInSameInst, false, true));
914f281ae59SMichael Kruse 
915f281ae59SMichael Kruse     // write, read
916f281ae59SMichael Kruse     EXPECT_EQ(UMAP("{ Elt[] -> [i] : i <= 0 }"),
917f281ae59SMichael Kruse               computeArrayUnused(UMAP("{ Write[] -> [0]; Read[] -> [10] }"),
918f281ae59SMichael Kruse                                  UMAP("{ Write[] -> Elt[] }"),
919f281ae59SMichael Kruse                                  UMAP("{ Read[] -> Elt[] }"), ReadEltInSameInst,
920f281ae59SMichael Kruse                                  false, true));
921f281ae59SMichael Kruse 
922f281ae59SMichael Kruse     // read, write, read
923f281ae59SMichael Kruse     EXPECT_EQ(UMAP("{ Elt[] -> [i] : 0 < i <= 10 }"),
924f281ae59SMichael Kruse               computeArrayUnused(
925f281ae59SMichael Kruse                   UMAP("{ ReadA[] -> [0]; Write[] -> [10]; ReadB[] -> [20] }"),
926f281ae59SMichael Kruse                   UMAP("{ Write[] -> Elt[] }"),
927f281ae59SMichael Kruse                   UMAP("{ ReadA[] -> Elt[];  ReadB[] -> Elt[] }"),
928f281ae59SMichael Kruse                   ReadEltInSameInst, false, true));
929f281ae59SMichael Kruse 
930ade14269SMichael Kruse     // read, write, write
931ade14269SMichael Kruse     EXPECT_EQ(
932ade14269SMichael Kruse         UMAP("{ Elt[] -> [i] : 0 < i <= 20 }"),
933ade14269SMichael Kruse         computeArrayUnused(
934ade14269SMichael Kruse             UMAP("{ Read[] -> [0]; WriteA[] -> [10];  WriteB[] -> [20] }"),
935ade14269SMichael Kruse             UMAP("{ WriteA[] -> Elt[]; WriteB[] -> Elt[] }"),
936ade14269SMichael Kruse             UMAP("{ Read[] -> Elt[] }"), ReadEltInSameInst, false, true));
937f281ae59SMichael Kruse 
938f281ae59SMichael Kruse     // read, write, write, read
939f281ae59SMichael Kruse     EXPECT_EQ(
940f281ae59SMichael Kruse         UMAP("{ Elt[] -> [i] : 0 < i <= 20 }"),
941f281ae59SMichael Kruse         computeArrayUnused(UMAP("{ ReadA[] -> [0]; WriteA[] -> [10];  WriteB[] "
942f281ae59SMichael Kruse                                 "-> [20]; ReadB[] -> [30] }"),
943f281ae59SMichael Kruse                            UMAP("{ WriteA[] -> Elt[]; WriteB[] -> Elt[] }"),
944f281ae59SMichael Kruse                            UMAP("{ ReadA[] -> Elt[];  ReadB[] -> Elt[] }"),
945f281ae59SMichael Kruse                            ReadEltInSameInst, false, true));
946ec67d364SMichael Kruse   }
947ec67d364SMichael Kruse 
948ec67d364SMichael Kruse   // Read and write in same statement
949ec67d364SMichael Kruse   EXPECT_EQ(UMAP("{ Elt[] -> [i] : i < 0 }"),
950ec67d364SMichael Kruse             computeArrayUnused(UMAP("{ RW[] -> [0] }"),
951ec67d364SMichael Kruse                                UMAP("{ RW[] -> Elt[] }"),
952ec67d364SMichael Kruse                                UMAP("{ RW[] -> Elt[] }"), true, false, false));
953ec67d364SMichael Kruse   EXPECT_EQ(UMAP("{ Elt[] -> [i] : i <= 0 }"),
954ec67d364SMichael Kruse             computeArrayUnused(UMAP("{ RW[] -> [0] }"),
955ec67d364SMichael Kruse                                UMAP("{ RW[] -> Elt[] }"),
956ec67d364SMichael Kruse                                UMAP("{ RW[] -> Elt[] }"), true, false, true));
957ec67d364SMichael Kruse   EXPECT_EQ(UMAP("{ Elt[] -> [0] }"),
958ec67d364SMichael Kruse             computeArrayUnused(UMAP("{ RW[] -> [0] }"),
959ec67d364SMichael Kruse                                UMAP("{ RW[] -> Elt[] }"),
960ec67d364SMichael Kruse                                UMAP("{ RW[] -> Elt[] }"), false, true, true));
961ec67d364SMichael Kruse }
962ec67d364SMichael Kruse 
TEST(DeLICM,convertZoneToTimepoints)963acb08aaeSMichael Kruse TEST(DeLICM, convertZoneToTimepoints) {
964acb08aaeSMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
965acb08aaeSMichael Kruse                                                         &isl_ctx_free);
966acb08aaeSMichael Kruse 
967acb08aaeSMichael Kruse   // Corner case: empty set
968acb08aaeSMichael Kruse   EXPECT_EQ(USET("{}"), convertZoneToTimepoints(USET("{}"), false, false));
969acb08aaeSMichael Kruse   EXPECT_EQ(USET("{}"), convertZoneToTimepoints(USET("{}"), true, false));
970acb08aaeSMichael Kruse   EXPECT_EQ(USET("{}"), convertZoneToTimepoints(USET("{}"), false, true));
971acb08aaeSMichael Kruse   EXPECT_EQ(USET("{}"), convertZoneToTimepoints(USET("{}"), true, true));
972acb08aaeSMichael Kruse 
973acb08aaeSMichael Kruse   // Basic usage
974acb08aaeSMichael Kruse   EXPECT_EQ(USET("{}"), convertZoneToTimepoints(USET("{ [1] }"), false, false));
975acb08aaeSMichael Kruse   EXPECT_EQ(USET("{ [0] }"),
976acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [1] }"), true, false));
977acb08aaeSMichael Kruse   EXPECT_EQ(USET("{ [1] }"),
978acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [1] }"), false, true));
979acb08aaeSMichael Kruse   EXPECT_EQ(USET("{ [0]; [1] }"),
980acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [1] }"), true, true));
981acb08aaeSMichael Kruse 
982acb08aaeSMichael Kruse   // Non-adjacent ranges
983acb08aaeSMichael Kruse   EXPECT_EQ(USET("{}"),
984acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [1]; [11] }"), false, false));
985acb08aaeSMichael Kruse   EXPECT_EQ(USET("{ [0]; [10] }"),
986acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [1]; [11] }"), true, false));
987acb08aaeSMichael Kruse   EXPECT_EQ(USET("{ [1]; [11] }"),
988acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [1]; [11] }"), false, true));
989acb08aaeSMichael Kruse   EXPECT_EQ(USET("{ [0]; [1]; [10]; [11] }"),
990acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [1]; [11] }"), true, true));
991acb08aaeSMichael Kruse 
992acb08aaeSMichael Kruse   // Adjacent unit ranges
993acb08aaeSMichael Kruse   EXPECT_EQ(
994acb08aaeSMichael Kruse       USET("{ [i] : 0 < i < 10 }"),
995acb08aaeSMichael Kruse       convertZoneToTimepoints(USET("{ [i] : 0 < i <= 10 }"), false, false));
996acb08aaeSMichael Kruse   EXPECT_EQ(
997acb08aaeSMichael Kruse       USET("{ [i] : 0 <= i < 10 }"),
998acb08aaeSMichael Kruse       convertZoneToTimepoints(USET("{ [i] : 0 < i <= 10 }"), true, false));
999acb08aaeSMichael Kruse   EXPECT_EQ(
1000acb08aaeSMichael Kruse       USET("{ [i] : 0 < i <= 10 }"),
1001acb08aaeSMichael Kruse       convertZoneToTimepoints(USET("{ [i] : 0 < i <= 10 }"), false, true));
1002acb08aaeSMichael Kruse   EXPECT_EQ(USET("{ [i] : 0 <= i <= 10 }"),
1003acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [i] : 0 < i <= 10 }"), true, true));
1004acb08aaeSMichael Kruse 
1005acb08aaeSMichael Kruse   // More than one dimension
1006acb08aaeSMichael Kruse   EXPECT_EQ(USET("{}"),
1007acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [0,1] }"), false, false));
1008acb08aaeSMichael Kruse   EXPECT_EQ(USET("{ [0,0] }"),
1009acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [0,1] }"), true, false));
1010acb08aaeSMichael Kruse   EXPECT_EQ(USET("{ [0,1] }"),
1011acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [0,1] }"), false, true));
1012acb08aaeSMichael Kruse   EXPECT_EQ(USET("{ [0,0]; [0,1] }"),
1013acb08aaeSMichael Kruse             convertZoneToTimepoints(USET("{ [0,1] }"), true, true));
1014174f4839SMichael Kruse 
1015174f4839SMichael Kruse   // Map domains
1016174f4839SMichael Kruse   EXPECT_EQ(UMAP("{}"), convertZoneToTimepoints(UMAP("{ [1] -> [] }"),
1017174f4839SMichael Kruse                                                 isl::dim::in, false, false));
1018174f4839SMichael Kruse   EXPECT_EQ(UMAP("{ [0] -> [] }"),
1019174f4839SMichael Kruse             convertZoneToTimepoints(UMAP("{ [1] -> [] }"), isl::dim::in, true,
1020174f4839SMichael Kruse                                     false));
1021174f4839SMichael Kruse   EXPECT_EQ(UMAP("{ [1] -> [] }"),
1022174f4839SMichael Kruse             convertZoneToTimepoints(UMAP("{ [1] -> [] }"), isl::dim::in, false,
1023174f4839SMichael Kruse                                     true));
1024174f4839SMichael Kruse   EXPECT_EQ(
1025174f4839SMichael Kruse       UMAP("{ [0] -> []; [1] -> [] }"),
1026174f4839SMichael Kruse       convertZoneToTimepoints(UMAP("{ [1] -> [] }"), isl::dim::in, true, true));
1027174f4839SMichael Kruse 
1028174f4839SMichael Kruse   // Map ranges
1029174f4839SMichael Kruse   EXPECT_EQ(UMAP("{}"), convertZoneToTimepoints(UMAP("{ [] -> [1] }"),
1030174f4839SMichael Kruse                                                 isl::dim::out, false, false));
1031174f4839SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [0] }"),
1032174f4839SMichael Kruse             convertZoneToTimepoints(UMAP("{ [] -> [1] }"), isl::dim::out, true,
1033174f4839SMichael Kruse                                     false));
1034174f4839SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [1] }"),
1035174f4839SMichael Kruse             convertZoneToTimepoints(UMAP("{ [] -> [1] }"), isl::dim::out, false,
1036174f4839SMichael Kruse                                     true));
1037174f4839SMichael Kruse   EXPECT_EQ(UMAP("{ [] -> [0]; [] -> [1] }"),
1038174f4839SMichael Kruse             convertZoneToTimepoints(UMAP("{ [] -> [1] }"), isl::dim::out, true,
1039174f4839SMichael Kruse                                     true));
1040174f4839SMichael Kruse }
1041174f4839SMichael Kruse 
TEST(DeLICM,distribute)1042174f4839SMichael Kruse TEST(DeLICM, distribute) {
1043174f4839SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
1044174f4839SMichael Kruse                                                         &isl_ctx_free);
1045174f4839SMichael Kruse 
1046174f4839SMichael Kruse   // Basic usage
1047174f4839SMichael Kruse   EXPECT_EQ(MAP("{ [Domain[] -> Range1[]] -> [Domain[] -> Range2[]] }"),
1048174f4839SMichael Kruse             distributeDomain(MAP("{ Domain[] -> [Range1[] -> Range2[]] }")));
1049174f4839SMichael Kruse   EXPECT_EQ(
1050174f4839SMichael Kruse       MAP("{ [Domain[i,j] -> Range1[i,k]] -> [Domain[i,j] -> Range2[j,k]] }"),
1051174f4839SMichael Kruse       distributeDomain(MAP("{ Domain[i,j] -> [Range1[i,k] -> Range2[j,k]] }")));
1052174f4839SMichael Kruse 
1053174f4839SMichael Kruse   // Union maps
1054174f4839SMichael Kruse   EXPECT_EQ(
1055174f4839SMichael Kruse       UMAP(
1056174f4839SMichael Kruse           "{ [DomainA[i,j] -> RangeA1[i,k]] -> [DomainA[i,j] -> RangeA2[j,k]];"
1057174f4839SMichael Kruse           "[DomainB[i,j] -> RangeB1[i,k]] -> [DomainB[i,j] -> RangeB2[j,k]] }"),
1058174f4839SMichael Kruse       distributeDomain(
1059174f4839SMichael Kruse           UMAP("{ DomainA[i,j] -> [RangeA1[i,k] -> RangeA2[j,k]];"
1060174f4839SMichael Kruse                "DomainB[i,j] -> [RangeB1[i,k] -> RangeB2[j,k]] }")));
1061174f4839SMichael Kruse }
1062174f4839SMichael Kruse 
TEST(DeLICM,lift)1063174f4839SMichael Kruse TEST(DeLICM, lift) {
1064174f4839SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
1065174f4839SMichael Kruse                                                         &isl_ctx_free);
1066174f4839SMichael Kruse 
1067174f4839SMichael Kruse   // Basic usage
1068174f4839SMichael Kruse   EXPECT_EQ(UMAP("{ [Factor[] -> Domain[]] -> [Factor[] -> Range[]] }"),
1069174f4839SMichael Kruse             liftDomains(UMAP("{ Domain[] -> Range[] }"), USET("{ Factor[] }")));
1070174f4839SMichael Kruse   EXPECT_EQ(UMAP("{ [Factor[l] -> Domain[i,k]] -> [Factor[l] -> Range[j,k]] }"),
1071174f4839SMichael Kruse             liftDomains(UMAP("{ Domain[i,k] -> Range[j,k] }"),
1072174f4839SMichael Kruse                         USET("{ Factor[l] }")));
1073174f4839SMichael Kruse 
1074174f4839SMichael Kruse   // Multiple maps in union
1075174f4839SMichael Kruse   EXPECT_EQ(
1076174f4839SMichael Kruse       UMAP("{ [FactorA[] -> DomainA[]] -> [FactorA[] -> RangeA[]];"
1077174f4839SMichael Kruse            "[FactorB[] -> DomainA[]] -> [FactorB[] -> RangeA[]];"
1078174f4839SMichael Kruse            "[FactorA[] -> DomainB[]] -> [FactorA[] -> RangeB[]];"
1079174f4839SMichael Kruse            "[FactorB[] -> DomainB[]] -> [FactorB[] -> RangeB[]] }"),
1080174f4839SMichael Kruse       liftDomains(UMAP("{ DomainA[] -> RangeA[]; DomainB[] -> RangeB[] }"),
1081174f4839SMichael Kruse                   USET("{ FactorA[]; FactorB[] }")));
1082174f4839SMichael Kruse }
1083174f4839SMichael Kruse 
TEST(DeLICM,apply)1084174f4839SMichael Kruse TEST(DeLICM, apply) {
1085174f4839SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
1086174f4839SMichael Kruse                                                         &isl_ctx_free);
1087174f4839SMichael Kruse 
1088174f4839SMichael Kruse   // Basic usage
1089174f4839SMichael Kruse   EXPECT_EQ(
1090174f4839SMichael Kruse       UMAP("{ [DomainDomain[] -> NewDomainRange[]] -> Range[] }"),
1091174f4839SMichael Kruse       applyDomainRange(UMAP("{ [DomainDomain[] -> DomainRange[]] -> Range[] }"),
1092174f4839SMichael Kruse                        UMAP("{ DomainRange[] -> NewDomainRange[] }")));
1093174f4839SMichael Kruse   EXPECT_EQ(
1094174f4839SMichael Kruse       UMAP("{ [DomainDomain[i,k] -> NewDomainRange[j,k,l]] -> Range[i,j] }"),
1095174f4839SMichael Kruse       applyDomainRange(
1096174f4839SMichael Kruse           UMAP("{ [DomainDomain[i,k] -> DomainRange[j,k]] -> Range[i,j] }"),
1097174f4839SMichael Kruse           UMAP("{ DomainRange[j,k] -> NewDomainRange[j,k,l] }")));
1098174f4839SMichael Kruse 
1099174f4839SMichael Kruse   // Multiple maps in union
1100174f4839SMichael Kruse   EXPECT_EQ(UMAP("{ [DomainDomainA[] -> NewDomainRangeA[]] -> RangeA[];"
1101174f4839SMichael Kruse                  "[DomainDomainB[] -> NewDomainRangeB[]] -> RangeB[] }"),
1102174f4839SMichael Kruse             applyDomainRange(
1103174f4839SMichael Kruse                 UMAP("{ [DomainDomainA[] -> DomainRangeA[]] -> RangeA[];"
1104174f4839SMichael Kruse                      "[DomainDomainB[] -> DomainRangeB[]] -> RangeB[] }"),
1105174f4839SMichael Kruse                 UMAP("{ DomainRangeA[] -> NewDomainRangeA[];"
1106174f4839SMichael Kruse                      "DomainRangeB[] -> NewDomainRangeB[] }")));
1107acb08aaeSMichael Kruse }
11080f50ffb3SMichael Kruse 
TEST(Isl,Quota)11090f50ffb3SMichael Kruse TEST(Isl, Quota) {
11100f50ffb3SMichael Kruse   std::unique_ptr<isl_ctx, decltype(&isl_ctx_free)> Ctx(isl_ctx_alloc(),
11110f50ffb3SMichael Kruse                                                         &isl_ctx_free);
11120f50ffb3SMichael Kruse 
11130f50ffb3SMichael Kruse   isl::set TestSet1{Ctx.get(), "{ [0] }"};
11140f50ffb3SMichael Kruse   isl::set TestSet2{Ctx.get(), "{ [i] : i > 0 }"};
11150f50ffb3SMichael Kruse 
11160f50ffb3SMichael Kruse   {
11170f50ffb3SMichael Kruse     IslMaxOperationsGuard MaxOpGuard(Ctx.get(), 1);
11180f50ffb3SMichael Kruse     ASSERT_EQ(isl_options_get_on_error(Ctx.get()), ISL_ON_ERROR_CONTINUE);
11190f50ffb3SMichael Kruse     ASSERT_EQ(isl_ctx_get_max_operations(Ctx.get()), 1ul);
11200f50ffb3SMichael Kruse     ASSERT_FALSE(MaxOpGuard.hasQuotaExceeded());
11210f50ffb3SMichael Kruse 
11220f50ffb3SMichael Kruse     // Intentionally exceed the quota. Each allocation will use at least one
11230f50ffb3SMichael Kruse     // operation, guaranteed to exceed the max_operations of 1.
11240f50ffb3SMichael Kruse     isl::id::alloc(Ctx.get(), "A", nullptr);
11250f50ffb3SMichael Kruse     isl::id::alloc(Ctx.get(), "B", nullptr);
11260f50ffb3SMichael Kruse     ASSERT_TRUE(MaxOpGuard.hasQuotaExceeded());
11270f50ffb3SMichael Kruse 
11280f50ffb3SMichael Kruse     // Check returned object after exceeded quota.
11290f50ffb3SMichael Kruse     isl::set Union = TestSet1.unite(TestSet2);
11300f50ffb3SMichael Kruse     EXPECT_TRUE(Union.is_null());
11310f50ffb3SMichael Kruse 
11320f50ffb3SMichael Kruse     // Check isl::boolean result after exceeded quota.
11330f50ffb3SMichael Kruse     isl::boolean BoolResult = TestSet1.is_empty();
11340f50ffb3SMichael Kruse     EXPECT_TRUE(BoolResult.is_error());
11350f50ffb3SMichael Kruse     EXPECT_FALSE(BoolResult.is_false());
11360f50ffb3SMichael Kruse     EXPECT_FALSE(BoolResult.is_true());
11375a6d7706SMichael Kruse     EXPECT_DEATH((void)(bool)BoolResult,
11380f50ffb3SMichael Kruse                  "IMPLEMENTATION ERROR: Unhandled error state");
11395a6d7706SMichael Kruse     EXPECT_DEATH((void)(bool)!BoolResult,
11400f50ffb3SMichael Kruse                  "IMPLEMENTATION ERROR: Unhandled error state");
11410f50ffb3SMichael Kruse     EXPECT_DEATH(
11420f50ffb3SMichael Kruse         {
11430f50ffb3SMichael Kruse           if (BoolResult) {
11440f50ffb3SMichael Kruse           }
11450f50ffb3SMichael Kruse         },
11460f50ffb3SMichael Kruse         "IMPLEMENTATION ERROR: Unhandled error state");
11470f50ffb3SMichael Kruse     EXPECT_DEATH((void)(BoolResult == false),
11480f50ffb3SMichael Kruse                  "IMPLEMENTATION ERROR: Unhandled error state");
11490f50ffb3SMichael Kruse     EXPECT_DEATH((void)(BoolResult == true),
11500f50ffb3SMichael Kruse                  "IMPLEMENTATION ERROR: Unhandled error state");
11510f50ffb3SMichael Kruse 
11520f50ffb3SMichael Kruse     // Check isl::stat result after exceeded quota.
11530f50ffb3SMichael Kruse     isl::stat StatResult =
11540f50ffb3SMichael Kruse         TestSet1.foreach_point([](isl::point) { return isl::stat::ok(); });
11550f50ffb3SMichael Kruse     EXPECT_TRUE(StatResult.is_error());
11560f50ffb3SMichael Kruse     EXPECT_FALSE(StatResult.is_ok());
11570f50ffb3SMichael Kruse   }
11580f50ffb3SMichael Kruse   ASSERT_EQ(isl_ctx_last_error(Ctx.get()), isl_error_quota);
11590f50ffb3SMichael Kruse   ASSERT_EQ(isl_options_get_on_error(Ctx.get()), ISL_ON_ERROR_WARN);
11600f50ffb3SMichael Kruse   ASSERT_EQ(isl_ctx_get_max_operations(Ctx.get()), 0ul);
11610f50ffb3SMichael Kruse 
11620f50ffb3SMichael Kruse   // Operations must work again after leaving the quota scope.
11630f50ffb3SMichael Kruse   {
11640f50ffb3SMichael Kruse     isl::set Union = TestSet1.unite(TestSet2);
11650f50ffb3SMichael Kruse     EXPECT_FALSE(Union.is_null());
11660f50ffb3SMichael Kruse 
11670f50ffb3SMichael Kruse     isl::boolean BoolResult = TestSet1.is_empty();
11680f50ffb3SMichael Kruse     EXPECT_FALSE(BoolResult.is_error());
11690f50ffb3SMichael Kruse     EXPECT_TRUE(BoolResult.is_false());
11700f50ffb3SMichael Kruse     EXPECT_FALSE(BoolResult.is_true());
11710f50ffb3SMichael Kruse     EXPECT_FALSE(BoolResult);
11720f50ffb3SMichael Kruse     EXPECT_TRUE(!BoolResult);
11730f50ffb3SMichael Kruse 
11740f50ffb3SMichael Kruse     isl::stat StatResult =
11750f50ffb3SMichael Kruse         TestSet1.foreach_point([](isl::point) { return isl::stat::ok(); });
11760f50ffb3SMichael Kruse     EXPECT_FALSE(StatResult.is_error());
11770f50ffb3SMichael Kruse     EXPECT_TRUE(StatResult.is_ok());
11780f50ffb3SMichael Kruse   }
11790f50ffb3SMichael Kruse }
11800f50ffb3SMichael Kruse 
118105cf9c22SMichael Kruse } // anonymous namespace
1182