239 lines · plain
1// RUN: mlir-opt %s -pass-pipeline='builtin.module(func.func(test-affine-reify-value-bounds))' -verify-diagnostics \2// RUN: -split-input-file | FileCheck %s3 4// CHECK: #[[$map:.*]] = affine_map<()[s0, s1] -> (s0 + s1)>5// CHECK-LABEL: func @affine_apply(6// CHECK-SAME: %[[a:.*]]: index, %[[b:.*]]: index7// CHECK: %[[apply:.*]] = affine.apply #[[$map]]()[%[[a]], %[[b]]]8// CHECK: %[[apply:.*]] = affine.apply #[[$map]]()[%[[a]], %[[b]]]9// CHECK: return %[[apply]]10func.func @affine_apply(%a: index, %b: index) -> index {11 %0 = affine.apply affine_map<()[s0, s1] -> (s0 + s1)>()[%a, %b]12 %1 = "test.reify_bound"(%0) : (index) -> (index)13 return %1 : index14}15 16// -----17 18// CHECK-LABEL: func @affine_max_lb(19// CHECK-SAME: %[[a:.*]]: index20// CHECK: %[[c2:.*]] = arith.constant 2 : index21// CHECK: return %[[c2]]22func.func @affine_max_lb(%a: index) -> (index) {23 // Note: There are two LBs: s0 and 2. FlatAffineValueConstraints always24 // returns the constant one at the moment.25 %1 = affine.max affine_map<()[s0] -> (s0, 2)>()[%a]26 %2 = "test.reify_bound"(%1) {type = "LB"}: (index) -> (index)27 return %2 : index28}29 30// -----31 32func.func @affine_max_ub(%a: index) -> (index) {33 %1 = affine.max affine_map<()[s0] -> (s0, 2)>()[%a]34 // expected-error @below{{could not reify bound}}35 %2 = "test.reify_bound"(%1) {type = "UB"}: (index) -> (index)36 return %2 : index37}38 39// -----40 41// CHECK-LABEL: func @affine_min_ub(42// CHECK-SAME: %[[a:.*]]: index43// CHECK: %[[c3:.*]] = arith.constant 3 : index44// CHECK: return %[[c3]]45func.func @affine_min_ub(%a: index) -> (index) {46 // Note: There are two UBs: s0 + 1 and 3. FlatAffineValueConstraints always47 // returns the constant one at the moment.48 %1 = affine.min affine_map<()[s0] -> (s0, 2)>()[%a]49 %2 = "test.reify_bound"(%1) {type = "UB"}: (index) -> (index)50 return %2 : index51}52 53// -----54 55func.func @affine_min_lb(%a: index) -> (index) {56 %1 = affine.min affine_map<()[s0] -> (s0, 2)>()[%a]57 // expected-error @below{{could not reify bound}}58 %2 = "test.reify_bound"(%1) {type = "LB"}: (index) -> (index)59 return %2 : index60}61 62// -----63 64// CHECK-LABEL: func @composed_affine_apply(65// CHECK: %[[cst:.*]] = arith.constant -8 : index66// CHECK: return %[[cst]]67func.func @composed_affine_apply(%i1 : index) -> (index) {68 // The ValueBoundsOpInterface implementation of affine.apply fully composes69 // the affine map (and its operands) with other affine.apply ops drawn from70 // its operands before adding it to the constraint set. This is to work71 // around a limitation in `FlatLinearConstraints`, which can currently not72 // compute a constant bound for %s. (The affine map simplification logic can73 // simplify %s to -8.)74 %i2 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16)>(%i1)75 %i3 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16 + 8)>(%i1)76 %s = affine.apply affine_map<()[s0, s1] -> (s0 - s1)>()[%i2, %i3]77 %reified = "test.reify_bound"(%s) {type = "EQ", constant} : (index) -> (index)78 return %reified : index79}80 81 82// -----83 84func.func @are_equal(%i1 : index) {85 %i2 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16)>(%i1)86 %i3 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16 + 8)>(%i1)87 %s = affine.apply affine_map<()[s0, s1] -> (s0 - s1)>()[%i2, %i3]88 // expected-remark @below{{false}}89 "test.compare"(%i2, %i3) : (index, index) -> ()90 return91}92 93// -----94 95// Test for affine::fullyComposeAndCheckIfEqual96func.func @composed_are_equal(%i1 : index) {97 %i2 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16)>(%i1)98 %i3 = affine.apply affine_map<(d0) -> ((d0 floordiv 32) * 16 + 8)>(%i1)99 %s = affine.apply affine_map<()[s0, s1] -> (s0 - s1)>()[%i2, %i3]100 // expected-remark @below{{different}}101 "test.compare"(%i2, %i3) {compose} : (index, index) -> ()102 return103}104 105// -----106 107func.func @compare_affine_max(%a: index, %b: index) {108 %0 = affine.max affine_map<()[s0, s1] -> (s0, s1)>()[%a, %b]109 // expected-remark @below{{true}}110 "test.compare"(%0, %a) {cmp = "GE"} : (index, index) -> ()111 // expected-error @below{{unknown}}112 "test.compare"(%0, %a) {cmp = "GT"} : (index, index) -> ()113 // expected-remark @below{{false}}114 "test.compare"(%0, %a) {cmp = "LT"} : (index, index) -> ()115 // expected-error @below{{unknown}}116 "test.compare"(%0, %a) {cmp = "LE"} : (index, index) -> ()117 return118}119 120// -----121 122func.func @compare_affine_min(%a: index, %b: index) {123 %0 = affine.min affine_map<()[s0, s1] -> (s0, s1)>()[%a, %b]124 // expected-error @below{{unknown}}125 "test.compare"(%0, %a) {cmp = "GE"} : (index, index) -> ()126 // expected-remark @below{{false}}127 "test.compare"(%0, %a) {cmp = "GT"} : (index, index) -> ()128 // expected-error @below{{unknown}}129 "test.compare"(%0, %a) {cmp = "LT"} : (index, index) -> ()130 // expected-remark @below{{true}}131 "test.compare"(%0, %a) {cmp = "LE"} : (index, index) -> ()132 return133}134 135// -----136 137func.func @compare_const_map() {138 %c5 = arith.constant 5 : index139 // expected-remark @below{{true}}140 "test.compare"(%c5) {cmp = "GT", rhs_map = affine_map<() -> (4)>}141 : (index) -> ()142 // expected-remark @below{{true}}143 "test.compare"(%c5) {cmp = "LT", lhs_map = affine_map<() -> (4)>}144 : (index) -> ()145 return146}147 148// -----149 150func.func @compare_maps(%a: index, %b: index) {151 // expected-remark @below{{true}}152 "test.compare"(%a, %b, %b, %a)153 {cmp = "GT", lhs_map = affine_map<(d0, d1) -> (1 + d0 + d1)>,154 rhs_map = affine_map<(d0, d1) -> (d0 + d1)>}155 : (index, index, index, index) -> ()156 return157}158 159// -----160 161// CHECK-DAG: #[[$map1:.+]] = affine_map<()[s0] -> (s0 floordiv 15)>162// CHECK-DAG: #[[$map2:.+]] = affine_map<()[s0] -> ((s0 mod 15) floordiv 5)>163// CHECK-DAG: #[[$map3:.+]] = affine_map<()[s0] -> (s0 mod 5)>164// CHECK-LABEL: func.func @delinearize_static165// CHECK-SAME: (%[[arg0:.+]]: index)166// CHECK-DAG: %[[v1:.+]] = affine.apply #[[$map1]]()[%[[arg0]]]167// CHECK-DAG: %[[v2:.+]] = affine.apply #[[$map2]]()[%[[arg0]]]168// CHECK-DAG: %[[v3:.+]] = affine.apply #[[$map3]]()[%[[arg0]]]169// CHECK: return %[[v1]], %[[v2]], %[[v3]]170func.func @delinearize_static(%arg0: index) -> (index, index, index) {171 %c2 = arith.constant 2 : index172 %c3 = arith.constant 3 : index173 %0:3 = affine.delinearize_index %arg0 into (2, 3, 5) : index, index, index174 %1 = "test.reify_bound"(%0#0) {type = "EQ"} : (index) -> (index)175 %2 = "test.reify_bound"(%0#1) {type = "EQ"} : (index) -> (index)176 %3 = "test.reify_bound"(%0#2) {type = "EQ"} : (index) -> (index)177 // expected-remark @below{{true}}178 "test.compare"(%0#0, %c2) {cmp = "LT"} : (index, index) -> ()179 // expected-remark @below{{true}}180 "test.compare"(%0#1, %c3) {cmp = "LT"} : (index, index) -> ()181 return %1, %2, %3 : index, index, index182}183 184// -----185 186// CHECK-DAG: #[[$map1:.+]] = affine_map<()[s0] -> (s0 floordiv 15)>187// CHECK-DAG: #[[$map2:.+]] = affine_map<()[s0] -> ((s0 mod 15) floordiv 5)>188// CHECK-DAG: #[[$map3:.+]] = affine_map<()[s0] -> (s0 mod 5)>189// CHECK-LABEL: func.func @delinearize_static_no_outer_bound190// CHECK-SAME: (%[[arg0:.+]]: index)191// CHECK-DAG: %[[v1:.+]] = affine.apply #[[$map1]]()[%[[arg0]]]192// CHECK-DAG: %[[v2:.+]] = affine.apply #[[$map2]]()[%[[arg0]]]193// CHECK-DAG: %[[v3:.+]] = affine.apply #[[$map3]]()[%[[arg0]]]194// CHECK: return %[[v1]], %[[v2]], %[[v3]]195func.func @delinearize_static_no_outer_bound(%arg0: index) -> (index, index, index) {196 %c2 = arith.constant 2 : index197 %c3 = arith.constant 3 : index198 %0:3 = affine.delinearize_index %arg0 into (3, 5) : index, index, index199 %1 = "test.reify_bound"(%0#0) {type = "EQ"} : (index) -> (index)200 %2 = "test.reify_bound"(%0#1) {type = "EQ"} : (index) -> (index)201 %3 = "test.reify_bound"(%0#2) {type = "EQ"} : (index) -> (index)202 "test.compaare"(%0#0, %c2) {cmp = "LT"} : (index, index) -> ()203 // expected-remark @below{{true}}204 "test.compare"(%0#1, %c3) {cmp = "LT"} : (index, index) -> ()205 return %1, %2, %3 : index, index, index206}207 208// -----209 210// CHECK: #[[$map:.+]] = affine_map<()[s0, s1] -> (s0 + s1 * 3)>211// CHECK-LABEL: func.func @linearize_static212// CHECK-SAME: (%[[arg0:.+]]: index, %[[arg1:.+]]: index)213// CHECK: %[[v1:.+]] = affine.apply #[[$map]]()[%[[arg1]], %[[arg0]]]214// CHECK: return %[[v1]]215func.func @linearize_static(%arg0: index, %arg1: index) -> index {216 %c6 = arith.constant 6 : index217 %0 = affine.linearize_index disjoint [%arg0, %arg1] by (2, 3) : index218 %1 = "test.reify_bound"(%0) {type = "EQ"} : (index) -> (index)219 // expected-remark @below{{true}}220 "test.compare"(%0, %c6) {cmp = "LT"} : (index, index) -> ()221 return %1 : index222}223 224// -----225 226// CHECK: #[[$map:.+]] = affine_map<()[s0, s1] -> (s0 + s1 * 3)>227// CHECK-LABEL: func.func @linearize_static_no_outer_bound228// CHECK-SAME: (%[[arg0:.+]]: index, %[[arg1:.+]]: index)229// CHECK: %[[v1:.+]] = affine.apply #[[$map]]()[%[[arg1]], %[[arg0]]]230// CHECK: return %[[v1]]231func.func @linearize_static_no_outer_bound(%arg0: index, %arg1: index) -> index {232 %c6 = arith.constant 6 : index233 %0 = affine.linearize_index disjoint [%arg0, %arg1] by (3) : index234 %1 = "test.reify_bound"(%0) {type = "EQ"} : (index) -> (index)235 // expected-error @below{{unknown}}236 "test.compare"(%0, %c6) {cmp = "LT"} : (index, index) -> ()237 return %1 : index238}239