Skip to content

Add evaluator rule for bigNatEq# (copy #3123)#3126

Open
mergify[bot] wants to merge 1 commit into1.8from
mergify/copy/1.8/pr-3123
Open

Add evaluator rule for bigNatEq# (copy #3123)#3126
mergify[bot] wants to merge 1 commit into1.8from
mergify/copy/1.8/pr-3123

Conversation

@mergify
Copy link
Copy Markdown
Contributor

@mergify mergify bot commented Jan 23, 2026

Fixes #3084

Still TODO:

@mergify mergify bot added the conflicts label Jan 23, 2026
@mergify
Copy link
Copy Markdown
Contributor Author

mergify bot commented Jan 23, 2026

Cherry-pick of 0b6aa0d has failed:

On branch mergify/copy/1.8/pr-3123
Your branch is up to date with 'origin/1.8'.

You are currently cherry-picking commit 0b6aa0d5.
  (fix conflicts and run "git cherry-pick --continue")
  (use "git cherry-pick --skip" to skip this patch)
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Changes to be committed:
	new file:   changelog/2026-01-22T17_03_38+01_00_fix_3084
	modified:   tests/Main.hs
	new file:   tests/shouldwork/Issues/T3084.hs

Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   clash-ghc/src-ghc/Clash/GHC/Evaluator/Primitive.hs

To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally

Fixes #3084

(cherry picked from commit 0b6aa0d)
@DigitalBrains1 DigitalBrains1 force-pushed the mergify/copy/1.8/pr-3123 branch from 6caa869 to 9eaf21d Compare January 23, 2026 14:01
@DigitalBrains1 DigitalBrains1 enabled auto-merge (squash) January 23, 2026 14:03
@DigitalBrains1
Copy link
Copy Markdown
Member

It turns out, in old GHC's the primitive is probably defined in a different module. I'll fix it.

@leonschoorl
Copy link
Copy Markdown
Member

Starting in GHC 9.0.1 big-number support was changed from integer-gmp (or possibly integer-simple depending on ghc build time configuration) to ghc-bignum.
See also our own clash-lib.cabal

Since bigNatEq# only exists inside the ghc-bignum library, you can #ifdef the addition out on pre 9.0 GHC versions.

@DigitalBrains1
Copy link
Copy Markdown
Member

Thanks! I'm aware already. But I do not have a reproducer to test the code path on GHC 9.0 and GHC 9.2, so the backport will only make the primive evaluator rule available in GHC 9.4+.

@leonschoorl
Copy link
Copy Markdown
Member

I looked into it some more, and I believe you're right, this rule isn't needed on GHC < 9.4.

bigNatEq# only became a primitive when it was marked as NOINLINE in e1d02fb0, which was first included in ghc-bignum-1.3, and which was first shipped with GHC-9.4.

The test can be simplified(?) to

module T3084 where

import Clash.Prelude hiding (SNat, Mod)
import GHC.Num.BigNat (bigNatEq#)
import GHC.Num.Natural (Natural(..))
import GHC.Base (isTrue#)

-- | Prevent GHC from constant folding operations. Clash should be able to
-- do it though.
lit
  :: Num a
  => Unsigned 64
  -> a
lit = fromIntegral

topEntity :: Bool
topEntity = f bigNatural bigNatural
 where
   bigNatural = lit maxBound + 1
   bigNatural :: Natural

f :: Natural -> Natural -> Bool
f (NB x) (NB y) = isTrue# (bigNatEq# x y)
-- f (NS _) (NS _) = ...
f _      _      = False

Which compiles on all GHC >= 9.0.

On GHC 9.0 & 9.2 this results in
No blackbox found for: _INTERNAL_.{__ffi_static_ccall_unsafe ghc-bignum-1.1:__gmpn_cmp
But all all "normal" ways of comparing Nat(ural)s always goes through GHC.Num.Natural.naturalEq# and that does have an evaluator rule.
And as you can see in the linked commit above that naturalEq# did have an NOINLINE before ghc-bignum-1.3, so it'll always trigger that evaluator rule.

I wonder if this means we should be dropping that evaluator rule with ghc-bignum >=1.3.

@leonschoorl
Copy link
Copy Markdown
Member

leonschoorl commented Jan 28, 2026

On a related note it is somewhat problematic that naturalEq# is no longer a primitive.
This means that clash now gets exposed to the internal representation of Natural.

topEntity :: Natural -> Natural ->  Bool
topEntity = (==)

now results in

    Clash.Netlist.BlackBox(353): No blackbox found for: GHC.Num.BigNat.bigNatEq#

on GHC >= 9.4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants