Skip to content

Commit a85df82

Browse files
author
Alex McKenna
authored
Use Int instead of Int# in toEnum / fromEnum prims (#2127)
* Add test for #2126 * Use Int instead of Int# in toEnum / fromEnum prims In the primitives for conversion to / from Enum introduced in 0613f21, the definitions are converting to / from Int# instead of Int as the type of the functions demands. This is not correct, and means that conversion to the enum type will never fire (as the argument is always a boxed int instead of an unboxed int), and the conversion from the enum type to Int will result in an ill-typed expression being output which can lead to case 1# of I# x -> ... which are obviously bogus.
1 parent 50c4b9f commit a85df82

File tree

5 files changed

+61
-15
lines changed

5 files changed

+61
-15
lines changed

clash-ghc/src-ghc/Clash/GHC/Evaluator/Primitive.hs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1925,7 +1925,7 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
19251925

19261926
-- Enum
19271927
"Clash.Sized.Internal.BitVector.toEnum##"
1928-
| [i] <- intLiterals' args
1928+
| [i] <- intCLiterals' args
19291929
-> let Bit msk val = BitVector.toEnum## (fromInteger i)
19301930
in reduce (mkBitLit ty (toInteger msk) (toInteger val))
19311931

@@ -2140,7 +2140,8 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
21402140

