Highlights:
-
Very significant performance improvements, further detailed below. We also created a site https://clash-lang.github.io/clash-benchmarks/ where we track performance improvements. These graphs are for the current
masterbranch, not for released Clash versions. -
We have added support for the
checked-literalspackage. Numeric literals (e.g.,5or3.2) can now be checked at compile time. That is, you'll get a compile error if the literal does not fit the target type -- even in polymorphic contexts! You can enable the checker by adding the following to your project's Cabal file:library [..] build-depends: [..] checked-literals ghc-options: -fplugin=CheckedLiteralsSee https://clash-lang.org/blog/2026-04-07-checked-literals/.
Performance:
-
clashandclashinow use GHC-style RTS defaults through executable-with-rtsoptsflags instead of linking RTS hooks. The existing unused hooks have been removed. Existing users should set-with-rtsoptsto-K512M -H -I5 -Tif they use their own Clash executable. These flags has been shown to give a ~25% compilation speed up in larger designs. If you used a Clash starter project to initialize your design, you should change:executable clash [..]To:
executable clash [..] ghc-options: "-with-rtsopts=-K512M -H -I5 -T"
in the cabal file. See #3252.
-
Improved normalization performance for repeated top-down rewrite loops by avoiding full root restarts after every successful rewrite. This gives a ~17% performance improvements on larger designs #3249.
-
Clash now converts GHC Core to its own Clash Core in parallel. For larger projects, this can shave off ~40% of load times. See #3299.
-
Clash now prunes the binders it collects from top modules when loading from precompiled core. For larger projects, this can shave off 15% of package loading times. See #3298.
-
flattenCallTreenow caches intermediate results, reducing Clash normalization by 10% for realistic designs. Fixes #3246.
Added:
-fclash-debug-manifest-hash. When enabled, Clash emits a__debug_hashobject inclash-manifest.jsonlisting the SHA256 of each input that feeds into the top-levelhash(tops,prim_map,clash_mod_date,call_graph,opts). As the name implies, this should only be used to debug and should not be relied upon by tooling. See #3280.SaturatingNuminstances forErroring,Overflowing,Saturating,Wrapping, andZeroing.
Changed:
- Replaced the deprecated
data-binary-ieee754dependency withcastDoubleToWord64,castFloatToWord32,castWord32ToFloat, andcastWord64ToDoublefromGHC.Float. See #3174. flake.nixnow advertises the clash-lang Cachix binary cache vianixConfig.extra-substituters. Runningnix developwill prompt you to trust the cache, avoiding having to build Clash from source. See #3213.
Fixed:
- Clash no longer crashes for self-recursive global binders in very specific circumstances. See #3311.
- Clash no longer crashes upon calling
sequenceA/traverse#on a zero-sizedVec. See #3290. - Clash no longer crashes when constant-folding partial primitives in the GHC evaluator. This covers
shiftL/shiftR/rotateL/rotateRwith negative shift amounts onBitVector/Signed/Unsigned,(^)with negative exponents,chron out-of-range integers, andquot/rem/div/modby zero onInt/Word/Int{8,16,32,64}/Word{8,16,32,64}. Such expressions now fold toundefined(rather than crashing the compiler). Fixes #3234. - Clash no longer crashes with
mkVecNil: failed to instantiate Nil DCwhen unfoldingtraverse#in very specific circumstances. See #3291. - Clash no longer errors when two
-iimport paths refer to the same directory via different syntactic spellings (e.g.-isrc -isrc/.) and a data file lives in that directory. See #3142. - Clash no longer produces an error when using
dataToTagin combination with custom bit representations. See #2724. - Clash no longer takes exponential time and memory normalizing
foldl/scanl/splitAtover a vector when the result keeps the (co-recursively defined) vector spine alive, e.g.snd (foldl const (z, s) (xs :: Vec n a)). The evaluator'szipWithandsplitAtreductions now share their arguments instead of duplicating the vector spine on every peel. See #3308. - Clash now recognizes
~when solving GADT arms. Fixes #3232. - Clash will no longer generate duplicate
attributewhen they're both used for top entity ports and internal signals. See #3218. The VHDL backend now also reports a clearer error when a synthesis attribute is declared with conflicting types in the same design. - Due to HDL standards, when the result of a top entity is read by another binder Clash is forced to introduce an internal indirection signal. Clash no longer attaches the top entity's
Annotatesynthesis attributes to that internal signal, preventing duplicate synthesis attributes in the generated HDL. See #3224. - Errors in
Synthesizeport annotations (e.g. aPortProducton a non-product port) are now reported before a design is normalized, instead of afterwards. This avoids waiting for a potentially long normalization only to get a trivial port error. See #3305. - Run
bindConstantVarafter post-normalizationinlineCleanup/caseConso constant let-bindings exposed late are inlined before netlist generation #3041. - The VHDL primitives for
integerToNaturalThrowandintegerToNaturalClampno longer contain syntax errors. See #3315. - The internal function
Clash.Util.Interpolate.iinclash-libno longer inserts an extra blank line after a paragraph that gets reflowed onto multiple lines. See #2753. deriveAutoRegno longer fails on GHC versions whereKnownNatlives inGHC.Internal.TypeNatsrather thanGHC.TypeNats. See #3100.makeTopEntitynow accounts for unary product types. See #3066.