Skip to content

Commit 7248f4e

Browse files
[mlir][bufferization] Add "bottom-up from terminators" analysis heuristic
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 c089fa5 commit 7248f4e

17 files changed

+192
-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
@@ -356,10 +356,6 @@ struct BufferizationOptions {
356356
DefaultMemorySpaceFn defaultMemorySpaceFn =
357357
[](TensorType t) -> std::optional<Attribute> { return Attribute(); };
358358

359-
/// Seed for the analysis fuzzer. If set to `0`, the fuzzer is deactivated.
360-
/// Should be used only with `testAnalysisOnly = true`.
361-
unsigned analysisFuzzerSeed = 0;
362-
363359
/// If set to `true`, the analysis is skipped. A buffer is copied before every
364360
/// write. This flag cannot be used together with `testAnalysisOnly = true`.
365361
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
@@ -454,6 +454,24 @@ def OneShotBufferize : Pass<"one-shot-bufferize", "ModuleOp"> {
454454
argument is read/written and which returned values are aliasing/equivalent.
455455
For debugging purposes, such information can be printed with
456456
`test-analysis-only`.
457+
458+
The order in which ops are analyzed is important. The analysis is greedy and
459+
ops that are analyzed earlier are more likely to bufferize in-place. The
460+
heuristic can be set with `analysis-heuristic`. At the moment, the following
461+
heuristics are available:
462+
463+
* `bottom-up` (default): Analyze ops from bottom to top.
464+
* `top-down`: Analyze ops from top to bottom.
465+
* `fuzzer`: Randomize the ordering of ops with `analysis-fuzzer-seed`.
466+
* `bottom-up-from-terminators`: Traverse the reverse use-def chains of
467+
tensor IR, starting from region branch terminators (bottom-up). Nested
468+
regions are traversed before enclosing regions. Analyze the traversed ops
469+
first, then analyze the remaining ops bottom-up. This heuristic is useful
470+
for bufferizing loop constructs. One-Shot Bufferize currently supports
471+
only such IR where yielded tensor values bufferize to equivalent region
472+
iter_args, and first analyzing all ops on the path from the "yielding" op
473+
to the beginning of the loop body makes it more likely for the region
474+
iter_args and yielded values to bufferize to equivalent buffers.
457475
}];
458476
let options = [
459477
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: 84 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,98 @@ 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+
if (heuristic == OneShotBufferizationOptions::AnalysisHeuristic::BottomUp) {
1165+
// Default: Walk ops in reverse for better interference analysis.
1166+
std::reverse(orderedOps.begin(), orderedOps.end());
1167+
} else if (heuristic ==
1168+
OneShotBufferizationOptions::AnalysisHeuristic::TopDown) {
1169+
// Ops are already sorted top-down in `orderedOps`.
1170+
} else if (heuristic ==
1171+
OneShotBufferizationOptions::AnalysisHeuristic::Fuzzer) {
1172+
assert(getOptions().analysisFuzzerSeed &&
1173+
"expected that fuzzer seed it set");
1174+
// This is a fuzzer. For testing purposes only. Randomize the order in
1175+
// which operations are analyzed. The bufferization quality is likely
1176+
// worse, but we want to make sure that no assertions are triggered
1177+
// anywhere.
1178+
std::mt19937 g(getOptions().analysisFuzzerSeed);
1179+
llvm::shuffle(orderedOps.begin(), orderedOps.end(), g);
1180+
} else {
1181+
llvm_unreachable("unsupported heuristic");
1182+
}
11301183
}
11311184

1185+
// Analyze ops in the computed order.
1186+
for (Operation *op : orderedOps)
1187+
if (failed(analyzeSingleOp(op, domInfo)))
1188+
return failure();
1189+
11321190
equivalenceAnalysis(op, *this);
11331191
return success();
11341192
}

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)