Skip to content

Commit 35d3b34

Browse files
[mlir][bufferization] Add "bottom-up from terminators" analysis heuristic (#83964)
One-Shot Bufferize currently does not support loops where a yielded value bufferizes to a buffer that is different from the buffer of the region iter_arg. In such a case, the bufferization fails with an error such as: ``` Yield operand #0 is not equivalent to the corresponding iter bbArg scf.yield %0 : tensor<5xf32> ``` One common reason for non-equivalent buffers is that an op on the path from the region iter_arg to the terminator bufferizes out-of-place. Ops that are analyzed earlier are more likely to bufferize in-place. This commit adds a new heuristic that gives preference to ops that are reachable on the reverse SSA use-def chain from a region terminator and are within the parent region of the terminator. This is expected to work better than the existing heuristics for loops where an iter_arg is written to multiple times within a loop, but only one write is fed into the terminator. Current users of One-Shot Bufferize are not affected by this change. "Bottom-up" is still the default heuristic. Users can switch to the new heuristic manually. This commit also turns the "fuzzer" pass option into a heuristic, cleaning up the code a bit.
1 parent 7bb87d5 commit 35d3b34

17 files changed

+198
-64
lines changed

mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -366,10 +366,6 @@ struct BufferizationOptions {
366366
DefaultMemorySpaceFn defaultMemorySpaceFn =
367367
[](TensorType t) -> std::optional<Attribute> { return Attribute(); };
368368

369-
/// Seed for the analysis fuzzer. If set to `0`, the fuzzer is deactivated.
370-
/// Should be used only with `testAnalysisOnly = true`.
371-
unsigned analysisFuzzerSeed = 0;
372-
373369
/// If set to `true`, the analysis is skipped. A buffer is copied before every
374370
/// write. This flag cannot be used together with `testAnalysisOnly = true`.
375371
bool copyBeforeWrite = false;

mlir/include/mlir/Dialect/Bufferization/Transforms/OneShotAnalysis.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ class OneShotAnalysisState;
2424

2525
/// Options for analysis-enabled bufferization.
2626
struct OneShotBufferizationOptions : public BufferizationOptions {
27-
enum class AnalysisHeuristic { BottomUp, TopDown };
27+
enum class AnalysisHeuristic {
28+
BottomUp,
29+
TopDown,
30+
BottomUpFromTerminators,
31+
Fuzzer
32+
};
2833

2934
OneShotBufferizationOptions() = default;
3035

@@ -42,6 +47,11 @@ struct OneShotBufferizationOptions : public BufferizationOptions {
4247
/// Specify the functions that should not be analyzed. copyBeforeWrite will be
4348
/// set to true when bufferizing them.
4449
llvm::ArrayRef<std::string> noAnalysisFuncFilter;
50+
51+
/// Seed for the analysis fuzzer. Used only if the heuristic is set to
52+
/// `AnalysisHeuristic::Fuzzer`. The fuzzer should be used only with
53+
/// `testAnalysisOnly = true`.
54+
unsigned analysisFuzzerSeed = 0;
4555
};
4656

4757
/// State for analysis-enabled bufferization. This class keeps track of alias

mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.td

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,24 @@ def OneShotBufferize : Pass<"one-shot-bufferize", "ModuleOp"> {
459459
argument is read/written and which returned values are aliasing/equivalent.
460460
For debugging purposes, such information can be printed with
461461
`test-analysis-only`.
462+
463+
The order in which ops are analyzed is important. The analysis is greedy and
464+
ops that are analyzed earlier are more likely to bufferize in-place. The
465+
heuristic can be set with `analysis-heuristic`. At the moment, the following
466+
heuristics are available:
467+
468+
* `bottom-up` (default): Analyze ops from bottom to top.
469+
* `top-down`: Analyze ops from top to bottom.
470+
* `fuzzer`: Randomize the ordering of ops with `analysis-fuzzer-seed`.
471+
* `bottom-up-from-terminators`: Traverse the reverse use-def chains of
472+
tensor IR, starting from region branch terminators (bottom-up). Nested
473+
regions are traversed before enclosing regions. Analyze the traversed ops
474+
first, then analyze the remaining ops bottom-up. This heuristic is useful
475+
for bufferizing loop constructs. One-Shot Bufferize currently supports
476+
only such IR where yielded tensor values bufferize to equivalent region
477+
iter_args, and first analyzing all ops on the path from the "yielding" op
478+
to the beginning of the loop body makes it more likely for the region
479+
iter_args and yielded values to bufferize to equivalent buffers.
462480
}];
463481
let options = [
464482
Option<"allowReturnAllocsFromLoops", "allow-return-allocs-from-loops",

mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ parseHeuristicOption(const std::string &s) {
182182
return OneShotBufferizationOptions::AnalysisHeuristic::BottomUp;
183183
if (s == "top-down")
184184
return OneShotBufferizationOptions::AnalysisHeuristic::TopDown;
185+
if (s == "bottom-up-from-terminators")
186+
return OneShotBufferizationOptions::AnalysisHeuristic::
187+
BottomUpFromTerminators;
188+
if (s == "fuzzer")
189+
return OneShotBufferizationOptions::AnalysisHeuristic::Fuzzer;
185190
llvm_unreachable("invalid analysisheuristic option");
186191
}
187192

mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp

Lines changed: 90 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
#include "mlir/Dialect/MemRef/IR/MemRef.h"
5252
#include "mlir/IR/AsmState.h"
5353
#include "mlir/IR/Dominance.h"
54+
#include "mlir/IR/Iterators.h"
5455
#include "mlir/IR/Operation.h"
5556
#include "mlir/IR/TypeUtilities.h"
5657
#include "mlir/Interfaces/ControlFlowInterfaces.h"
@@ -1094,41 +1095,104 @@ static void equivalenceAnalysis(Operation *op, OneShotAnalysisState &state) {
10941095
equivalenceAnalysis(ops, state);
10951096
}
10961097

1097-
LogicalResult OneShotAnalysisState::analyzeOp(Operation *op,
1098-
const DominanceInfo &domInfo) {
1099-
// Collect ops so we can build our own reverse traversal.
1100-
SmallVector<Operation *> ops;
1101-
op->walk([&](Operation *op) {
1102-
// No tensors => no buffers.
1103-
if (!hasTensorSemantics(op))
1098+
/// "Bottom-up from terminators" heuristic.
1099+
static SmallVector<Operation *>
1100+
bottomUpFromTerminatorsHeuristic(Operation *op,
1101+
const OneShotAnalysisState &state) {
1102+
SetVector<Operation *> traversedOps;
1103+
1104+
// Find region terminators.
1105+
op->walk<WalkOrder::PostOrder>([&](RegionBranchTerminatorOpInterface term) {
1106+
if (!traversedOps.insert(term))
11041107
return;
1105-
ops.push_back(op);
1108+
// Follow the reverse SSA use-def chain from each yielded value as long as
1109+
// we stay within the same region.
1110+
SmallVector<OpResult> worklist;
1111+
for (Value v : term->getOperands()) {
1112+
if (!isa<TensorType>(v.getType()))
1113+
continue;
1114+
auto opResult = dyn_cast<OpResult>(v);
1115+
if (!opResult)
1116+
continue;
1117+
worklist.push_back(opResult);
1118+
}
1119+
while (!worklist.empty()) {
1120+
OpResult opResult = worklist.pop_back_val();
1121+
Operation *defOp = opResult.getDefiningOp();
1122+
if (!traversedOps.insert(defOp))
1123+
continue;
1124+
if (!term->getParentRegion()->findAncestorOpInRegion(*defOp))
1125+
continue;
1126+
AliasingOpOperandList aliases = state.getAliasingOpOperands(opResult);
1127+
for (auto alias : aliases) {
1128+
Value v = alias.opOperand->get();
1129+
if (!isa<TensorType>(v.getType()))
1130+
continue;
1131+
auto opResult = dyn_cast<OpResult>(v);
1132+
if (!opResult)
1133+
continue;
1134+
worklist.push_back(opResult);
1135+
}
1136+
}
11061137
});
11071138

1108-
if (getOptions().analysisFuzzerSeed) {
1109-
// This is a fuzzer. For testing purposes only. Randomize the order in which
1110-
// operations are analyzed. The bufferization quality is likely worse, but
1111-
// we want to make sure that no assertions are triggered anywhere.
1112-
std::mt19937 g(getOptions().analysisFuzzerSeed);
1113-
llvm::shuffle(ops.begin(), ops.end(), g);
1114-
}
1139+
// Analyze traversed ops, then all remaining ops.
1140+
SmallVector<Operation *> result(traversedOps.begin(), traversedOps.end());
1141+
op->walk<WalkOrder::PostOrder, ReverseIterator>([&](Operation *op) {
1142+
if (!traversedOps.contains(op) && hasTensorSemantics(op))
1143+
result.push_back(op);
1144+
});
1145+
return result;
1146+
}
11151147

1148+
LogicalResult OneShotAnalysisState::analyzeOp(Operation *op,
1149+
const DominanceInfo &domInfo) {
11161150
OneShotBufferizationOptions::AnalysisHeuristic heuristic =
11171151
getOptions().analysisHeuristic;
1118-
if (heuristic == OneShotBufferizationOptions::AnalysisHeuristic::BottomUp) {
1119-
// Default: Walk ops in reverse for better interference analysis.
1120-
for (Operation *op : reverse(ops))
1121-
if (failed(analyzeSingleOp(op, domInfo)))
1122-
return failure();
1123-
} else if (heuristic ==
1124-
OneShotBufferizationOptions::AnalysisHeuristic::TopDown) {
1125-
for (Operation *op : ops)
1126-
if (failed(analyzeSingleOp(op, domInfo)))
1127-
return failure();
1152+
1153+
SmallVector<Operation *> orderedOps;
1154+
if (heuristic ==
1155+
OneShotBufferizationOptions::AnalysisHeuristic::BottomUpFromTerminators) {
1156+
orderedOps = bottomUpFromTerminatorsHeuristic(op, *this);
11281157
} else {
1129-
llvm_unreachable("unsupported heuristic");
1158+
op->walk([&](Operation *op) {
1159+
// No tensors => no buffers.
1160+
if (!hasTensorSemantics(op))
1161+
return;
1162+
orderedOps.push_back(op);
1163+
});
1164+
switch (heuristic) {
1165+
case OneShotBufferizationOptions::AnalysisHeuristic::BottomUp: {
1166+
// Default: Walk ops in reverse for better interference analysis.
1167+
std::reverse(orderedOps.begin(), orderedOps.end());
1168+
break;
1169+
}
1170+
case OneShotBufferizationOptions::AnalysisHeuristic::TopDown: {
1171+
// Ops are already sorted top-down in `orderedOps`.
1172+
break;
1173+
}
1174+
case OneShotBufferizationOptions::AnalysisHeuristic::Fuzzer: {
1175+
assert(getOptions().analysisFuzzerSeed &&
1176+
"expected that fuzzer seed it set");
1177+
// This is a fuzzer. For testing purposes only. Randomize the order in
1178+
// which operations are analyzed. The bufferization quality is likely
1179+
// worse, but we want to make sure that no assertions are triggered
1180+
// anywhere.
1181+
std::mt19937 g(getOptions().analysisFuzzerSeed);
1182+
llvm::shuffle(orderedOps.begin(), orderedOps.end(), g);
1183+
break;
1184+
}
1185+
default: {
1186+
llvm_unreachable("unsupported heuristic");
1187+
}
1188+
}
11301189
}
11311190

1191+
// Analyze ops in the computed order.
1192+
for (Operation *op : orderedOps)
1193+
if (failed(analyzeSingleOp(op, domInfo)))
1194+
return failure();
1195+
11321196
equivalenceAnalysis(op, *this);
11331197
return success();
11341198
}

mlir/test/Dialect/Arith/one-shot-bufferize.mlir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries" -split-input-file | FileCheck %s
22

33
// Run fuzzer with different seeds.
4-
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=23 bufferize-function-boundaries" -split-input-file -o /dev/null
5-
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=59 bufferize-function-boundaries" -split-input-file -o /dev/null
6-
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=91 bufferize-function-boundaries" -split-input-file -o /dev/null
4+
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=23 bufferize-function-boundaries" -split-input-file -o /dev/null
5+
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=59 bufferize-function-boundaries" -split-input-file -o /dev/null
6+
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=91 bufferize-function-boundaries" -split-input-file -o /dev/null
77

88
// Test bufferization using memref types that have no layout map.
99
// RUN: mlir-opt %s -one-shot-bufferize="unknown-type-conversion=identity-layout-map function-boundary-type-conversion=identity-layout-map bufferize-function-boundaries" -split-input-file -o /dev/null

mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-allow-return-allocs.mlir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// RUN: mlir-opt %s -one-shot-bufferize="allow-unknown-ops" -canonicalize -split-input-file | FileCheck %s
22

33
// Run fuzzer with different seeds.
4-
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=23" -split-input-file -o /dev/null
5-
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=59" -split-input-file -o /dev/null
6-
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=91" -split-input-file -o /dev/null
4+
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=23" -split-input-file -o /dev/null
5+
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=59" -split-input-file -o /dev/null
6+
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=91" -split-input-file -o /dev/null
77

88
// CHECK-LABEL: func @buffer_not_deallocated(
99
// CHECK-SAME: %[[t:.*]]: tensor<?xf32>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-heuristic=bottom-up-from-terminators" -split-input-file | FileCheck %s
2+
3+
// CHECK-LABEL: func @simple_test(
4+
func.func @simple_test(%lb: index, %ub: index, %step: index, %f1: f32, %f2: f32) -> (tensor<5xf32>, tensor<5xf32>) {
5+
%c0 = arith.constant 0 : index
6+
%p = arith.constant 0.0 : f32
7+
8+
// Make sure that ops that feed into region terminators bufferize in-place
9+
// (if possible).
10+
// Note: This test case fails to bufferize with a "top-down" or "bottom-up"
11+
// heuristic.
12+
13+
%0 = tensor.empty() : tensor<5xf32>
14+
%1 = scf.for %iv = %lb to %ub step %step iter_args(%t = %0) -> (tensor<5xf32>) {
15+
// CHECK: linalg.fill {__inplace_operands_attr__ = ["none", "false"]}
16+
%2 = linalg.fill ins(%f1 : f32) outs(%t : tensor<5xf32>) -> tensor<5xf32>
17+
// CHECK: linalg.fill {__inplace_operands_attr__ = ["none", "true"]}
18+
%3 = linalg.fill ins(%f2 : f32) outs(%t : tensor<5xf32>) -> tensor<5xf32>
19+
%4 = vector.transfer_read %2[%c0], %p : tensor<5xf32>, vector<5xf32>
20+
vector.print %4 : vector<5xf32>
21+
scf.yield %3 : tensor<5xf32>
22+
}
23+
24+
%5 = tensor.empty() : tensor<5xf32>
25+
%6 = scf.for %iv = %lb to %ub step %step iter_args(%t = %0) -> (tensor<5xf32>) {
26+
// CHECK: linalg.fill {__inplace_operands_attr__ = ["none", "true"]}
27+
%7 = linalg.fill ins(%f1 : f32) outs(%t : tensor<5xf32>) -> tensor<5xf32>
28+
// CHECK: linalg.fill {__inplace_operands_attr__ = ["none", "false"]}
29+
%8 = linalg.fill ins(%f2 : f32) outs(%t : tensor<5xf32>) -> tensor<5xf32>
30+
%9 = vector.transfer_read %8[%c0], %p : tensor<5xf32>, vector<5xf32>
31+
vector.print %9 : vector<5xf32>
32+
scf.yield %7 : tensor<5xf32>
33+
}
34+
35+
return %1, %6 : tensor<5xf32>, tensor<5xf32>
36+
}

mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize-partial.mlir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
// RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="allow-unknown-ops unknown-type-conversion=identity-layout-map" -split-input-file | FileCheck %s --check-prefix=CHECK-NO-LAYOUT-MAP
55

66
// Run fuzzer with different seeds.
7-
// RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=23" -split-input-file -o /dev/null
8-
// RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=59" -split-input-file -o /dev/null
9-
// RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=91" -split-input-file -o /dev/null
7+
// RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=23" -split-input-file -o /dev/null
8+
// RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=59" -split-input-file -o /dev/null
9+
// RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=91" -split-input-file -o /dev/null
1010

1111
// RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="dialect-filter=tensor,bufferization allow-unknown-ops" -canonicalize -split-input-file | FileCheck %s --check-prefix=CHECK-TENSOR
1212
// RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="dialect-filter=scf,bufferization allow-unknown-ops" -canonicalize -split-input-file | FileCheck %s --check-prefix=CHECK-SCF

mlir/test/Dialect/Bufferization/Transforms/one-shot-bufferize.mlir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
// RUN: mlir-opt %s -one-shot-bufferize="allow-unknown-ops" -verify-diagnostics -split-input-file | FileCheck %s
22

33
// Run fuzzer with different seeds.
4-
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=23" -verify-diagnostics -split-input-file -o /dev/null
5-
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=59" -verify-diagnostics -split-input-file -o /dev/null
6-
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-fuzzer-seed=91" -verify-diagnostics -split-input-file -o /dev/null
4+
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=23" -verify-diagnostics -split-input-file -o /dev/null
5+
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=59" -verify-diagnostics -split-input-file -o /dev/null
6+
// RUN: mlir-opt %s -one-shot-bufferize="test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=91" -verify-diagnostics -split-input-file -o /dev/null
77

88
// Run with top-down analysis.
99
// RUN: mlir-opt %s -one-shot-bufferize="allow-unknown-ops analysis-heuristic=top-down" -verify-diagnostics -split-input-file | FileCheck %s --check-prefix=CHECK-TOP-DOWN-ANALYSIS

mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize-allow-return-allocs.mlir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries=1 " -split-input-file | FileCheck %s --check-prefix=NO-DROP
33

44
// Run fuzzer with different seeds.
5-
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries=1 test-analysis-only analysis-fuzzer-seed=23" -split-input-file -o /dev/null
6-
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries=1 test-analysis-only analysis-fuzzer-seed=59" -split-input-file -o /dev/null
7-
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries=1 test-analysis-only analysis-fuzzer-seed=91" -split-input-file -o /dev/null
5+
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries=1 test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=23" -split-input-file -o /dev/null
6+
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries=1 test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=59" -split-input-file -o /dev/null
7+
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries=1 test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=91" -split-input-file -o /dev/null
88

99
// Test bufferization using memref types that have no layout map.
1010
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries=1 unknown-type-conversion=identity-layout-map function-boundary-type-conversion=identity-layout-map" -split-input-file -o /dev/null

mlir/test/Dialect/Bufferization/Transforms/one-shot-module-bufferize-analysis.mlir

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries test-analysis-only" -split-input-file | FileCheck %s
22

33
// Run fuzzer with different seeds.
4-
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries test-analysis-only analysis-fuzzer-seed=23" -split-input-file -o /dev/null
5-
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries test-analysis-only analysis-fuzzer-seed=59" -split-input-file -o /dev/null
6-
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries test-analysis-only analysis-fuzzer-seed=91" -split-input-file -o /dev/null
4+
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=23" -split-input-file -o /dev/null
5+
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=59" -split-input-file -o /dev/null
6+
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries test-analysis-only analysis-heuristic=fuzzer analysis-fuzzer-seed=91" -split-input-file -o /dev/null
7+
8+
// Try different heuristics. Not checking the result, just make sure that we do
9+
// not crash.
10+
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries test-analysis-only analysis-heuristic=bottom-up-from-terminators" -split-input-file -o /dev/null
11+
// RUN: mlir-opt %s -one-shot-bufferize="bufferize-function-boundaries test-analysis-only analysis-heuristic=top-down" -split-input-file -o /dev/null
712

813
// TODO: Extract op-specific test cases and move them to their respective
914
// dialects.

0 commit comments

Comments
 (0)