diff --git a/programming_examples/ml/gelu/Makefile b/programming_examples/ml/gelu/Makefile index 216c907f41b..ff3f3167b69 100644 --- a/programming_examples/ml/gelu/Makefile +++ b/programming_examples/ml/gelu/Makefile @@ -64,7 +64,7 @@ build/final.xclbin: build/${targetname}.mlir build/kernels.a cd ${@D} && aiecc --aie-generate-xclbin --aie-generate-npu-insts --no-compile-host \ --xclbin-name=${@F} \ --no-xchesscc --no-xbridge \ - --aie-generate-npu --npu-insts-name=insts.bin $(<:%=../%) + --npu-insts-name=insts.bin $(<:%=../%) ${targetname}.exe: ${srcdir}/test.cpp rm -rf _build diff --git a/programming_examples/ml/silu/Makefile b/programming_examples/ml/silu/Makefile index 90e8ded9e94..fea7676cbd6 100644 --- a/programming_examples/ml/silu/Makefile +++ b/programming_examples/ml/silu/Makefile @@ -65,7 +65,7 @@ build/final.xclbin: build/${targetname}.mlir build/kernels.a cd ${@D} && aiecc --aie-generate-xclbin --aie-generate-npu-insts --no-compile-host \ --xclbin-name=${@F} \ --no-xchesscc --no-xbridge \ - --aie-generate-npu --npu-insts-name=insts.bin $(<:%=../%) + --npu-insts-name=insts.bin $(<:%=../%) ${targetname}.exe: ${srcdir}/test.cpp rm -rf _build diff --git a/programming_examples/ml/swiglu/Makefile b/programming_examples/ml/swiglu/Makefile index 6cb0c496b9c..919487b189a 100644 --- a/programming_examples/ml/swiglu/Makefile +++ b/programming_examples/ml/swiglu/Makefile @@ -64,7 +64,7 @@ build/final.xclbin: build/${targetname}.mlir build/kernels.a cd ${@D} && aiecc --aie-generate-xclbin --aie-generate-npu-insts --no-compile-host \ --xclbin-name=${@F} \ --no-xchesscc --no-xbridge --dynamic-objFifos=false \ - --aie-generate-npu --npu-insts-name=insts.bin $(<:%=../%) + --npu-insts-name=insts.bin $(<:%=../%) ${targetname}.exe: ${srcdir}/test.cpp rm -rf _build diff --git a/test/aiecc/cpp_host_compile.mlir b/test/aiecc/cpp_host_compile.mlir index 60575be0d17..7e30c727f3f 100644 --- a/test/aiecc/cpp_host_compile.mlir +++ b/test/aiecc/cpp_host_compile.mlir @@ -17,9 +17,10 @@ // RUN: aiecc --no-xchesscc --no-xbridge --compile-host -n --verbose %s 2>&1 | FileCheck %s // RUN: aiecc --no-xchesscc --no-xbridge --compile-host --host-target=aarch64-linux-gnu -n --verbose %s 2>&1 | FileCheck %s --check-prefix=AARCH64 -// Test: full host compilation with -I/-L/-l/-o and host source file -// RUN: aiecc --no-xchesscc --no-xbridge --compile-host -n --verbose \ -// RUN: -I/some/include -L/some/lib -lsomelib %s /tmp/host_test.cpp -o host_out 2>&1 \ +// Test: full host compilation with -I/-L/-l/-o and host source file. Host +// flags and host source files are passed after the `--` separator. +// RUN: aiecc --no-xchesscc --no-xbridge --compile-host -n --verbose %s -- \ +// RUN: -I/some/include -L/some/lib -lsomelib /tmp/host_test.cpp -o host_out 2>&1 \ // RUN: | FileCheck %s --check-prefix=HOSTFULL // CHECK: Generating aie_inc.cpp for device diff --git a/test/aiecc/unknown_args_rejected.mlir b/test/aiecc/unknown_args_rejected.mlir new file mode 100644 index 00000000000..4f249c9fb4c --- /dev/null +++ b/test/aiecc/unknown_args_rejected.mlir @@ -0,0 +1,51 @@ +//===- unknown_args_rejected.mlir -------------------------------*- MLIR -*-===// +// +// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// Copyright (C) 2026, Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +// Verify that aiecc rejects unknown command-line options that appear before +// the `--` host-passthrough separator. See issue #2989. + +// REQUIRES: peano + +// An unknown long option is rejected. +// RUN: not aiecc --garbage %s 2>&1 | FileCheck %s --check-prefix=GARBAGE +// GARBAGE: {{[Uu]nknown command line argument.*--garbage}} + +// A typo'd `--aie-*` option is rejected (the original report from #2989). +// RUN: not aiecc --aie-genrate-npu-insts %s 2>&1 | FileCheck %s --check-prefix=TYPO +// TYPO: {{[Uu]nknown command line argument.*--aie-genrate-npu-insts}} + +// Anything after `--` is forwarded to host compilation and not validated by +// aiecc. With --no-compile-host the passthrough args are not consumed at all, +// which is fine. +// RUN: aiecc --no-xchesscc --no-xbridge --no-compile-host -n %s -- --garbage 2>&1 | FileCheck %s --check-prefix=PASSTHROUGH +// PASSTHROUGH-NOT: {{[Uu]nknown command line argument}} + +module { + aie.device(npu1_1col) { + %tile_0_0 = aie.tile(0, 0) + %tile_0_2 = aie.tile(0, 2) + + aie.objectfifo @of_in(%tile_0_0, {%tile_0_2}, 2 : i32) : !aie.objectfifo> + aie.objectfifo @of_out(%tile_0_2, {%tile_0_0}, 2 : i32) : !aie.objectfifo> + + %core_0_2 = aie.core(%tile_0_2) { + aie.end + } + + aie.runtime_sequence(%in : memref<16xi32>, %out : memref<16xi32>) { + %c0 = arith.constant 0 : i64 + %c1 = arith.constant 1 : i64 + %c16 = arith.constant 16 : i64 + aiex.npu.dma_memcpy_nd(%out[%c0,%c0,%c0,%c0][%c1,%c1,%c1,%c16][%c0,%c0,%c0,%c1]) {metadata = @of_out, id = 1 : i64} : memref<16xi32> + aiex.npu.dma_memcpy_nd(%in[%c0,%c0,%c0,%c0][%c1,%c1,%c1,%c16][%c0,%c0,%c0,%c1]) {metadata = @of_in, id = 0 : i64, issue_token = true} : memref<16xi32> + aiex.npu.dma_wait {symbol = @of_out} + } + } +} diff --git a/tools/aiecc/aiecc.cpp b/tools/aiecc/aiecc.cpp index 2897b95bab3..4e31f9145e9 100644 --- a/tools/aiecc/aiecc.cpp +++ b/tools/aiecc/aiecc.cpp @@ -457,8 +457,11 @@ static cl::opt outputFilename("o", cl::desc("Output filename for host compilation"), cl::init(""), cl::cat(aieCompilerOptions)); -// Sink for unrecognized host compilation flags (e.g. -Wl,... -lstdc++) -static cl::list sinkArgs(cl::Sink, cl::desc("Additional flags")); +// Host-compiler passthrough captured after the `--` separator on the command +// line, preserved in user-specified order. Anything before `--` must be a +// recognized aiecc option (or a positional input file); unknown flags there +// are rejected by ParseCommandLineOptions. +static std::vector hostExtraArgs; //===----------------------------------------------------------------------===// // Thread-safe output @@ -516,15 +519,19 @@ static std::string getInputFilename() { return ""; } -// Get host source files from positional arguments. +// Get host source files: positional args (before `--`) plus any host source +// files appearing among the post-`--` passthrough args. static std::vector getHostSourceFiles() { std::string mlirFile = getInputFilename(); std::vector hostFiles; - hostFiles.reserve(positionalArgs.size()); for (const auto &arg : positionalArgs) { if (arg != mlirFile && isHostSourceFile(arg)) hostFiles.push_back(arg); } + for (const auto &arg : hostExtraArgs) { + if (isHostSourceFile(arg)) + hostFiles.push_back(arg); + } return hostFiles; } @@ -5079,14 +5086,17 @@ static LogicalResult compileHostProgram(StringRef tmpDirName, cmd.push_back("-l" + lib); } - // Any additional unrecognized flags (e.g. -Wl,... -lstdc++) - for (const auto &arg : sinkArgs) { + // Post-`--` passthrough, in user-specified order. Host source files mixed + // in here are already included. + for (const auto &arg : hostExtraArgs) { cmd.push_back(arg); } - // Host source files - for (const auto &src : hostSourceFiles) { - cmd.push_back(src); + // Positional host source files (pre-`--` legacy form) + std::string mlirFile = getInputFilename(); + for (const auto &arg : positionalArgs) { + if (arg != mlirFile && isHostSourceFile(arg)) + cmd.push_back(arg); } // Output filename @@ -5621,8 +5631,28 @@ static int processInputFile(StringRef inputFile, StringRef tmpDirName) { int main(int argc, char **argv) { InitLLVM y(argc, argv); + // Split argv on the first standalone `--`. Everything after is forwarded + // verbatim to the host compiler (host-source files are routed separately + // via getHostSourceFiles()). Everything before must be a recognized aiecc + // option or input file; unknown flags there are rejected by LLVM. + std::vector frontArgv; + frontArgv.reserve(argc); + bool sawSeparator = false; + for (int i = 0; i < argc; ++i) { + if (i > 0 && !sawSeparator && std::strcmp(argv[i], "--") == 0) { + sawSeparator = true; + continue; + } + if (sawSeparator) { + hostExtraArgs.emplace_back(argv[i]); + } else { + frontArgv.push_back(argv[i]); + } + } + cl::AddExtraVersionPrinter(printVersion); - cl::ParseCommandLineOptions(argc, argv, "AIE Compiler Driver\n"); + cl::ParseCommandLineOptions(static_cast(frontArgv.size()), + frontArgv.data(), "AIE Compiler Driver\n"); if (showVersion) { printVersion(llvm::outs());