Perhaps ghc-bignum "primitives" should be allowed to inline.
There are various rules for conversions between types that generally work well.
However for a patch of mine the rules failed to fire and I saw things like this expression.
```
(case GHC.Num.Integer.$wintegerToWord#
(case i_aN8 of { GHC.Types.I# i_a2i7 ->
GHC.Num.Integer.IS i_a2i7
})
```
If integerToWord would be allowed to inline this would still compile to a no-op.
Now I wonder if we could run into similar situations with user-defined numeric types. Can these cause rules to fail to fire and can we then end up in the same situation?
I don't have code where it does happen (outside of my patch) currently. But I thought @hsyl20 might be able to say if this should be a concern or not without spending too much time on it.
----------
(Edit by @hsyl20)
The idea would be to only keep BigNat# primitives opaque but to allow Integer/Natural primitives to inline.
List of ghc-bignum primitives that are not inlined:
* Natural
* [X] naturalFromBigNat# - won't do as it uses BigNat# internals
* [ ] naturalToBigNat# - need constant folding for bigNatFromWord#
* [ ] naturalToWord# - need constant folding for bigNatIndex#
* [x] naturalToWordClamp# - just inline
* [x] naturalGe# - need constant folding for bigNatGe# (or just bigNatCompare?)
* [x] naturalLe# - need constant folding for bigNatLe# (ditto)
* [x] naturalGt# - need constant folding for bigNatGt# (ditto)
* [x] naturalLt# - need constant folding for bigNatLt# (ditto)
* [x] naturalCompare - need constant folding for bigNatCompare
* [ ] naturalPopCount# - need constant folding for bigNatPopCount#
* [ ] naturalShiftR# - need constant folding for bigNatShiftR#
* [ ] naturalShiftL# - need constant folding for bigNatShiftL# (clz# should already be done)
* [ ] naturalAdd - need constant folding for addWordC# (not sure if we have it), bigNatFromWord2#, bigNatAddWord# and bigNatAdd
* [ ] naturalSub - need constant folding for bigNatSubWordUnsafe#, subWordC#, bigNatSub
* [ ] naturalSubThrow - rewrite using naturalSub
* [ ] naturalSubUnsafe - c-f for bigNatSubWordUnsafe#, bigNatSub
* [ ] naturalMul - put 0/1 tests in new naturalMulWord#, need constant folding for naturalFromWord2#
* [ ] naturalMulWord (new) - need constant folding for bigNatMul, bigNatMulWord#
* [x] naturalSignum - just inline
* [x] naturalNegate - just inline
* [ ] naturalQuotRem - need constant folding for bigNatQuotRemWord#, bigNatQuotRem#
* [ ] naturalQuot - need constant folding for bigNatQuotWord#, bigNatQuot
* [ ] naturalRem - need constant folding for bigNatRemWord#, bigNatRem
* [ ] naturalAnd - need constant folding for bigNatToWord#, bigNatAnd
* [ ] naturalAndNot, naturalOr, naturalXor - similar to naturalAnd
* [ ] naturalTestBit# - need constant folding for bigNatTestBit#
* [ ] naturalBit# - need constant folding for bigNatBit#
* [ ] naturalGcd - need constant folding for gcdWord#, bigNatGcdWord#, bigNatGcd
* [ ] naturalLcm - need constant folding for bigNatLcmWordWord#, bigNatLcmWord#, bigNatLcm
* [ ] naturalLog2# - need constant folding for bigNatLog2
* [ ] naturalLogBaseWord# - need constant folding for wordLogBase#, bigNatLogBaseWord#
* [ ] naturalLogBase# - need constant folding for bigNatLogBase#
* [ ] naturalPowMod - need constant folding for powModWord#, bigNatPowModWord#, bigNatPowMod
* [ ] naturalSizeInBase# - need constant folding for wordLogBase#, bigNatSizeInBase#
* [x] naturalToAddr# - just inline and make bigNatToAddrLE/BE# NOINLINE
* [x] naturalFromAddr# - just inline and make bigNatFromAddrLE/BE# NOINLINE
* [x] naturalToMutableByteArray# - just inline and make bigNatToMutableByteArrayLE/BE# NOINLINE
* [x] naturalFromByteArray# - just inline and make bigNatFromByteArrayLE/BE# NOINLINE
* Integer
* [ ] integerToInt# - need cf bigNatToWord#
* [ ] integerFromWord# - need cf for bigNatFromWord#
* [ ] integerToWord# - need cf for bigNatToWord#
* [ ] integerFromNatural - just inline (relies on integerFromWord#)
* [ ] integerToNaturalClamp - need cf for naturalFromBigNat#, naturalFromWord#
* [ ] integerToNatural - need cf for naturalFromBigNat#, naturalFromWord#
* [ ] integerToNaturalThrow - need cf for naturalFromWord#, naturalFromBigNat#
* [x] integerEq# - need cf for bigNatEq#
* [x] integerNe# - need cf for bigNatNe#
* [x] integerGt#/Le/Lt/Ge - just inline (relies on integerCompare)
* [x] integerCompare - merge integerCompare/Compare', just inline, need cf for bigNatCompare
* [ ] integerSub - quite big, maybe split fast/slow path. need cf for bigNatSubWordUnsafe#, bigNatSubUnsafe, bigNatAdd, subIntC#, bigNatCompare, bigNatAddWord#...
* [ ] integerAdd - ditto
* [ ] integerMul - remove CPP (we always build with stage1 which is >= 8.11). maybe split. need cf for bigNatMul, bigNatMulWord#, timesInt2#...
* [ ] integerNegate - need cf for bigNatFromWord#, bigNatEqWord#
* [ ] integerAbs - just inline
* [x] integerSignum[#] - just inline
* [ ] integerPopCount# - need cf for popCntI#, bigNatPopCount#
* [ ] integerBit# - need cf for bigNatBit#
* [ ] integerTestBit# - put negative case in a noinline helper. need cf for bigNatTestBit#
* [ ] integerShiftR# - need cf for bigNatShiftR#, bigNatShiftRNeg#
* [ ] integerShiftL# - need cf for bigNatShiftL#, relies on integerBit#
* [ ] integerOr - add helper integerOrInt#, split negative case?. need cf for bigNatOrWord#, bigNatAndNot, bigNatAddWord#, bigNatSub...
* [ ] integerXor, integerAnd - ditto
* [ ] integerComplement - need cf for bigNatAddWord#, bigNatSubWordUnsafe#
* [ ] integerQuotRem# - need cf for bigNatQuotRemWord#, bigNatQuotRem#. Quite big...
* [ ] integerQuot, integerRem - similar to integerQuotRem#
* [ ] integerDivMod# - just inline, relies on integerSignum#, integerSub, integerAdd, integerQuotRem#
* [ ] integerDiv - just inline, relies in integerQuot, integerDivMod#
* [ ] integerMod - ditto, relies on integerRem
* [ ] integerGcd - add integerGcdInt# helper to remove recursive call. need cf for bigNatGcd, bigNatGcdWord#, gcdWord#. Relies on integerAbs
* [ ] integerLcm - inline, relies on integerAbs, integerQuot, integerGcd, integerMul
* [ ] integerFromInt64#, integerFromWord64# - need cf for bigNatFromWord64#
* [ ] integerToInt64#, integerToWord64# - need cf for bigNatToWord64#
* [ ] integerEncodeDouble#, integerEncodeFloat# - why is that even here? put this in base with bigNatEncodeDouble# and intEncodeDouble#.
issue