Skip to content

Commit 5828f3f

Browse files
ZenithalHourlyRatePrakhar-Dixit
authored andcommitted
[mlir] Fix FunctionOpInterface impl for external func (llvm#124693)
For function declarations (i.e. func op has no entry block), the FunctionOpInterface method `insertArgument` and `eraseArgument` will cause segfault. This PR guards against manipulation of empty entry block by checking whether func op is external. An example can be seen in google/heir#1324 The segfault trace ``` llvm#1 0x0000560f1289d9db PrintStackTraceSignalHandler(void*) /proc/self/cwd/external/llvm-project/llvm/lib/Support/Unix/Signals.inc:874:1 llvm#2 0x0000560f1289b116 llvm::sys::RunSignalHandlers() /proc/self/cwd/external/llvm-project/llvm/lib/Support/Signals.cpp:105:5 llvm#3 0x0000560f1289e145 SignalHandler(int) /proc/self/cwd/external/llvm-project/llvm/lib/Support/Unix/Signals.inc:415:1 llvm#4 0x00007f829a3d9520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520) llvm#5 0x0000560f1257f8bc void __gnu_cxx::new_allocator<mlir::BlockArgument>::construct<mlir::BlockArgument, mlir::BlockArgument>(mlir::BlockArgument*, mlir::BlockArgument&&) /usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/ext/new_allocator.h:162:23 llvm#6 0x0000560f1257f84d void std::allocator_traits<std::allocator<mlir::BlockArgument> >::construct<mlir::BlockArgument, mlir::BlockArgument>(std::allocator<mlir::BlockArgument>&, mlir::BlockArgument*, mlir::BlockArgument&&) /usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/alloc_traits.h:520:2 llvm#7 0x0000560f12580498 void std::vector<mlir::BlockArgument, std::allocator<mlir::BlockArgument> >::_M_insert_aux<mlir::BlockArgument>(__gnu_cxx::__normal_iterator<mlir::BlockArgument*, std::vector<mlir::BlockArgument, std::allocator<mlir::BlockArgument> > >, mlir::BlockArgument&&) /usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/vector.tcc:405:7 llvm#8 0x0000560f1257cf7e std::vector<mlir::BlockArgument, std::allocator<mlir::BlockArgument> >::insert(__gnu_cxx::__normal_iterator<mlir::BlockArgument const*, std::vector<mlir::BlockArgument, std::allocator<mlir::BlockArgument> > >, mlir::BlockArgument const&) /usr/lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/vector.tcc:154:6 llvm#9 0x0000560f1257b349 mlir::Block::insertArgument(unsigned int, mlir::Type, mlir::Location) /proc/self/cwd/external/llvm-project/mlir/lib/IR/Block.cpp:178:13 llvm#10 0x0000560f123d2a1c mlir::function_interface_impl::insertFunctionArguments(mlir::FunctionOpInterface, llvm::ArrayRef<unsigned int>, mlir::TypeRange, llvm::ArrayRef<mlir::DictionaryAttr>, llvm::ArrayRef<mlir::Location>, unsigned int, mlir::Type) /proc/self/cwd/external/llvm-project/mlir/lib/Interfaces/FunctionInterfaces.cpp:232:11 llvm#11 0x0000560f0be6b727 mlir::detail::FunctionOpInterfaceTrait<mlir::func::FuncOp>::insertArguments(llvm::ArrayRef<unsigned int>, mlir::TypeRange, llvm::ArrayRef<mlir::DictionaryAttr>, llvm::ArrayRef<mlir::Location>) /proc/self/cwd/bazel-out/k8-dbg/bin/external/llvm-project/mlir/include/mlir/Interfaces/FunctionInterfaces.h.inc:809:7 llvm#12 0x0000560f0be6b536 mlir::detail::FunctionOpInterfaceTrait<mlir::func::FuncOp>::insertArgument(unsigned int, mlir::Type, mlir::DictionaryAttr, mlir::Location) /proc/self/cwd/bazel-out/k8-dbg/bin/external/llvm-project/mlir/include/mlir/Interfaces/FunctionInterfaces.h.inc:796:7 ```
1 parent 48246aa commit 5828f3f

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

mlir/lib/Interfaces/FunctionInterfaces.cpp

+17-9
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,7 @@ void function_interface_impl::insertFunctionArguments(
199199
// There are 3 things that need to be updated:
200200
// - Function type.
201201
// - Arg attrs.
202-
// - Block arguments of entry block.
203-
Block &entry = op->getRegion(0).front();
202+
// - Block arguments of entry block, if not empty.
204203

205204
// Update the argument attributes of the function.
206205
ArrayAttr oldArgAttrs = op.getArgAttrsAttr();
@@ -226,10 +225,15 @@ void function_interface_impl::insertFunctionArguments(
226225
setAllArgAttrDicts(op, newArgAttrs);
227226
}
228227

229-
// Update the function type and any entry block arguments.
228+
// Update the function type.
230229
op.setFunctionTypeAttr(TypeAttr::get(newType));
231-
for (unsigned i = 0, e = argIndices.size(); i < e; ++i)
232-
entry.insertArgument(argIndices[i] + i, argTypes[i], argLocs[i]);
230+
231+
// Update entry block arguments, if not empty.
232+
if (!op.isExternal()) {
233+
Block &entry = op->getRegion(0).front();
234+
for (unsigned i = 0, e = argIndices.size(); i < e; ++i)
235+
entry.insertArgument(argIndices[i] + i, argTypes[i], argLocs[i]);
236+
}
233237
}
234238

235239
void function_interface_impl::insertFunctionResults(
@@ -279,8 +283,7 @@ void function_interface_impl::eraseFunctionArguments(
279283
// There are 3 things that need to be updated:
280284
// - Function type.
281285
// - Arg attrs.
282-
// - Block arguments of entry block.
283-
Block &entry = op->getRegion(0).front();
286+
// - Block arguments of entry block, if not empty.
284287

285288
// Update the argument attributes of the function.
286289
if (ArrayAttr argAttrs = op.getArgAttrsAttr()) {
@@ -292,9 +295,14 @@ void function_interface_impl::eraseFunctionArguments(
292295
setAllArgAttrDicts(op, newArgAttrs);
293296
}
294297

295-
// Update the function type and any entry block arguments.
298+
// Update the function type.
296299
op.setFunctionTypeAttr(TypeAttr::get(newType));
297-
entry.eraseArguments(argIndices);
300+
301+
// Update entry block arguments, if not empty.
302+
if (!op.isExternal()) {
303+
Block &entry = op->getRegion(0).front();
304+
entry.eraseArguments(argIndices);
305+
}
298306
}
299307

300308
void function_interface_impl::eraseFunctionResults(

0 commit comments

Comments
 (0)