21412141
"Clash.Sized.Internal.BitVector.fromEnum#"
21422142
| Just (_, kn) <- extractKnownNat tcm tys
2143-
, Just val <- reifyNat kn (liftBitVector2Int (toInteger . BitVector.fromEnum#) args)
2143+
, let resTy = getResultTy tcm ty tys
2144+
, Just val <- reifyNat kn (liftBitVector2CInt tcm resTy (toInteger . BitVector.fromEnum#) args)
21442145
-> reduce val
21452146

21462147
-- Bounded
@@ -2317,13 +2318,14 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
23172318

23182319
-- Enum
23192320
"Clash.Sized.Internal.Index.toEnum#"
2320-
| [i] <- intLiterals' args
2321+
| [i] <- intCLiterals' args
23212322
, Just (nTy, mb) <- extractKnownNat tcm tys
23222323
-> reduce (mkIndexLit ty nTy mb i)
23232324

23242325
"Clash.Sized.Internal.Index.fromEnum#"
23252326
| [i] <- indexLiterals' args
2326-
-> reduce (integerToIntLiteral i)
2327+
-> let resTy = getResultTy tcm ty tys
2328+
in reduce (mkIntCLit tcm i resTy)
23272329

23282330
-- Bounded
23292331
"Clash.Sized.Internal.Index.maxBound#"
@@ -2433,13 +2435,14 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
24332435

24342436
-- Enum
24352437
"Clash.Sized.Internal.Signed.toEnum#"
2436-
| [i] <- intLiterals' args
2438+
| [i] <- intCLiterals' args
24372439
, Just (litTy, mb) <- extractKnownNat tcm tys
24382440
-> reduce (mkSignedLit ty litTy mb i)
24392441

24402442
"Clash.Sized.Internal.Signed.fromEnum#"
24412443
| [i] <- signedLiterals' args
2442-
-> reduce (integerToIntLiteral i)
2444+
-> let resTy = getResultTy tcm ty tys
2445+
in reduce (mkIntCLit tcm i resTy)
24432446

24442447
-- Bounded
24452448
"Clash.Sized.Internal.Signed.minBound#"
@@ -2650,13 +2653,14 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
26502653

26512654
-- Enum
26522655
"Clash.Sized.Internal.Unsigned.toEnum#"
2653-
| [i] <- intLiterals' args
2656+
| [i] <- intCLiterals' args
26542657
, Just (litTy, mb) <- extractKnownNat tcm tys
26552658
-> reduce (mkUnsignedLit ty litTy mb i)
26562659

26572660
"Clash.Sized.Internal.Unsigned.fromEnum#"
26582661
| [i] <- unsignedLiterals' args
2659-
-> reduce (integerToIntLiteral i)
2662+
-> let resTy = getResultTy tcm ty tys
2663+
in reduce (mkIntCLit tcm i resTy)
26602664

26612665
-- Bounded
26622666
"Clash.Sized.Internal.Unsigned.minBound#"
@@ -4047,6 +4051,9 @@ intLiterals = pairOf intLiteral
40474051
intLiterals' :: [Value] -> [Integer]
40484052
intLiterals' = listOf intLiteral
40494053

4054+
intCLiterals' :: [Value] -> [Integer]
4055+
intCLiterals' = listOf intCLiteral
4056+
40504057
intLiteral :: Value -> Maybe Integer
40514058
intLiteral x = case x of
40524059
Lit (IntLiteral i) -> Just i
@@ -4182,6 +4189,14 @@ bitVectorLitIntLit tcm tys args
41824189
| otherwise
41834190
= Nothing
41844191

4192+
mkIntCLit :: TyConMap -> Integer -> Type -> Term
4193+
mkIntCLit tcm lit resTy =
4194+
App (Data intDc) (Literal (IntLiteral lit))
4195+
where
4196+
(_, tyView -> TyConApp intTcNm []) = splitFunForallTy resTy
4197+
Just intTc = lookupUniqMap intTcNm tcm
4198+
[intDc] = tyConDataCons intTc
4199+
41854200
mkFloatCLit :: TyConMap -> Word32 -> Type -> Term
41864201
mkFloatCLit tcm lit resTy =
41874202
App (Data floatDc) (Literal (FloatLiteral lit))
@@ -4468,22 +4483,24 @@ liftInteger2BitVector
44684483
-> [Value]
44694484
-> (Proxy n -> Maybe Term)
44704485
liftInteger2BitVector f resTyInfo args _p
4471-
| [i] <- intLiterals' args
4486+
| [i] <- intCLiterals' args
44724487
= let BV msk val = f i
44734488
in Just (mkBitVectorLit' resTyInfo (toInteger msk) (toInteger val))
44744489

44754490
| otherwise
44764491
= Nothing
44774492

4478-
liftBitVector2Int
4493+
liftBitVector2CInt
44794494
:: KnownNat n
4480-
=> (BitVector n -> Integer)
4495+
=> TyConMap
4496+
-> Type
4497+
-> (BitVector n -> Integer)
44814498
-> [Value]
44824499
-> (Proxy n -> Maybe Term)
4483-
liftBitVector2Int f args _p
4500+
liftBitVector2CInt tcm resTy f args _p
44844501
| [i] <- bitVectorLiterals' args
44854502
= let val = f (toBV i)
4486-
in Just $ integerToIntLiteral val
4503+
in Just $ mkIntCLit tcm val resTy
44874504
| otherwise
44884505
= Nothing
44894506

tests/Main.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ runClashTest = defaultMain $ clashTestRoot
567567
, buildTargets=BuildSpecific["top_bit", "top_bitvector", "top_index", "top_signed", "top_unsigned"]
568568
}
569569
, runTest "T2046B" def{clashFlags=["-Werror"]}
570+
, runTest "T2046C" def{hdlSim=False,clashFlags=["-Werror"],buildTargets=BuildSpecific["topEntity"]}
570571
, runTest "T2097" def{hdlSim=False}
571572
] <>
572573
if compiledWith == Cabal then

tests/shouldwork/Issues/T2046B.hs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
{-# LANGUAGE ViewPatterns #-}
2-
31
module T2046B where
42

53
import Clash.Prelude

tests/shouldwork/Issues/T2046BType.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,12 @@ type T2046B =
99
, (BitVector 1, BitVector 2)
1010
, Bit
1111
)
12+
13+
type T2046C =
14+
( (Int, Int)
15+
, (Int, Int)
16+
, (Int, Int)
17+
, (Int, Int)
18+
, Int
19+
)
20+

tests/shouldwork/Issues/T2046C.hs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module T2046C where
2+
3+
import Clash.Prelude
4+
import T2046BType
5+
6+
inBit :: (Enum a) => a -> Bool
7+
inBit x = case fromEnum x of
8+
0 -> True
9+
1 -> True
10+
_ -> False
11+
12+
topEntity :: Bool
13+
topEntity =
14+
let ((a,b),(c,d),(e,f),(g,h),i) = ((0,1),(0,1),(0,1),(0,1),0) :: T2046B
15+
in and [ inBit a, inBit b
16+
, inBit c, inBit d
17+
, inBit e, inBit f
18+
, inBit g, inBit h
19+
, inBit i
20+
]
21+

0 commit comments

Comments
 (0)