Skip to content

Commit 6588073

Browse files
[mlir][func] Fix incorrect API usage in FuncOpConversion (llvm#113977)
This commit fixes a case of incorrect dialect conversion API usage during `FuncOpConversion`. `replaceAllUsesExcept` (same as `replaceAllUsesWith`) is currently not supported in a dialect conversion. `replaceUsesOfBlockArgument` should be used instead. It sometimes works anyway (like in this case), but that's just because of the way we insert materializations. This commit is in preparation of merging the 1:1 and 1:N dialect conversion drivers. (At that point, the current use of `replaceAllUsesExcept` will no longer work.)
1 parent 00ca207 commit 6588073

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

mlir/lib/Conversion/FuncToLLVM/FuncToLLVM.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,16 +273,16 @@ static void wrapExternalFunction(OpBuilder &builder, Location loc,
273273
static void restoreByValRefArgumentType(
274274
ConversionPatternRewriter &rewriter, const LLVMTypeConverter &typeConverter,
275275
ArrayRef<std::optional<NamedAttribute>> byValRefNonPtrAttrs,
276-
LLVM::LLVMFuncOp funcOp) {
276+
ArrayRef<BlockArgument> oldBlockArgs, LLVM::LLVMFuncOp funcOp) {
277277
// Nothing to do for function declarations.
278278
if (funcOp.isExternal())
279279
return;
280280

281281
ConversionPatternRewriter::InsertionGuard guard(rewriter);
282282
rewriter.setInsertionPointToStart(&funcOp.getFunctionBody().front());
283283

284-
for (const auto &[arg, byValRefAttr] :
285-
llvm::zip(funcOp.getArguments(), byValRefNonPtrAttrs)) {
284+
for (const auto &[arg, oldArg, byValRefAttr] :
285+
llvm::zip(funcOp.getArguments(), oldBlockArgs, byValRefNonPtrAttrs)) {
286286
// Skip argument if no `llvm.byval` or `llvm.byref` attribute.
287287
if (!byValRefAttr)
288288
continue;
@@ -295,7 +295,7 @@ static void restoreByValRefArgumentType(
295295
cast<TypeAttr>(byValRefAttr->getValue()).getValue());
296296

297297
auto valueArg = rewriter.create<LLVM::LoadOp>(arg.getLoc(), resTy, arg);
298-
rewriter.replaceAllUsesExcept(arg, valueArg, valueArg);
298+
rewriter.replaceUsesOfBlockArgument(oldArg, valueArg);
299299
}
300300
}
301301

@@ -309,6 +309,10 @@ mlir::convertFuncOpToLLVMFuncOp(FunctionOpInterface funcOp,
309309
return rewriter.notifyMatchFailure(
310310
funcOp, "Only support FunctionOpInterface with FunctionType");
311311

312+
// Keep track of the entry block arguments. They will be needed later.
313+
SmallVector<BlockArgument> oldBlockArgs =
314+
llvm::to_vector(funcOp.getArguments());
315+
312316
// Convert the original function arguments. They are converted using the
313317
// LLVMTypeConverter provided to this legalization pattern.
314318
auto varargsAttr = funcOp->getAttrOfType<BoolAttr>(varargsAttrName);
@@ -438,7 +442,7 @@ mlir::convertFuncOpToLLVMFuncOp(FunctionOpInterface funcOp,
438442
// pointee type in the function body when converting `llvm.byval`/`llvm.byref`
439443
// function arguments.
440444
restoreByValRefArgumentType(rewriter, converter, byValRefNonPtrAttrs,
441-
newFuncOp);
445+
oldBlockArgs, newFuncOp);
442446

443447
if (!shouldUseBarePtrCallConv(funcOp, &converter)) {
444448
if (funcOp->getAttrOfType<UnitAttr>(

0 commit comments

Comments
 (0)