Hey guys!
So, I was working on some cross-compiling, and found a bug
(http://hackage.haskell.org/trac/ghc/ticket/7620)

Eventually I found that the issue was with C CodeGen in general, and had
nothing to do with ARM.

I've attached the patch there, but it may be only part of a bigger
problem.

The rough problem came from two things:
1) -(-128 :: Int8) => -128
        You can't negate the smallest int in an integer space because of how
        2s compliment works. There aren't enough bits to store +128.

2) We have a number of operations that transform:
        | i < 0 = a + i => a - (negative i)
        And
        | i < 0 = a - i => a + (negative i)

And the assumption is that any integer can be negated, but that's not
true in exactly one case.

So, for example, it could turn
        thing+-128
into
        thing--128
Which is not valid C.
That (but for Int32) was what I was seeing, and causing me trouble
building integer simple.

So, that was the bug I had encountered, and I don't know how the GHC
code works, I just trawled through until I found the line that was
causing me trouble, but I just figured I'd remind people that not every
integer can be negated, in case the same mistake is being done in other
places.

From 8559aa7826bfe99e53d85c4c6e86c6c56c94bddd Mon Sep 17 00:00:00 2001
From: Christopher Vollick <[email protected]>
Date: Sat, 26 Jan 2013 16:58:23 -0500
Subject: [PATCH] De-Optimized RegOff

It used to take a positive offset and spit it out as
	blah+offset
And a negative offset and spit it out as
	blah-negated_offset

Here's the problem, though.
-(-128 :: Int8) is -128, becase of the way 2s compliment works.

So, when integer-simple was doing with with the lowest int, it was
ending up generating
	blah--offset
Which is not valid C.

So, since I don't think that was saving us anything anyway, since every
C compiler ever is able to do that for us, and
	blah+-offset
is not ambiguous, I'm good with it as is.

I wouldn't be surprised if there aren't other such errors in the system,
where it's assumed that a number can always be negated, when it can't,
but those aren't blocking me right now.
---
 compiler/cmm/PprC.hs |    6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/compiler/cmm/PprC.hs b/compiler/cmm/PprC.hs
index bcfb5dc..b845aec 100644
--- a/compiler/cmm/PprC.hs
+++ b/compiler/cmm/PprC.hs
@@ -357,11 +357,7 @@ pprExpr e = case e of
     CmmReg reg      -> pprCastReg reg
     CmmRegOff reg 0 -> pprCastReg reg
 
-    CmmRegOff reg i
-        | i >  0    -> pprRegOff (char '+') i
-        | otherwise -> pprRegOff (char '-') (-i)
-      where
-        pprRegOff op i' = pprCastReg reg <> op <> int i'
+    CmmRegOff reg i -> pprCastReg reg <> (char '+') <> int i
 
     CmmMachOp mop args -> pprMachOpApp mop args
 
-- 
1.7.10.4

Attachment: signature.asc
Description: Digital signature

_______________________________________________
ghc-devs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/ghc-devs

Reply via email to