From 31b00b4c72f89cf7e9e61733141838cf7819f2db Mon Sep 17 00:00:00 2001 From: KrystalDelusion <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 31 Jan 2025 11:03:33 +1300 Subject: [PATCH 1/4] celledges: Use b_width_capped for left shifts `b_width_capped` already exists for preventing arithmetic overflow, limiting the value of `b_width` to 30. This just changes the left shifts to also use it. The caveat of incorrect results for extremely large values of `a_width` still applies, as does the improbability of that actually happening. This fixes #4844 (or at least, the floating point exception; the circuit still isn't valid but I think that's fine). --- kernel/celledges.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/celledges.cc b/kernel/celledges.cc index bad7124d9..68e55db02 100644 --- a/kernel/celledges.cc +++ b/kernel/celledges.cc @@ -253,13 +253,13 @@ void shift_op(AbstractCellEdgesDatabase *db, RTLIL::Cell *cell) if (a_width == 1 && is_signed) { int skip = 1 << (k + 1); int base = skip -1; - if (i % skip != base && i - a_width + 2 < 1 << b_width) + if (i % skip != base && i - a_width + 2 < 1 << b_width_capped) db->add_edge(cell, ID::B, k, ID::Y, i, -1); } else if (is_signed) { - if (i - a_width + 2 < 1 << b_width) + if (i - a_width + 2 < 1 << b_width_capped) db->add_edge(cell, ID::B, k, ID::Y, i, -1); } else { - if (i - a_width + 1 < 1 << b_width) + if (i - a_width + 1 < 1 << b_width_capped) db->add_edge(cell, ID::B, k, ID::Y, i, -1); } // right shifts From cf52cf300916d82eaee0194b29d9ae342c0a6d68 Mon Sep 17 00:00:00 2001 From: KrystalDelusion <93062060+KrystalDelusion@users.noreply.github.com> Date: Fri, 31 Jan 2025 12:15:53 +1300 Subject: [PATCH 2/4] nowrshmsk: Check for stride==0 log2(0) returns -inf, which gives undefined behaviour when casting to an int. So catch the case when it's 0 just set the width to 0. --- frontends/ast/simplify.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index b00cde28e..d35756d4e 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2936,7 +2936,10 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin lsb_expr->children[stride_ix]->detectSignWidth(stride_width, stride_sign); max_width = std::max(i_width, stride_width); // Stride width calculated from actual stride value. - stride_width = std::ceil(std::log2(std::abs(stride))); + if (stride == 0) + stride_width = 0; + else + stride_width = std::ceil(std::log2(std::abs(stride))); if (i_width + stride_width > max_width) { // For (truncated) i*stride to be within the range of dst, the following must hold: From f5c53a99e76cef918b01e8b1b773c6be7b18e1e0 Mon Sep 17 00:00:00 2001 From: Catherine Date: Tue, 14 Jan 2025 06:11:52 +0000 Subject: [PATCH 3/4] CI: Sanitize for undefined behavior. --- .github/workflows/test-build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test-build.yml b/.github/workflows/test-build.yml index 95af300c9..6a69caaea 100644 --- a/.github/workflows/test-build.yml +++ b/.github/workflows/test-build.yml @@ -56,6 +56,7 @@ jobs: mkdir build cd build make -f ../Makefile config-$CC + echo 'SANITIZER = undefined' >> Makefile.conf make -f ../Makefile -j$procs ENABLE_LTO=1 - name: Log yosys-config output @@ -82,6 +83,7 @@ jobs: if: needs.pre_job.outputs.should_skip != 'true' env: CC: clang + UBSAN_OPTIONS: halt_on_error=1 strategy: matrix: os: [ubuntu-latest, macos-latest] From 212d2a6d6e962606c825a136a34bdee02d0d9c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Povi=C5=A1er?= Date: Mon, 3 Feb 2025 11:13:07 +0100 Subject: [PATCH 4/4] lib/fst: Remove unaligned pointer access --- libs/fst/00_PATCH_strict_alignment.patch | 42 ++++++++++++++++++++++++ libs/fst/00_UPDATE.sh | 1 + libs/fst/fastlz.cc | 21 +----------- 3 files changed, 44 insertions(+), 20 deletions(-) create mode 100644 libs/fst/00_PATCH_strict_alignment.patch diff --git a/libs/fst/00_PATCH_strict_alignment.patch b/libs/fst/00_PATCH_strict_alignment.patch new file mode 100644 index 000000000..77946824d --- /dev/null +++ b/libs/fst/00_PATCH_strict_alignment.patch @@ -0,0 +1,42 @@ +diff --git a/fastlz.cc b/fastlz.cc +index 3272ca7a8..41ea27a16 100644 +--- a/fastlz.cc ++++ b/fastlz.cc +@@ -60,24 +60,9 @@ + #endif + + /* +- * Prevent accessing more than 8-bit at once, except on x86 architectures. ++ * Yosys patch: do not do unaligned accesses on any platform + */ +-#if !defined(FASTLZ_STRICT_ALIGN) + #define FASTLZ_STRICT_ALIGN +-#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */ +-#undef FASTLZ_STRICT_ALIGN +-#elif defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__amd64) /* GNU C */ +-#undef FASTLZ_STRICT_ALIGN +-#elif defined(_M_IX86) /* Intel, MSVC */ +-#undef FASTLZ_STRICT_ALIGN +-#elif defined(__386) +-#undef FASTLZ_STRICT_ALIGN +-#elif defined(_X86_) /* MinGW */ +-#undef FASTLZ_STRICT_ALIGN +-#elif defined(__I86__) /* Digital Mars */ +-#undef FASTLZ_STRICT_ALIGN +-#endif +-#endif + + /* prototypes */ + int fastlz_compress(const void* input, int length, void* output); +@@ -88,11 +73,7 @@ int fastlz_decompress(const void* input, int length, void* output, int maxout); + #define MAX_LEN 264 /* 256 + 8 */ + #define MAX_DISTANCE 8192 + +-#if !defined(FASTLZ_STRICT_ALIGN) +-#define FASTLZ_READU16(p) *((const flzuint16*)(p)) +-#else + #define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8) +-#endif + + #define HASH_LOG 13 + #define HASH_SIZE (1<< HASH_LOG) diff --git a/libs/fst/00_UPDATE.sh b/libs/fst/00_UPDATE.sh index aef0e4fe8..7ab74d7cd 100755 --- a/libs/fst/00_UPDATE.sh +++ b/libs/fst/00_UPDATE.sh @@ -17,3 +17,4 @@ sed -i -e 's,"fastlz.c","fastlz.cc",' *.cc *.h patch -p0 < 00_PATCH_win_zlib.patch patch -p0 < 00_PATCH_win_io.patch +patch -p1 < 00_PATCH_strict_alignment.patch diff --git a/libs/fst/fastlz.cc b/libs/fst/fastlz.cc index 3272ca7a8..41ea27a16 100644 --- a/libs/fst/fastlz.cc +++ b/libs/fst/fastlz.cc @@ -60,24 +60,9 @@ #endif /* - * Prevent accessing more than 8-bit at once, except on x86 architectures. + * Yosys patch: do not do unaligned accesses on any platform */ -#if !defined(FASTLZ_STRICT_ALIGN) #define FASTLZ_STRICT_ALIGN -#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__amd64) /* GNU C */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(_M_IX86) /* Intel, MSVC */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(__386) -#undef FASTLZ_STRICT_ALIGN -#elif defined(_X86_) /* MinGW */ -#undef FASTLZ_STRICT_ALIGN -#elif defined(__I86__) /* Digital Mars */ -#undef FASTLZ_STRICT_ALIGN -#endif -#endif /* prototypes */ int fastlz_compress(const void* input, int length, void* output); @@ -88,11 +73,7 @@ int fastlz_decompress(const void* input, int length, void* output, int maxout); #define MAX_LEN 264 /* 256 + 8 */ #define MAX_DISTANCE 8192 -#if !defined(FASTLZ_STRICT_ALIGN) -#define FASTLZ_READU16(p) *((const flzuint16*)(p)) -#else #define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8) -#endif #define HASH_LOG 13 #define HASH_SIZE (1<< HASH_LOG)