Newest at the top
2025-06-23 18:40:22 +0200 | cawfee | (root@2001:19f0:4400:79a1::babe) (Ping timeout: 252 seconds) |
2025-06-23 18:39:55 +0200 | <[exa]> | yeah I know, was just curious :D |
2025-06-23 18:39:33 +0200 | <haskellbridge> | <magic_rb> [exa] yeah the optimization was completely my fault, i took as a "hey it should be a noop" challenge |
2025-06-23 18:38:54 +0200 | <tomsmeding> | using Int and not Word64 because GHC has nice unboxed literal syntax for Int# but not for Word64# |
2025-06-23 18:38:36 +0200 | <tomsmeding> | magic_rb: https://play.haskell.org/saved/ygIqjecU |
2025-06-23 18:38:36 +0200 | <mreh> | it's not intuitive, at least to me, but I guess the value wraps and it gets the right answer |
2025-06-23 18:37:37 +0200 | <tomsmeding> | [exa]: they didn't, I think, mreh just wanted the thing that fromIntegral does but somehow expected fromIntegral to do something different |
2025-06-23 18:36:52 +0200 | <[exa]> | I wish to know how'd someone manage to turn i8 to u8 conversion into a cost centre |
2025-06-23 18:36:42 +0200 | mreh | reads up, ah looks like it |
2025-06-23 18:36:03 +0200 | <mreh> | what does GHC do? rebox then unbox it again? |
2025-06-23 18:35:44 +0200 | <haskellbridge> | <magic_rb> Other wise its a noop |
2025-06-23 18:35:39 +0200 | <haskellbridge> | <magic_rb> Only in this case :P |
2025-06-23 18:35:33 +0200 | <EvanR> | lol |
2025-06-23 18:35:30 +0200 | <EvanR> | a no-op that is slow |
2025-06-23 18:35:25 +0200 | <haskellbridge> | <magic_rb> tomsmeding getting syntax errors from your assembler, good one XD |
2025-06-23 18:35:05 +0200 | <haskellbridge> | <magic_rb> Yeah unsafeCoerce breaks the unboxed arithmetic optimization sadly |
2025-06-23 18:34:46 +0200 | <tomsmeding> | yes |
2025-06-23 18:34:44 +0200 | <tomsmeding> | but GHC aggressively unboxes arithmetic, as it should |
2025-06-23 18:34:43 +0200 | ames | (~amelia@offtopia/offtopian/amelia) {ames} |
2025-06-23 18:34:40 +0200 | <EvanR> | e.g. Int8 and Word8 |
2025-06-23 18:34:27 +0200 | <tomsmeding> | EvanR: it's a no-op on boxed values |
2025-06-23 18:34:20 +0200 | <EvanR> | hold on unsafeCoerce isn't a no-op? |
2025-06-23 18:34:20 +0200 | ames | (~amelia@offtopia/offtopian/amelia) (Quit: Bye!) |
2025-06-23 18:34:18 +0200 | prdak | (~Thunderbi@user/prdak) (Ping timeout: 252 seconds) |
2025-06-23 18:34:11 +0200 | peterbecich | (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 252 seconds) |
2025-06-23 18:33:55 +0200 | <tomsmeding> | been there, done that |
2025-06-23 18:33:53 +0200 | <tomsmeding> | but unsafeCoerce# is really unsafe: if you unsafeCoerce# a Double# to a Word64#, which one would think should just work on a machine with 64-bit doubles, GHC will generate Word64# instructions on a floating-point register and you'll get syntax errors from your assembler |
2025-06-23 18:33:35 +0200 | yangby | (~secret@60.176.176.179) (Quit: Go out for a walk and buy a drink.) |
2025-06-23 18:33:27 +0200 | <haskellbridge> | <magic_rb> To use unsafeCoerce# youd have to write unbox code which is a pain in the arse |
2025-06-23 18:33:09 +0200 | <haskellbridge> | <magic_rb> Right so unsafeCoerce breaks the unboxed arithmetic magic, interesting |
2025-06-23 18:32:52 +0200 | <tomsmeding> | now in this case you could probably use unsafeCoerce# on the unboxed values inside, and it would work on processors that put 8-bit signed and unsigned integers in the same registers (which is all of them) |
2025-06-23 18:32:22 +0200 | <tomsmeding> | because GHC receives from unsafeCoerce an equality of Int8 and Word8, not of Int8# and Word8# |
2025-06-23 18:32:07 +0200 | <tomsmeding> | writing 2 * unsafeCoerce (x + 1) requires GHC to box the Word8# result of 'x +# 1#' to a Word8 again, dereference the pointer again but now as an Int8, and do the 2* on the Int8# |
2025-06-23 18:31:29 +0200 | <tomsmeding> | https://play.haskell.org/saved/jR3HVPQ5 |
2025-06-23 18:31:25 +0200 | <tomsmeding> | magic_rb: unsafeCoerce is actually _slower_ in this case because unsafeCoerce works on lifted values |
2025-06-23 18:31:21 +0200 | <mreh> | I wasn't expecting the answer to be fromIntegral, but there you go |
2025-06-23 18:31:15 +0200 | Discordian93 | (~Discordia@user/Discordian93) (Quit: Leaving.) |
2025-06-23 18:29:51 +0200 | prdak | (~Thunderbi@user/prdak) prdak |
2025-06-23 18:29:47 +0200 | <tomsmeding> | even better would have been static restrictions like https://hackage.haskell.org/package/int-cast does |
2025-06-23 18:29:16 +0200 | <tomsmeding> | mreh: an alternative implementation of fromIntegral would have been: throw a runtime error if the value is not as-is representable in the target type |
2025-06-23 18:29:11 +0200 | <EvanR> | because unsafeCoerce doesn't |
2025-06-23 18:29:07 +0200 | <EvanR> | that the answer to this question ended up amounting to doing a conversion is great |
2025-06-23 18:28:42 +0200 | <tomsmeding> | plenty of administration around it but that looks unrelated to the integer conversion |
2025-06-23 18:28:22 +0200 | <tomsmeding> | when you click Asm, you see that it becomes two adjacent assembly instructions, addb and shlb |
2025-06-23 18:28:05 +0200 | <tomsmeding> | in Core you can see that fromIntegral becomes GHC.Prim.word8ToInt8# |
2025-06-23 18:27:53 +0200 | <tomsmeding> | the 2* and +1 added to see where the actual user code is |
2025-06-23 18:27:38 +0200 | <tomsmeding> | magic_rb: https://play.haskell.org/saved/5AlmTIJY |
2025-06-23 18:27:29 +0200 | <EvanR> | a baseline expectation for this operation would be, if the value is representable by both Word8 and Int8 then the conversion leaves the value unchanged |
2025-06-23 18:27:07 +0200 | <mreh> | it's only a gameboy interpreter, no need to blazingly fast optimizations |
2025-06-23 18:25:54 +0200 | <mreh> | tomsmeding: good point |