1 //===- AffineStructuresParserTest.cpp - FAC parsing unit tests --*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains tests for parsing IntegerSets to FlatAffineConstraints. 10 // The tests with invalid input check that the parser only accepts well-formed 11 // IntegerSets. The tests with well-formed input compare the returned FACs to 12 // manually constructed FACs with a PresburgerSet equality check. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "./AffineStructuresParser.h" 17 #include "mlir/Analysis/Presburger/PresburgerSet.h" 18 19 #include <gtest/gtest.h> 20 21 namespace mlir { 22 23 /// Construct a FlatAffineConstraints from a set of inequality, equality, and 24 /// division onstraints. 25 static FlatAffineConstraints makeFACFromConstraints( 26 unsigned dims, unsigned syms, ArrayRef<SmallVector<int64_t, 4>> ineqs, 27 ArrayRef<SmallVector<int64_t, 4>> eqs = {}, 28 ArrayRef<std::pair<SmallVector<int64_t, 4>, int64_t>> divs = {}) { 29 FlatAffineConstraints fac(ineqs.size(), eqs.size(), dims + syms + 1, dims, 30 syms, 0); 31 for (const auto &div : divs) 32 fac.addLocalFloorDiv(div.first, div.second); 33 for (const auto &eq : eqs) 34 fac.addEquality(eq); 35 for (const auto &ineq : ineqs) 36 fac.addInequality(ineq); 37 return fac; 38 } 39 40 TEST(ParseFACTest, InvalidInputTest) { 41 MLIRContext context; 42 FailureOr<FlatAffineConstraints> fac; 43 44 fac = parseIntegerSetToFAC("(x)", &context, false); 45 EXPECT_TRUE(failed(fac)) 46 << "should not accept strings with no constraint list"; 47 48 fac = parseIntegerSetToFAC("(x)[] : ())", &context, false); 49 EXPECT_TRUE(failed(fac)) 50 << "should not accept strings that contain remaining characters"; 51 52 fac = parseIntegerSetToFAC("(x)[] : (x - >= 0)", &context, false); 53 EXPECT_TRUE(failed(fac)) 54 << "should not accept strings that contain incomplete constraints"; 55 56 fac = parseIntegerSetToFAC("(x)[] : (y == 0)", &context, false); 57 EXPECT_TRUE(failed(fac)) 58 << "should not accept strings that contain unkown identifiers"; 59 60 fac = parseIntegerSetToFAC("(x, x) : (2 * x >= 0)", &context, false); 61 EXPECT_TRUE(failed(fac)) 62 << "should not accept strings that contain repeated identifier names"; 63 64 fac = parseIntegerSetToFAC("(x)[x] : (2 * x >= 0)", &context, false); 65 EXPECT_TRUE(failed(fac)) 66 << "should not accept strings that contain repeated identifier names"; 67 68 fac = parseIntegerSetToFAC("(x) : (2 * x + 9223372036854775808 >= 0)", 69 &context, false); 70 EXPECT_TRUE(failed(fac)) << "should not accept strings with integer literals " 71 "that do not fit into int64_t"; 72 } 73 74 /// Parses and compares the `str` to the `ex`. The equality check is performed 75 /// by using PresburgerSet::isEqual 76 static bool parseAndCompare(StringRef str, const FlatAffineConstraints &ex, 77 MLIRContext *context) { 78 FailureOr<FlatAffineConstraints> fac = parseIntegerSetToFAC(str, context); 79 80 EXPECT_TRUE(succeeded(fac)); 81 82 return PresburgerSet(*fac).isEqual(PresburgerSet(ex)); 83 } 84 85 TEST(ParseFACTest, ParseAndCompareTest) { 86 MLIRContext context; 87 // simple ineq 88 EXPECT_TRUE(parseAndCompare( 89 "(x)[] : (x >= 0)", makeFACFromConstraints(1, 0, {{1, 0}}), &context)); 90 91 // simple eq 92 EXPECT_TRUE(parseAndCompare("(x)[] : (x == 0)", 93 makeFACFromConstraints(1, 0, {}, {{1, 0}}), 94 &context)); 95 96 // multiple constraints 97 EXPECT_TRUE(parseAndCompare("(x)[] : (7 * x >= 0, -7 * x + 5 >= 0)", 98 makeFACFromConstraints(1, 0, {{7, 0}, {-7, 5}}), 99 &context)); 100 101 // multiple dimensions 102 EXPECT_TRUE(parseAndCompare("(x,y,z)[] : (x + y - z >= 0)", 103 makeFACFromConstraints(3, 0, {{1, 1, -1, 0}}), 104 &context)); 105 106 // dimensions and symbols 107 EXPECT_TRUE(parseAndCompare( 108 "(x,y,z)[a,b] : (x + y - z + 2 * a - 15 * b >= 0)", 109 makeFACFromConstraints(3, 2, {{1, 1, -1, 2, -15, 0}}), &context)); 110 111 // only symbols 112 EXPECT_TRUE(parseAndCompare("()[a] : (2 * a - 4 == 0)", 113 makeFACFromConstraints(0, 1, {}, {{2, -4}}), 114 &context)); 115 116 // simple floordiv 117 EXPECT_TRUE(parseAndCompare( 118 "(x, y) : (y - 3 * ((x + y - 13) floordiv 3) - 42 == 0)", 119 makeFACFromConstraints(2, 0, {}, {{0, 1, -3, -42}}, {{{1, 1, -13}, 3}}), 120 &context)); 121 122 // multiple floordiv 123 EXPECT_TRUE(parseAndCompare( 124 "(x, y) : (y - x floordiv 3 - y floordiv 2 == 0)", 125 makeFACFromConstraints(2, 0, {}, {{0, 1, -1, -1, 0}}, 126 {{{1, 0, 0}, 3}, {{0, 1, 0, 0}, 2}}), 127 &context)); 128 129 // nested floordiv 130 EXPECT_TRUE(parseAndCompare( 131 "(x, y) : (y - (x + y floordiv 2) floordiv 3 == 0)", 132 makeFACFromConstraints(2, 0, {}, {{0, 1, 0, -1, 0}}, 133 {{{0, 1, 0}, 2}, {{1, 0, 1, 0}, 3}}), 134 &context)); 135 } 136 137 } // namespace mlir 138