diff --git a/lib/Conversion/FlyToROCDL/FlyToROCDL.cpp b/lib/Conversion/FlyToROCDL/FlyToROCDL.cpp index 7b37660ee..240770dbe 100644 --- a/lib/Conversion/FlyToROCDL/FlyToROCDL.cpp +++ b/lib/Conversion/FlyToROCDL/FlyToROCDL.cpp @@ -776,24 +776,17 @@ class GpuLaunchFuncOpLowering : public OpConversionPattern { if (Value tok = op.getAsyncToken()) asyncTokenType = tok.getType(); - // There are two relevant builder signatures in this MLIR: - // - (kernel, ..., asyncTokenType, asyncDependencies, clusterSize) - // - (kernel, ..., asyncObject, clusterSize) - // Pick the one that matches the original op structure. - if (Value asyncObj = adaptor.getAsyncObject()) { - if (!adaptor.getAsyncDependencies().empty()) - return rewriter.notifyMatchFailure( - op, "launch_func has both asyncObject and asyncDependencies"); - - rewriter.replaceOpWithNewOp( - op, kernelRef, grid, block, adaptor.getDynamicSharedMemorySize(), - adaptor.getKernelOperands(), asyncObj, clusterSize); - return success(); - } + // The two former builder signatures (one taking asyncTokenType + + // asyncDependencies, one taking asyncObject) were merged upstream into a + // single builder that takes all of them. + if (adaptor.getAsyncObject() && !adaptor.getAsyncDependencies().empty()) + return rewriter.notifyMatchFailure(op, + "launch_func has both asyncObject and asyncDependencies"); rewriter.replaceOpWithNewOp( op, kernelRef, grid, block, adaptor.getDynamicSharedMemorySize(), - adaptor.getKernelOperands(), asyncTokenType, adaptor.getAsyncDependencies(), clusterSize); + adaptor.getKernelOperands(), asyncTokenType, adaptor.getAsyncDependencies(), + adaptor.getAsyncObject(), clusterSize); return success(); } }; diff --git a/lib/Dialect/Fly/Transforms/LayoutLowering.cpp b/lib/Dialect/Fly/Transforms/LayoutLowering.cpp index 46950b5ca..faab099ce 100644 --- a/lib/Dialect/Fly/Transforms/LayoutLowering.cpp +++ b/lib/Dialect/Fly/Transforms/LayoutLowering.cpp @@ -2952,7 +2952,7 @@ static std::optional narrowUpperBound(Value v, unsigned depth, // A value reached twice on one walk (cyclic chain) cannot be bounded here. if (!visited.insert(def).second) return std::nullopt; - auto pop = llvm::make_scope_exit([&] { visited.erase(def); }); + auto pop = llvm::scope_exit([&] { visited.erase(def); }); // Launch coordinates: ask the op for its own range. Every gpu index op // implements InferIntRangeInterface, and that implementation already prefers diff --git a/python/flydsl/__init__.py b/python/flydsl/__init__.py index ce9b9b35c..d3095c7a0 100644 --- a/python/flydsl/__init__.py +++ b/python/flydsl/__init__.py @@ -2,7 +2,7 @@ # Copyright (c) 2025 FlyDSL Project Contributors # ruff: noqa: I001 -__version__ = "0.3.3" +__version__ = "0.3.3.dev887" from .autotune import Config as Config, autotune as autotune diff --git a/scripts/build_llvm.sh b/scripts/build_llvm.sh index b0dfdb313..5b5cc0325 100755 --- a/scripts/build_llvm.sh +++ b/scripts/build_llvm.sh @@ -13,9 +13,55 @@ LLVM_INSTALL_DIR="${LLVM_INSTALL_DIR:-$LLVM_SRC_DIR/mlir_install}" LLVM_INSTALL_TGZ="${LLVM_INSTALL_TGZ:-$LLVM_SRC_DIR/mlir_install.tgz}" LLVM_PACKAGE_INSTALL="${LLVM_PACKAGE_INSTALL:-1}" -# Read LLVM commit hash from thirdparty/llvm-build-info.json (upstream entry) +# Parse CLI args early so --llvm-entry is available before reading the JSON. +for arg in "$@"; do + case "$arg" in + --llvm-entry=*) LLVM_BUILD_ENTRY="${arg#*=}" ;; + esac +done + +# Read LLVM commit hash from thirdparty/llvm-build-info.json. +# Use --llvm-entry= or LLVM_BUILD_ENTRY to select a non-default entry, +# or pick interactively when neither is set and stdin is a terminal. LLVM_BUILD_INFO="${REPO_ROOT}/thirdparty/llvm-build-info.json" -LLVM_COMMIT_DEFAULT=$(python3 -c "import json; print(json.load(open('${LLVM_BUILD_INFO}'))['upstream']['llvm_hash'])") +if [ -z "${LLVM_BUILD_ENTRY}" ] && [ -t 0 ]; then + mapfile -t LLVM_ENTRIES < <(python3 -c " +import json +info = json.load(open('${LLVM_BUILD_INFO}')) +for k in info: + desc = info[k].get('description', '') + suffix = ' -- ' + desc if desc else '' + print(k + suffix) +") + if [ "${#LLVM_ENTRIES[@]}" -gt 1 ]; then + echo "Available LLVM build entries:" + for i in "${!LLVM_ENTRIES[@]}"; do + default_tag="" + entry_name="${LLVM_ENTRIES[$i]%% --*}" + if [ "$entry_name" = "upstream" ]; then + default_tag=" (default)" + fi + echo " $((i+1))) ${LLVM_ENTRIES[$i]}${default_tag}" + done + read -r -p "Select entry [1]: " choice + choice="${choice:-1}" + idx=$((choice - 1)) + if [ "$idx" -ge 0 ] && [ "$idx" -lt "${#LLVM_ENTRIES[@]}" ]; then + LLVM_BUILD_ENTRY="${LLVM_ENTRIES[$idx]%% --*}" + else + echo "Invalid selection, using 'upstream'." + LLVM_BUILD_ENTRY="upstream" + fi + fi +fi +LLVM_BUILD_ENTRY="${LLVM_BUILD_ENTRY:-upstream-main-add-unclausevmem-patch}" +LLVM_COMMIT_DEFAULT=$(python3 -c "import json; print(json.load(open('${LLVM_BUILD_INFO}'))['${LLVM_BUILD_ENTRY}']['llvm_hash'])") +LLVM_CHERRY_PICKS=$(python3 -c " +import json +entry = json.load(open('${LLVM_BUILD_INFO}')).get('${LLVM_BUILD_ENTRY}', {}) +commits = entry.get('cherry_pick_commits', []) +print(' '.join(commits)) +") LLVM_REF="${LLVM_REF:-${LLVM_COMMIT:-$LLVM_COMMIT_DEFAULT}}" LLVM_PATCH="${REPO_ROOT}/thirdparty/llvm-rocdl-lld-argv0.patch" LLVM_BUILD_PROFILE="${LLVM_BUILD_PROFILE:-full}" @@ -43,7 +89,11 @@ echo "LLVM Source: $LLVM_SRC_DIR" echo "LLVM Build: $LLVM_BUILD_DIR" echo "LLVM Install: $LLVM_INSTALL_DIR" echo "LLVM Tarball: $LLVM_INSTALL_TGZ" +echo "LLVM Entry: $LLVM_BUILD_ENTRY" echo "LLVM Ref: $LLVM_REF" +if [ -n "${LLVM_CHERRY_PICKS}" ]; then + echo "LLVM Cherry: ${LLVM_CHERRY_PICKS}" +fi echo "LLVM Profile: $LLVM_BUILD_PROFILE" echo "LLVM Projects: $LLVM_ENABLE_PROJECTS" echo "LLVM Targets: $LLVM_TARGETS_TO_BUILD" @@ -93,6 +143,42 @@ else git checkout FETCH_HEAD fi +# Cherry-pick commits if the selected entry lists any. +if [ -n "${LLVM_CHERRY_PICKS}" ]; then + echo "Cherry-picking upstream commits for entry '${LLVM_BUILD_ENTRY}' ..." + LLVM_UPSTREAM_REMOTE="${LLVM_UPSTREAM_REMOTE:-https://github.com/llvm/llvm-project.git}" + if ! git remote get-url upstream >/dev/null 2>&1; then + git remote add upstream "${LLVM_UPSTREAM_REMOTE}" + fi + for cherry_hash in ${LLVM_CHERRY_PICKS}; do + if git merge-base --is-ancestor "${cherry_hash}" HEAD 2>/dev/null; then + echo " ${cherry_hash} already present, skipping." + continue + fi + echo " Fetching and cherry-picking ${cherry_hash} ..." + git fetch --depth=2 upstream "${cherry_hash}" + if ! git cherry-pick --no-commit "${cherry_hash}" 2>/dev/null; then + # Auto-resolve .ll test file conflicts with theirs strategy; + # fail if any non-.ll file has conflicts. + conflict_files=$(git diff --name-only --diff-filter=U) + non_ll_conflicts=$(echo "$conflict_files" | grep -v '\.ll$' | grep -v '^$' || true) + if [ -n "$non_ll_conflicts" ]; then + echo "ERROR: non-test-file conflicts during cherry-pick of ${cherry_hash}:" >&2 + echo "$non_ll_conflicts" >&2 + exit 1 + fi + echo " Resolving .ll test file conflicts with theirs strategy ..." + echo "$conflict_files" | while read -r f; do + [ -n "$f" ] && git checkout --theirs -- "$f" && git add "$f" + done + fi + done + if ! git diff --cached --quiet; then + git -c user.name="FlyDSL CI" -c user.email="flydsl-ci@noreply" \ + commit -m "cherry-pick: gfx1250 unclaused VMEM prologue fixes (#215450, #216897)" + fi +fi + if git apply --reverse --check "${LLVM_PATCH}" >/dev/null 2>&1; then echo "LLVM patch already applied: ${LLVM_PATCH}" else diff --git a/thirdparty/llvm-build-info.json b/thirdparty/llvm-build-info.json index 3df201869..8be90a851 100644 --- a/thirdparty/llvm-build-info.json +++ b/thirdparty/llvm-build-info.json @@ -2,5 +2,14 @@ "upstream": { "repository": "https://github.com/llvm/llvm-project.git", "llvm_hash": "e2a39f504fee836e4def9581bed817ecc327b9dc" + }, + "upstream-main-add-unclausevmem-patch": { + "repository": "https://github.com/llvm/llvm-project.git", + "llvm_hash": "941a04e69ee8fe4c7a162b2f1e215aa8df867534", + "cherry_pick_commits": [ + "1109d68feb1b746c675d8f88fb89085334f8f514", + "739eaa08d45e5f6e5d13b1dd82daf0e5dc27e344" + ], + "description": "gfx1250: fix unclaused VMEM prologue (base=#214885 incl #214127; cherry-pick #215450, #216897)" } }