From 41d8dd8a9f604ba4596f871641ad6c5a690237aa Mon Sep 17 00:00:00 2001 From: Erika Hunhoff Date: Tue, 12 May 2026 11:36:47 -0600 Subject: [PATCH 1/2] [aiecc] Reject unknown command-line arguments before `--` (#2989) aiecc previously declared a `cl::Sink` list that absorbed every unrecognized command-line argument and forwarded them to host compilation. This silently swallowed typos like `--aie-genrate-npu-insts` and made it impossible to tell aiecc-targeted flags apart from host-compiler passthrough. Pre-split argv on the first standalone `--`. Everything before is parsed by `cl::ParseCommandLineOptions` with no sink, so unrecognized flags become hard errors. Everything after is captured verbatim into a new `hostExtraArgs` vector and emitted in user-specified order during host compilation. Host source files appearing among the post-`--` args are also picked up by `getHostSourceFiles()`. Adds `test/aiecc/unknown_args_rejected.mlir` covering `--garbage`, the `--aie-genrate-npu-insts` typo from the issue, and the post-`--` passthrough path. Updates `cpp_host_compile.mlir`'s HOSTFULL run line to demonstrate the `--` separator form. Existing aiecc-recognized options (-I, -L, -l, -o, --sysroot, etc.) keep working without `--` since they bind to their own cl::opt/cl::list declarations. Co-Authored-By: Claude Opus 4 (1M context) --- test/aiecc/cpp_host_compile.mlir | 7 ++-- test/aiecc/unknown_args_rejected.mlir | 51 +++++++++++++++++++++++++++ tools/aiecc/aiecc.cpp | 50 ++++++++++++++++++++------ 3 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 test/aiecc/unknown_args_rejected.mlir 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()); From 63dea0ad606b32cfb60c1dba663eeb8a45534ff8 Mon Sep 17 00:00:00 2001 From: Erika Hunhoff Date: Wed, 13 May 2026 11:52:31 -0600 Subject: [PATCH 2/2] Drop unknown --aie-generate-npu flag from gelu/silu/swiglu Makefiles These three Makefiles passed --aie-generate-npu alongside the real --aie-generate-npu-insts flag; the former was silently ignored before this PR's strict argument check and is now a hard error. Co-Authored-By: Claude Opus 4 (1M context) --- programming_examples/ml/gelu/Makefile | 2 +- programming_examples/ml/silu/Makefile | 2 +- programming_examples/ml/swiglu/Makefile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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