Skip to content

Commit 675c1b7

Browse files
committed
[MLIR][LLVM] Fix inlining of a single block ending with unreachable
1 parent 2914ba1 commit 675c1b7

File tree

14 files changed

+51
-17
lines changed

14 files changed

+51
-17
lines changed

flang/lib/Optimizer/Dialect/FIRDialect.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct FIRInlinerInterface : public mlir::DialectInlinerInterface {
4444
/// We handle the return (a Fortran FUNCTION) by replacing the values
4545
/// previously returned by the call operation with the operands of the
4646
/// return.
47-
void handleTerminator(mlir::Operation *op,
47+
void handleTerminator(mlir::Operation *op, mlir::OpBuilder &builder,
4848
mlir::ValueRange valuesToRepl) const final {
4949
auto returnOp = llvm::cast<mlir::func::ReturnOp>(op);
5050
assert(returnOp.getNumOperands() == valuesToRepl.size());

mlir/examples/toy/Ch4/mlir/Dialect.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ struct ToyInlinerInterface : public DialectInlinerInterface {
7373

7474
/// Handle the given inlined terminator(toy.return) by replacing it with a new
7575
/// operation as necessary.
76-
void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
76+
void handleTerminator(Operation *op, OpBuilder &builder,
77+
ValueRange valuesToRepl) const final {
7778
// Only "toy.return" needs to be handled here.
7879
auto returnOp = cast<ReturnOp>(op);
7980

mlir/examples/toy/Ch5/mlir/Dialect.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ struct ToyInlinerInterface : public DialectInlinerInterface {
7373

7474
/// Handle the given inlined terminator(toy.return) by replacing it with a new
7575
/// operation as necessary.
76-
void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
76+
void handleTerminator(Operation *op, OpBuilder &builder,
77+
ValueRange valuesToRepl) const final {
7778
// Only "toy.return" needs to be handled here.
7879
auto returnOp = cast<ReturnOp>(op);
7980

mlir/examples/toy/Ch6/mlir/Dialect.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ struct ToyInlinerInterface : public DialectInlinerInterface {
7373

7474
/// Handle the given inlined terminator(toy.return) by replacing it with a new
7575
/// operation as necessary.
76-
void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
76+
void handleTerminator(Operation *op, OpBuilder &builder,
77+
ValueRange valuesToRepl) const final {
7778
// Only "toy.return" needs to be handled here.
7879
auto returnOp = cast<ReturnOp>(op);
7980

mlir/examples/toy/Ch7/mlir/Dialect.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ struct ToyInlinerInterface : public DialectInlinerInterface {
7979

8080
/// Handle the given inlined terminator(toy.return) by replacing it with a new
8181
/// operation as necessary.
82-
void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
82+
void handleTerminator(Operation *op, OpBuilder &builder,
83+
ValueRange valuesToRepl) const final {
8384
// Only "toy.return" needs to be handled here.
8485
auto returnOp = cast<ReturnOp>(op);
8586

mlir/include/mlir/Transforms/InliningUtils.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class DialectInlinerInterface
116116
/// calls, these are directly replaced with the operands of the `return`
117117
/// operation). The given 'op' will be removed by the caller, after this
118118
/// function has been called.
119-
virtual void handleTerminator(Operation *op,
119+
virtual void handleTerminator(Operation *op, OpBuilder &builder,
120120
ValueRange valuesToReplace) const {
121121
llvm_unreachable(
122122
"must implement handleTerminator in the case of one inlined block");
@@ -212,7 +212,8 @@ class InlinerInterface
212212
//===--------------------------------------------------------------------===//
213213

214214
virtual void handleTerminator(Operation *op, Block *newDest) const;
215-
virtual void handleTerminator(Operation *op, ValueRange valuesToRepl) const;
215+
virtual void handleTerminator(Operation *op, OpBuilder &builder,
216+
ValueRange valuesToRepl) const;
216217

217218
virtual Value handleArgument(OpBuilder &builder, Operation *call,
218219
Operation *callable, Value argument,

mlir/lib/Dialect/Func/Extensions/InlinerExtension.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ struct FuncInlinerInterface : public DialectInlinerInterface {
6767

6868
/// Handle the given inlined terminator by replacing it with a new operation
6969
/// as necessary.
70-
void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
70+
void handleTerminator(Operation *op, OpBuilder &builder,
71+
ValueRange valuesToRepl) const final {
7172
// Only return needs to be handled here.
7273
auto returnOp = cast<ReturnOp>(op);
7374

mlir/lib/Dialect/LLVMIR/Transforms/InlinerInterfaceImpl.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -746,8 +746,17 @@ struct LLVMInlinerInterface : public DialectInlinerInterface {
746746
/// Handle the given inlined return by replacing the uses of the call with the
747747
/// operands of the return. This overload is called when the inlined region
748748
/// only contains one block.
749-
void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
750-
// Return will be the only terminator present.
749+
void handleTerminator(Operation *op, OpBuilder &builder,
750+
ValueRange valuesToRepl) const final {
751+
if (isa<LLVM::UnreachableOp>(op)) {
752+
for (auto dst : valuesToRepl) {
753+
auto repl = builder.create<LLVM::PoisonOp>(op->getLoc(), dst.getType());
754+
dst.replaceAllUsesWith(repl);
755+
}
756+
return;
757+
}
758+
759+
// Otherwise return will be the only terminator present.
751760
auto returnOp = cast<LLVM::ReturnOp>(op);
752761

753762
// Replace the values directly with the return operands.

mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ struct LinalgInlinerInterface : public DialectInlinerInterface {
5757
}
5858
// Handle the given inlined terminator by replacing it with a new operation
5959
// as necessary. Required when the region has only one block.
60-
void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {}
60+
void handleTerminator(Operation *op, OpBuilder &builder,
61+
ValueRange valuesToRepl) const final {}
6162
};
6263

6364
} // namespace

mlir/lib/Dialect/SCF/IR/SCF.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ struct SCFInlinerInterface : public DialectInlinerInterface {
5151
}
5252
// Handle the given inlined terminator by replacing it with a new operation
5353
// as necessary. Required when the region has only one block.
54-
void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
54+
void handleTerminator(Operation *op, OpBuilder &builder,
55+
ValueRange valuesToRepl) const final {
5556
auto retValOp = dyn_cast<scf::YieldOp>(op);
5657
if (!retValOp)
5758
return;

0 commit comments

Comments
 (0)