diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMInlining.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMInlining.cpp index 65c1daee6711a..4a6154ea6d300 100644 --- a/mlir/lib/Dialect/LLVMIR/IR/LLVMInlining.cpp +++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMInlining.cpp @@ -663,6 +663,10 @@ struct LLVMInlinerInterface : public DialectInlinerInterface { << "Cannot inline: callable is not an LLVM::LLVMFuncOp\n"); return false; } + if (funcOp.isVarArg()) { + LLVM_DEBUG(llvm::dbgs() << "Cannot inline: callable is variadic\n"); + return false; + } // TODO: Generate aliasing metadata from noalias argument/result attributes. if (auto attrs = funcOp.getArgAttrs()) { for (DictionaryAttr attrDict : attrs->getAsRange()) { @@ -704,7 +708,8 @@ struct LLVMInlinerInterface : public DialectInlinerInterface { } bool isLegalToInline(Operation *op, Region *, bool, IRMapping &) const final { - return true; + // The inliner cannot handle variadic function arguments. + return !isa(op); } /// Handle the given inlined return by replacing it with a branch. This diff --git a/mlir/test/Dialect/LLVMIR/inlining.mlir b/mlir/test/Dialect/LLVMIR/inlining.mlir index 63e7a46f1bdb0..3af8753bc318a 100644 --- a/mlir/test/Dialect/LLVMIR/inlining.mlir +++ b/mlir/test/Dialect/LLVMIR/inlining.mlir @@ -644,3 +644,28 @@ llvm.func @caller(%ptr : !llvm.ptr) -> i32 { llvm.store %c5, %ptr { access_groups = [#caller] } : i32, !llvm.ptr llvm.return %0 : i32 } + +// ----- + +llvm.func @vararg_func(...) { + llvm.return +} + +llvm.func @vararg_intrinrics() { + %0 = llvm.mlir.constant(1 : i32) : i32 + %list = llvm.alloca %0 x !llvm.struct<"struct.va_list_opaque", (ptr)> : (i32) -> !llvm.ptr + // The vararg intinriscs should normally be part of a variadic function. + // However, this test uses a non-variadic function to ensure the presence of + // the intrinsic alone suffices to prevent inlining. + llvm.intr.vastart %list : !llvm.ptr + llvm.return +} + +// CHECK-LABEL: func @caller +llvm.func @caller() { + // CHECK-NEXT: llvm.call @vararg_func() + llvm.call @vararg_func() vararg(!llvm.func) : () -> () + // CHECK-NEXT: llvm.call @vararg_intrinrics() + llvm.call @vararg_intrinrics() : () -> () + llvm.return +}