brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.0 KiB · 339d97d Raw
382 lines · plain
1// RUN: mlir-opt %s -pass-pipeline='builtin.module(func.func(test-affine-reify-value-bounds{reify-to-func-args}))' \2// RUN:     -verify-diagnostics -split-input-file | FileCheck %s3 4// CHECK-LABEL: func @scf_for(5//  CHECK-SAME:     %[[a:.*]]: index, %[[b:.*]]: index, %[[c:.*]]: index6//       CHECK:   "test.some_use"(%[[a]], %[[b]])7func.func @scf_for(%a: index, %b: index, %c: index) {8  scf.for %iv = %a to %b step %c {9    %0 = "test.reify_bound"(%iv) {type = "LB"} : (index) -> (index)10    %1 = "test.reify_bound"(%iv) {type = "UB"} : (index) -> (index)11    "test.some_use"(%0, %1) : (index, index) -> ()12  }13  return14}15 16// -----17 18// CHECK-LABEL: func @scf_for_index_result_small(19//  CHECK-SAME:     %[[i:.*]]: index, %[[a:.*]]: index, %[[b:.*]]: index, %[[c:.*]]: index20//       CHECK:   "test.some_use"(%[[i]])21//       CHECK:   "test.some_use"(%[[i]])22func.func @scf_for_index_result_small(%i: index, %a: index, %b: index, %c: index) {23  %0 = scf.for %iv = %a to %b step %c iter_args(%arg = %i) -> index {24    %1 = "test.reify_bound"(%arg) {type = "EQ"} : (index) -> (index)25    "test.some_use"(%1) : (index) -> ()26    scf.yield %arg : index27  }28  %2 = "test.reify_bound"(%0) {type = "EQ"} : (index) -> (index)29  "test.some_use"(%2) : (index) -> ()30  return31}32 33// -----34 35// CHECK-LABEL: func @scf_for_index_result(36//  CHECK-SAME:     %[[i:.*]]: index, %[[a:.*]]: index, %[[b:.*]]: index, %[[c:.*]]: index37//       CHECK:   "test.some_use"(%[[i]])38//       CHECK:   "test.some_use"(%[[i]])39func.func @scf_for_index_result(%i: index, %a: index, %b: index, %c: index) {40  %0 = scf.for %iv = %a to %b step %c iter_args(%arg = %i) -> index {41    %add = arith.addi %arg, %a : index42    %sub = arith.subi %add, %a : index43 44    %1 = "test.reify_bound"(%arg) {type = "EQ"} : (index) -> (index)45    "test.some_use"(%1) : (index) -> ()46    scf.yield %sub : index47  }48  %2 = "test.reify_bound"(%0) {type = "EQ"} : (index) -> (index)49  "test.some_use"(%2) : (index) -> ()50  return51}52 53// -----54 55// CHECK-LABEL: func @scf_for_tensor_result_small(56//  CHECK-SAME:     %[[t:.*]]: tensor<?xf32>, %[[a:.*]]: index, %[[b:.*]]: index, %[[c:.*]]: index57//       CHECK:   %[[dim:.*]] = tensor.dim %[[t]]58//       CHECK:   "test.some_use"(%[[dim]])59//       CHECK:   %[[dim:.*]] = tensor.dim %[[t]]60//       CHECK:   "test.some_use"(%[[dim]])61func.func @scf_for_tensor_result_small(%t: tensor<?xf32>, %a: index, %b: index, %c: index) {62  %0 = scf.for %iv = %a to %b step %c iter_args(%arg = %t) -> tensor<?xf32> {63    %1 = "test.reify_bound"(%arg) {type = "EQ", dim = 0} : (tensor<?xf32>) -> (index)64    "test.some_use"(%1) : (index) -> ()65    scf.yield %arg : tensor<?xf32>66  }67  %2 = "test.reify_bound"(%0) {type = "EQ", dim = 0} : (tensor<?xf32>) -> (index)68  "test.some_use"(%2) : (index) -> ()69  return70}71 72// -----73 74// CHECK-LABEL: func @scf_for_tensor_result(75//  CHECK-SAME:     %[[t:.*]]: tensor<?xf32>, %[[a:.*]]: index, %[[b:.*]]: index, %[[c:.*]]: index76//       CHECK:   %[[dim:.*]] = tensor.dim %[[t]]77//       CHECK:   "test.some_use"(%[[dim]])78//       CHECK:   %[[dim:.*]] = tensor.dim %[[t]]79//       CHECK:   "test.some_use"(%[[dim]])80func.func @scf_for_tensor_result(%t: tensor<?xf32>, %a: index, %b: index, %c: index) {81  %cst = arith.constant 5.0 : f3282  %0 = scf.for %iv = %a to %b step %c iter_args(%arg = %t) -> tensor<?xf32> {83    %filled = linalg.fill ins(%cst : f32) outs(%arg : tensor<?xf32>) -> tensor<?xf32>84    %1 = "test.reify_bound"(%arg) {type = "EQ", dim = 0} : (tensor<?xf32>) -> (index)85    "test.some_use"(%1) : (index) -> ()86    scf.yield %filled : tensor<?xf32>87  }88  %2 = "test.reify_bound"(%0) {type = "EQ", dim = 0} : (tensor<?xf32>) -> (index)89  "test.some_use"(%2) : (index) -> ()90  return91}92 93// -----94 95func.func @scf_for_swapping_yield(%t1: tensor<?xf32>, %t2: tensor<?xf32>, %a: index, %b: index, %c: index) {96  %cst = arith.constant 5.0 : f3297  %r1, %r2 = scf.for %iv = %a to %b step %c iter_args(%arg1 = %t1, %arg2 = %t2) -> (tensor<?xf32>, tensor<?xf32>) {98    %filled1 = linalg.fill ins(%cst : f32) outs(%arg1 : tensor<?xf32>) -> tensor<?xf32>99    %filled2 = linalg.fill ins(%cst : f32) outs(%arg2 : tensor<?xf32>) -> tensor<?xf32>100    scf.yield %filled2, %filled1 : tensor<?xf32>, tensor<?xf32>101  }102  // expected-error @below{{could not reify bound}}103  %reify1 = "test.reify_bound"(%r1) {type = "EQ", dim = 0} : (tensor<?xf32>) -> (index)104  "test.some_use"(%reify1) : (index) -> ()105  return106}107 108// -----109 110// CHECK-LABEL: func @scf_forall(111//  CHECK-SAME:     %[[a:.*]]: index, %[[b:.*]]: index, %[[c:.*]]: index112//       CHECK:   "test.some_use"(%[[a]], %[[b]])113func.func @scf_forall(%a: index, %b: index, %c: index) {114  scf.forall (%iv) = (%a) to (%b) step (%c) {115    %0 = "test.reify_bound"(%iv) {type = "LB"} : (index) -> (index)116    %1 = "test.reify_bound"(%iv) {type = "UB"} : (index) -> (index)117    "test.some_use"(%0, %1) : (index, index) -> ()118  }119  return120}121 122// -----123 124// CHECK-LABEL: func @scf_forall_tensor_result(125//  CHECK-SAME:     %[[size:.*]]: index, %[[a:.*]]: index, %[[b:.*]]: index, %[[c:.*]]: index126//       CHECK:   "test.some_use"(%[[size]])127//       CHECK:   "test.some_use"(%[[size]])128func.func @scf_forall_tensor_result(%size: index, %a: index, %b: index, %c: index) {129  %cst = arith.constant 5.0 : f32130  %empty = tensor.empty(%size) : tensor<?xf32>131  %0 = scf.forall (%iv) = (%a) to (%b) step (%c) shared_outs(%arg = %empty) -> tensor<?xf32> {132    %filled = linalg.fill ins(%cst : f32) outs(%arg : tensor<?xf32>) -> tensor<?xf32>133    %1 = "test.reify_bound"(%arg) {type = "EQ", dim = 0} : (tensor<?xf32>) -> (index)134    "test.some_use"(%1) : (index) -> ()135    scf.forall.in_parallel {136      tensor.parallel_insert_slice %filled into %arg[0][%size][1] : tensor<?xf32> into tensor<?xf32>137    }138  }139  %2 = "test.reify_bound"(%0) {type = "EQ", dim = 0} : (tensor<?xf32>) -> (index)140  "test.some_use"(%2) : (index) -> ()141  return142}143 144// -----145 146// CHECK-LABEL: func @scf_if_constant(147func.func @scf_if_constant(%c : i1) {148  // CHECK: arith.constant 4 : index149  // CHECK: arith.constant 9 : index150  %c4 = arith.constant 4 : index151  %c9 = arith.constant 9 : index152  %r = scf.if %c -> index {153    scf.yield %c4 : index154  } else {155    scf.yield %c9 : index156  }157 158  // CHECK: %[[c4:.*]] = arith.constant 4 : index159  // CHECK: %[[c10:.*]] = arith.constant 10 : index160  %reify1 = "test.reify_bound"(%r) {type = "LB"} : (index) -> (index)161  %reify2 = "test.reify_bound"(%r) {type = "UB"} : (index) -> (index)162  // CHECK: "test.some_use"(%[[c4]], %[[c10]])163  "test.some_use"(%reify1, %reify2) : (index, index) -> ()164  return165}166 167// -----168 169// CHECK: #[[$map:.*]] = affine_map<()[s0, s1] -> (s0 + s1)>170// CHECK: #[[$map1:.*]] = affine_map<()[s0, s1] -> (s0 + s1 + 5)>171// CHECK-LABEL: func @scf_if_dynamic(172//  CHECK-SAME:     %[[a:.*]]: index, %[[b:.*]]: index, %{{.*}}: i1)173func.func @scf_if_dynamic(%a: index, %b: index, %c : i1) {174  %c4 = arith.constant 4 : index175  %r = scf.if %c -> index {176    %add1 = arith.addi %a, %b : index177    scf.yield %add1 : index178  } else {179    %add2 = arith.addi %b, %c4 : index180    %add3 = arith.addi %add2, %a : index181    scf.yield %add3 : index182  }183 184  // CHECK: %[[lb:.*]] = affine.apply #[[$map]]()[%[[a]], %[[b]]]185  // CHECK: %[[ub:.*]] = affine.apply #[[$map1]]()[%[[a]], %[[b]]]186  %reify1 = "test.reify_bound"(%r) {type = "LB"} : (index) -> (index)187  %reify2 = "test.reify_bound"(%r) {type = "UB"} : (index) -> (index)188  // CHECK: "test.some_use"(%[[lb]], %[[ub]])189  "test.some_use"(%reify1, %reify2) : (index, index) -> ()190  return191}192 193// -----194 195func.func @scf_if_no_affine_bound(%a: index, %b: index, %c : i1) {196  %r = scf.if %c -> index {197    scf.yield %a : index198  } else {199    scf.yield %b : index200  }201  // The reified bound would be min(%a, %b). min/max expressions are not202  // supported in reified bounds.203  // expected-error @below{{could not reify bound}}204  %reify1 = "test.reify_bound"(%r) {type = "LB"} : (index) -> (index)205  "test.some_use"(%reify1) : (index) -> ()206  return207}208 209// -----210 211// CHECK-LABEL: func @scf_if_tensor_dim(212func.func @scf_if_tensor_dim(%c : i1) {213  // CHECK: arith.constant 4 : index214  // CHECK: arith.constant 9 : index215  %c4 = arith.constant 4 : index216  %c9 = arith.constant 9 : index217  %t1 = tensor.empty(%c4) : tensor<?xf32>218  %t2 = tensor.empty(%c9) : tensor<?xf32>219  %r = scf.if %c -> tensor<?xf32> {220    scf.yield %t1 : tensor<?xf32>221  } else {222    scf.yield %t2 : tensor<?xf32>223  }224 225  // CHECK: %[[c4:.*]] = arith.constant 4 : index226  // CHECK: %[[c10:.*]] = arith.constant 10 : index227  %reify1 = "test.reify_bound"(%r) {type = "LB", dim = 0}228      : (tensor<?xf32>) -> (index)229  %reify2 = "test.reify_bound"(%r) {type = "UB", dim = 0}230      : (tensor<?xf32>) -> (index)231  // CHECK: "test.some_use"(%[[c4]], %[[c10]])232  "test.some_use"(%reify1, %reify2) : (index, index) -> ()233  return234}235 236// -----237 238// CHECK: #[[$map:.*]] = affine_map<()[s0, s1] -> (s0 + s1)>239// CHECK-LABEL: func @scf_if_eq(240//  CHECK-SAME:     %[[a:.*]]: index, %[[b:.*]]: index, %{{.*}}: i1)241func.func @scf_if_eq(%a: index, %b: index, %c : i1) {242  %c0 = arith.constant 0 : index243  %r = scf.if %c -> index {244    %add1 = arith.addi %a, %b : index245    scf.yield %add1 : index246  } else {247    %add2 = arith.addi %b, %c0 : index248    %add3 = arith.addi %add2, %a : index249    scf.yield %add3 : index250  }251 252  // CHECK: %[[eq:.*]] = affine.apply #[[$map]]()[%[[a]], %[[b]]]253  %reify1 = "test.reify_bound"(%r) {type = "EQ"} : (index) -> (index)254  // CHECK: "test.some_use"(%[[eq]])255  "test.some_use"(%reify1) : (index) -> ()256  return257}258 259// -----260 261func.func @compare_scf_for(%a: index, %b: index, %c: index) {262  scf.for %iv = %a to %b step %c {263    // expected-remark @below{{true}}264    "test.compare"(%iv, %a) {cmp = "GE"} : (index, index) -> ()265    // expected-remark @below{{true}}266    "test.compare"(%iv, %b) {cmp = "LT"} : (index, index) -> ()267  }268  return269}270 271// -----272 273func.func @scf_for_induction_var_upper_bound() {274  %c0 = arith.constant 0 : index275  %c1 = arith.constant 1 : index276  %c2 = arith.constant 2 : index277  %c3 = arith.constant 3 : index278  %c4 = arith.constant 4 : index279  %c5 = arith.constant 5 : index280  %c8 = arith.constant 8 : index281  %c10 = arith.constant 10 : index282  scf.for %iv = %c0 to %c10 step %c4 {283    // expected-remark @below{{true}}284    "test.compare"(%iv, %c8) {cmp = "LE"} : (index, index) -> ()285  }286  scf.for %iv = %c2 to %c8 step %c3 {287    // expected-remark @below{{true}}288    "test.compare"(%iv, %c5) {cmp = "LE"} : (index, index) -> ()289  }290  return291}292 293// -----294 295#map_ceildiv_dynamic_divisor = affine_map<(i)[s] -> (i ceildiv s)>296func.func @scf_for_induction_var_computed_upper_bound(%upperBound: index, %step: index) {297  %c0 = arith.constant 0 : index298  %c1 = arith.constant 1 : index299  %tripCount = affine.apply #map_ceildiv_dynamic_divisor (%upperBound)[%step]300  %tripCountMinusOne = arith.subi %tripCount, %c1 : index301  %computedUpperBound = arith.muli %tripCountMinusOne, %step : index302  scf.for %iv = %c0 to %upperBound step %step {303    // TODO: Value bounds analysis will fail to compute upper bound304    // because multiplication/division of unknown block arguments is305    // not supported.306    // expected-error @below{{unknown}}307    "test.compare"(%iv, %computedUpperBound) {cmp = "LE"} : (index, index) -> ()308  }309  return310}311 312// -----313 314func.func @scf_for_result_infer() {315  %c0 = arith.constant 0 : index316  %c1 = arith.constant 1 : index317  %c10 = arith.constant 10 : index318  %0 = scf.for %iv = %c0 to %c10 step %c1 iter_args(%arg = %c0) -> index {319    %2 = "test.some_use"() : () -> (i1)320    %3 = scf.if %2 -> (index) {321        %5 = arith.addi %arg, %c1 : index322        scf.yield %5 : index323    } else {324        scf.yield %arg : index325    }326    scf.yield %3 : index327  }328  // expected-remark @below{{true}}329  "test.compare"(%0, %c10) {cmp = "LE"} : (index, index) -> ()330  return331}332 333// -----334 335func.func @scf_for_result_infer_dynamic_init(%i : index) {336  %c0 = arith.constant 0 : index337  %c1 = arith.constant 1 : index338  %c10 = arith.constant 10 : index339  %0 = scf.for %iv = %c0 to %c10 step %c1 iter_args(%arg = %i) -> index {340    %2 = "test.some_use"() : () -> (i1)341    %3 = scf.if %2 -> (index) {342        %5 = arith.addi %arg, %c1 : index343        scf.yield %5 : index344    } else {345        scf.yield %arg : index346    }347    scf.yield %3 : index348  }349  %6 = arith.addi %i, %c10 : index350  // expected-remark @below{{true}}351  "test.compare"(%0, %6) {cmp = "LE"} : (index, index) -> ()352  return353}354 355// -----356 357func.func @scf_for_result_infer_dynamic_init_big_step(%i : index) {358  %c0 = arith.constant 0 : index359  %c1 = arith.constant 1 : index360  %c2 = arith.constant 2 : index361  %c4 = arith.constant 4 : index362  %c5 = arith.constant 5 : index363  %c10 = arith.constant 10 : index364  %0 = scf.for %iv = %c0 to %c10 step %c2 iter_args(%arg = %i) -> index {365    %2 = "test.some_use"() : () -> (i1)366    %3 = scf.if %2 -> (index) {367        %5 = arith.addi %arg, %c1 : index368        scf.yield %5 : index369    } else {370        scf.yield %arg : index371    }372    scf.yield %3 : index373  }374  %6 = arith.addi %i, %c5 : index375  %7 = arith.addi %i, %c4 : index376  // expected-remark @below{{true}}377  "test.compare"(%0, %6) {cmp = "LE"} : (index, index) -> ()378  // expected-error @below{{unknown}}379  "test.compare"(%0, %7) {cmp = "LE"} : (index, index) -> ()380  return381}382