Open leonschoorl opened 4 years ago
The divide by zero
is because implementation of Prelude.^ uses Prelude.even
and that doesn't work for types that can't represent the value 2, see https://github.com/clash-lang/clash-compiler/issues/959
This hang with Bit is because Bit's Integral instance is a hardcoded and doesn't throw divide by zero
exceptions like the other instances do: https://github.com/clash-lang/clash-compiler/blob/d547dee8a33e2a3cddd7772bbf0df8e587f45d27/clash-prelude/src/Clash/Sized/Internal/BitVector.hs#L297-L303
Ideally for us we would put the | y == 1 = x
first as the first case in f in base's implementation of (^)
We should try these benchmarks to see if the order of the cases of this f
are just an implementation detail or important for performance.
Just to throw in an additional note, negate
for Bit
looks suspicious: It's complement
rather than id
Is this intended? It isn't negation modulo 2 (which is id
, which in turn justifies (+) = (-)
), so it doesn't even match with BitVector 1
. And also now 0 - x
isn't - x
.
ghci> negate 1 :: BitVector 1
1
ghci> negate 0 :: BitVector 1
0
ghci> negate 1 :: Bit
0
ghci> negate 0 :: Bit
1
Maybe whoever wrote that thought (- x)
might be a handy shortcut, and to be honest, negating a (non-0) unsigned value would cause an overflow in the first place, so it probably wouldn't have worked in generic code anyway. But I thought I should bring it up.