From 0ce1cbcae7af1902b421ff0acd0e00a8e8ba9de8 Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Thu, 1 Oct 2026 13:10:17 +0000 Subject: [PATCH 1/3] opt_dff: Fix ModWalker use-after-free between constbits and eqbits Commit fae99416d ("Only init modwalker once.") introduced a shared ModWalker in OptDffWorker reused across run_constbits() and run_eqbits(). However, when run_constbits() proves a flip-flop bit is constant, the below sequence occurs: OptDffPass::execute() | +-> worker.run_constbits() | |-> fold_const_bits() | | `-> add_const_target() | | `-> worker.get_modwalker() #[caches FF Cell* info in modwalker] | |-> ... | `-> worker.remove_ff_bits() | `-> new_ff.emit() #[deletes FF Cell* info in module. cell info in modwalker is stale] | `-> worker.run_eqbits() |-> gather_initial_eq_classes() `-> filter_classes_sim() |-> BitSim::sim() #[passes modwalker which has stale cell info] `-> sim.eval_bit() |-> cell = modwalker...find().cell #[derives stale cell info] `-> if (cell->is_builtin_ff()) #[*** crashed as cell pointer is already freed *** ] So, reset modwalker_ptr in remove_ff_bits() whenever flip-flop bits are removed so run_eqbits() rebuilds a fresh ModWalker only when the module netlist was modified. Reported-by: Sean Luchen Signed-off-by: Lokesh Vutla --- passes/opt/dff/opt_dff.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/passes/opt/dff/opt_dff.cc b/passes/opt/dff/opt_dff.cc index 4e6d459df..3d684c5f7 100644 --- a/passes/opt/dff/opt_dff.cc +++ b/passes/opt/dff/opt_dff.cc @@ -37,6 +37,8 @@ OptDffWorker::OptDffWorker(const OptDffOptions &opt, Module *mod) void OptDffWorker::remove_ff_bits(Cell *cell, const pool &drop) { + modwalker_ptr.reset(); + FfData ff(&initvals, cell); std::vector keep; for (int i = 0; i < ff.width; i++) From 40fd22d48b1f85b1dc58d44b1b2019388add38f3 Mon Sep 17 00:00:00 2001 From: Mohamed Gaber Date: Sat, 3 Oct 2026 10:39:29 +0300 Subject: [PATCH 2/3] wheels: fix pkgconfig path - fix erroneous use of `{project}` in CIBW_ENVIRONMENT - fix resulting breaking of PKG_CONFIG_PATH which is set in the manylinux environment to /usr/local/lib/pkgconfig - cibw_before_all.sh now pulls and builds bison and static libffi into local prefixes on an as-needed basis - remove linux download and homebrew install of bison in wheels.yml - add (rewritten) _test_cibw_local.py, based on earlier _run_cibw_linux.py but a bit more robust --- .github/workflows/wheels.yml | 24 +++------- .github/workflows/wheels/_test_cibw_local.py | 45 +++++++++++++++++++ .github/workflows/wheels/cibw_before_all.sh | 46 ++++++++++++++------ pyproject.toml | 5 ++- 4 files changed, 87 insertions(+), 33 deletions(-) create mode 100644 .github/workflows/wheels/_test_cibw_local.py diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 6aff2d73c..33875b0bd 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -55,24 +55,8 @@ jobs: - uses: actions/setup-python@v6 with: python-version: "3.x" - - name: Get FFI - shell: bash - run: | - mkdir -p ffi - curl -L https://github.com/libffi/libffi/releases/download/v3.4.8/libffi-3.4.8.tar.gz | tar --strip-components=1 -xzC ffi - - if: ${{ matrix.os.family == 'linux' }} - name: "[Linux] Bison 3.8.2" - shell: bash - run: | - mkdir -p bison - curl -L https://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.gz | tar --strip-components=1 -xzC bison ## Software installed by default in GitHub Action Runner VMs: ## https://github.com/actions/runner-images - - if: ${{ matrix.os.family == 'macos' }} - name: "[macOS] Flex/Bison" - run: | - brew install flex bison - echo "PATH=$(brew --prefix flex)/bin:$(brew --prefix bison)/bin:$PATH" >> $GITHUB_ENV - if: ${{ matrix.os.family == 'windows' }} name: "[Windows] Flex/Bison" run: | @@ -80,14 +64,16 @@ jobs: - name: Build wheels uses: pypa/cibuildwheel@v4.1.0 env: + CIBW_PROJECT_REQUIRES_PYTHON: ">=3.10" # * APIs not supported by PyPy # * Musllinux disabled because it increases build time from 48m to ~3h CIBW_SKIP: > - cp39* *musllinux* CIBW_ARCHS: ${{ matrix.os.archs }} CIBW_BUILD_VERBOSITY: "1" # manylinux2014 (default) does not have a modern enough C++ compiler for Yosys + # update: it technically does, devtoolset-11, but it's a matter of + # time before it doesn't CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28 CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28 CIBW_BEFORE_ALL: bash ./.github/workflows/wheels/cibw_before_all.sh @@ -95,8 +81,8 @@ jobs: cmake="-DCMAKE_BUILD_TYPE=Release -DYOSYS_ENABLE_HOMEBREW:BOOL=OFF" CIBW_ENVIRONMENT: > OPTFLAGS=-O3 - PKG_CONFIG_PATH={project}/ffi/pfx/lib/pkgconfig - PATH="{project}/bison/src:$PATH" + PKG_CONFIG_PATH="$PWD/ffi/pfx/lib/pkgconfig:$PKG_CONFIG_PATH" + PATH="$PWD/bison/pfx/bin:$PATH" MACOSX_DEPLOYMENT_TARGET=11 CIBW_BEFORE_BUILD: bash ./.github/workflows/wheels/cibw_before_build.sh CIBW_TEST_COMMAND: python3 {project}/tests/pyosys/run_tests.py diff --git a/.github/workflows/wheels/_test_cibw_local.py b/.github/workflows/wheels/_test_cibw_local.py new file mode 100644 index 000000000..de3d8790d --- /dev/null +++ b/.github/workflows/wheels/_test_cibw_local.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# Copyright (C) 2024 UmbraLogic Technologies LLC +# SPDX-License-Identifier: MIT +""" +This runs the cibuildwheel step from the wheels workflow locally. +""" + +import os +import sys +import platform +import subprocess +from pathlib import Path + +import yaml +from packaging.tags import sys_tags + +__yosys_root__ = Path(__file__).absolute().parents[3] + +with open(__yosys_root__ / ".github" / "workflows" / "wheels.yml") as f: + workflow = yaml.safe_load(f) + +env = os.environ.copy() + +steps = workflow["jobs"]["build_wheels"]["steps"] +cibw_step = None +for step in steps: + if (step.get("uses") or "").startswith("pypa/cibuildwheel"): + cibw_step = step + break + +env_filter = { + "linux": ("_WINDOWS", "_MAC"), + "darwin": ("_LINUX", "_WINDOWS"), + "win32": ("_LINUX", "_MAC"), +}[sys.platform] +for key, value in cibw_step["env"].items(): + if key.endswith(env_filter): + continue + if key not in env: # prioritize user-set keys + env[key] = value + +python_tag = next(sys_tags()).interpreter +env["CIBW_BUILD"] = os.getenv("CIBW_BUILD", f"{python_tag}-*") +env["CIBW_ARCHS"] = os.getenv("CIBW_ARCHS", platform.machine()) +subprocess.check_call(["cibuildwheel"], env=env) diff --git a/.github/workflows/wheels/cibw_before_all.sh b/.github/workflows/wheels/cibw_before_all.sh index 61bfb2181..3aac0237b 100644 --- a/.github/workflows/wheels/cibw_before_all.sh +++ b/.github/workflows/wheels/cibw_before_all.sh @@ -11,25 +11,45 @@ if command -v apk &> /dev/null; then apk add flex bison fi +## Platform-independent - just build bison if it's missing or out of date +BISON_VER="3.8.2" +BISON_SHA256SUM="9bba0214ccf7f1079c5d59210045227bcf619519840ebfa80cd3849cff5a5bf2" if ! printf '%s\n' '%require "3.8"' '%%' 'start: ;' | bison -o /dev/null /dev/stdin ; then + PREFIX=$PWD/bison/pfx + rm -rf $PREFIX + BISON_SRC=$(mktemp -d) ( set -e -x - cd bison - ./configure + cd $BISON_SRC + curl -L https://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.xz > bison.tar.xz + echo "$BISON_SHA256SUM bison.tar.xz" | sha256sum -c - + tar --strip-components=1 -xJC . -f bison.tar.xz + ./configure --prefix=$PREFIX make clean make install -j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu) ) + rm -rf $BISON_SRC fi -## macOS/Windows -- installed in GitHub Action itself, not container - # Runtime Dependencies -## Build Static FFI (platform-dependent but not Python version dependent) -( - set -e -x - cd ffi - ## Ultimate libyosys.so will be shared, so we need fPIC for the static libraries - LDFLAGS=-fPIC CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --prefix=$PWD/pfx --enable-static --disable-shared - make clean - make install -j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu) -) +## Build Static FFI (platform-dependent but not Python version dependent) if +## missing +LIBFFI_VER="3.4.8" +LIBFFI_SHA256SUM="bc9842a18898bfacb0ed1252c4febcc7e78fa139fd27fdc7a3e30d9d9356119b" +if ! echo "int main() {}" | cc -x c -l:libffi.a - ; then + PREFIX=$PWD/ffi/pfx + rm -rf $PREFIX + LIBFFI_SRC=$(mktemp -d) + ( + set -e -x + cd $LIBFFI_SRC + curl -L "https://github.com/libffi/libffi/releases/download/v${LIBFFI_VER}/libffi-${LIBFFI_VER}.tar.gz" > libffi.tar.gz + echo "$LIBFFI_SHA256SUM libffi.tar.gz" | sha256sum -c - + tar --strip-components=1 -xzC . -f libffi.tar.gz + ## Ultimate libyosys.so will be shared, so we need fPIC for the static libraries + LDFLAGS=-fPIC CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --prefix=$PREFIX --enable-static --disable-shared + make install -j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu) + PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig pkg-config libffi --validate + ) + rm -rf $LIBFFI_SRC +fi diff --git a/pyproject.toml b/pyproject.toml index ce2330b34..088ab4f91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,4 +10,7 @@ build-backend = "local_backend" [tool.ruff] target-version = "py310" -lint.ignore = ["F541"] +lint.ignore = [ + "F541", # f-string missing placeholders + "W191" , # tab indentation +] From 07dcadbf10d88e859e553d6ab52e3ff7279e732e Mon Sep 17 00:00:00 2001 From: Mohamed Gaber Date: Sat, 3 Oct 2026 12:35:21 +0300 Subject: [PATCH 3/3] wheels: also build flex - also build flex because the default flex on macOS, while up-to-date, is customized and incompatible with Yosys (yep) --- .github/workflows/wheels.yml | 2 +- .github/workflows/wheels/cibw_before_all.sh | 43 ++++++++++++++++----- .gitignore | 2 + 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 33875b0bd..592c24d46 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -82,7 +82,7 @@ jobs: CIBW_ENVIRONMENT: > OPTFLAGS=-O3 PKG_CONFIG_PATH="$PWD/ffi/pfx/lib/pkgconfig:$PKG_CONFIG_PATH" - PATH="$PWD/bison/pfx/bin:$PATH" + PATH="$PWD/bison/pfx/bin:$PWD/flex/pfx/bin:$PATH" MACOSX_DEPLOYMENT_TARGET=11 CIBW_BEFORE_BUILD: bash ./.github/workflows/wheels/cibw_before_build.sh CIBW_TEST_COMMAND: python3 {project}/tests/pyosys/run_tests.py diff --git a/.github/workflows/wheels/cibw_before_all.sh b/.github/workflows/wheels/cibw_before_all.sh index 3aac0237b..0649a538f 100644 --- a/.github/workflows/wheels/cibw_before_all.sh +++ b/.github/workflows/wheels/cibw_before_all.sh @@ -1,19 +1,18 @@ #!/usr/bin/env bash set -e -x +set -o pipefail # Build-time dependencies ## Linux Docker Images -if command -v yum &> /dev/null; then - yum install -y flex # manylinux's bison versions are hopelessly out of date -fi - if command -v apk &> /dev/null; then apk add flex bison fi -## Platform-independent - just build bison if it's missing or out of date +## Platform-independent +### just build bison if it's missing or out of date BISON_VER="3.8.2" BISON_SHA256SUM="9bba0214ccf7f1079c5d59210045227bcf619519840ebfa80cd3849cff5a5bf2" +which -a bison || true if ! printf '%s\n' '%require "3.8"' '%%' 'start: ;' | bison -o /dev/null /dev/stdin ; then PREFIX=$PWD/bison/pfx rm -rf $PREFIX @@ -21,16 +20,43 @@ if ! printf '%s\n' '%require "3.8"' '%%' 'start: ;' | bison -o /dev/null /dev/st ( set -e -x cd $BISON_SRC - curl -L https://ftp.gnu.org/gnu/bison/bison-3.8.2.tar.xz > bison.tar.xz + curl --connect-timeout 5 --retry 3 -L https://ftp.gnu.org/gnu/bison/bison-${BISON_VER}.tar.xz > bison.tar.xz echo "$BISON_SHA256SUM bison.tar.xz" | sha256sum -c - tar --strip-components=1 -xJC . -f bison.tar.xz ./configure --prefix=$PREFIX - make clean make install -j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu) ) rm -rf $BISON_SRC fi + +### The Xcode Command Line Tools ersion of flex has an Apple-specific +### extension where int is substituted for size_t in some parts of the codebase. +### This is not compatible with Yosys. +### +### Also, the AlmaLinux repos are slow. +### +### It's best to just build flex if we don't like its output. +TMP_LEXER=$(mktemp) +FLEX_VER="2.6.4" +FLEX_SHA256SUM="e87aae032bf07c26f85ac0ed3250998c37621d95f8bd748b31f15b33c45ee995" +which -a flex || true +if ! ( printf "\n%%%%\n. { }\n%%%%\n" | flex -+ -o $TMP_LEXER && grep "yyFlexLexer::LexerOutput" $TMP_LEXER | grep -v 'size_t' ) ; then + PREFIX=$PWD/flex/pfx + rm -rf $PREFIX + FLEX_SRC=$(mktemp -d) + ( + set -e -x + cd $FLEX_SRC + curl --connect-timeout 5 --retry 3 -L https://github.com/westes/flex/releases/download/v${FLEX_VER}/flex-${FLEX_VER}.tar.gz > flex.tar.gz + echo "$FLEX_SHA256SUM flex.tar.gz" | sha256sum -c - + tar --strip-components=1 -xzC . -f flex.tar.gz + ./configure --prefix=$PREFIX --disable-shared --disable-silent-rules CFLAGS=-D_GNU_SOURCE + make install -j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu) + ) + rm -rf $FLEX_SRC +fi + # Runtime Dependencies ## Build Static FFI (platform-dependent but not Python version dependent) if ## missing @@ -43,13 +69,12 @@ if ! echo "int main() {}" | cc -x c -l:libffi.a - ; then ( set -e -x cd $LIBFFI_SRC - curl -L "https://github.com/libffi/libffi/releases/download/v${LIBFFI_VER}/libffi-${LIBFFI_VER}.tar.gz" > libffi.tar.gz + curl --connect-timeout 5 --retry 3 -L "https://github.com/libffi/libffi/releases/download/v${LIBFFI_VER}/libffi-${LIBFFI_VER}.tar.gz" > libffi.tar.gz echo "$LIBFFI_SHA256SUM libffi.tar.gz" | sha256sum -c - tar --strip-components=1 -xzC . -f libffi.tar.gz ## Ultimate libyosys.so will be shared, so we need fPIC for the static libraries LDFLAGS=-fPIC CFLAGS=-fPIC CXXFLAGS=-fPIC ./configure --prefix=$PREFIX --enable-static --disable-shared make install -j$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu) - PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig pkg-config libffi --validate ) rm -rf $LIBFFI_SRC fi diff --git a/.gitignore b/.gitignore index bb1a08bba..761a7bb8e 100644 --- a/.gitignore +++ b/.gitignore @@ -61,9 +61,11 @@ /kernel/python_wrappers.cc /ffi /bison +/flex /venv /*.whl /*.egg-info +/wheelhouse # yosysjs dependency /viz.js