Gentoo Archives: gentoo-commits

From: "Sergei Trofimovich (slyfox)" <slyfox@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] gentoo-x86 commit in dev-lang/ghc/files: ghc-7.8.3-unreg-lit.patch
Date: Sat, 23 Aug 2014 13:46:48
Message-Id: 20140823134643.1D10B3C2B@oystercatcher.gentoo.org
1 slyfox 14/08/23 13:46:43
2
3 Added: ghc-7.8.3-unreg-lit.patch
4 Log:
5 Fix integer-gmp crashes and miscomputations in UNREG builds.
6
7 (Portage version: 2.2.11_p14/cvs/Linux x86_64, signed Manifest commit with key 611FF3AA)
8
9 Revision Changes Path
10 1.1 dev-lang/ghc/files/ghc-7.8.3-unreg-lit.patch
11
12 file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-lang/ghc/files/ghc-7.8.3-unreg-lit.patch?rev=1.1&view=markup
13 plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-lang/ghc/files/ghc-7.8.3-unreg-lit.patch?rev=1.1&content-type=text/plain
14
15 Index: ghc-7.8.3-unreg-lit.patch
16 ===================================================================
17 commit a6ea05e21e175407dc9e45f18c56c1d727fd0f26
18 Author: Sergei Trofimovich <slyfox@g.o>
19 Date: Fri Aug 22 23:24:32 2014 +0300
20
21 UNREG: fix emission of large Integer literals in C codegen
22
23 Summary:
24 On amd64/UNREG build there is many failing tests trying
25 to deal with 'Integer' types.
26
27 Looking at 'overflow1' test I've observed invalid C code generated by
28 GHC.
29
30 Cmm code
31 CInt a = -1; (a == -1)
32 yields 'False' with optimisations enabled via the following C code:
33 StgWord64 a = (StgWord32)0xFFFFffffFFFFffffu; (a == 0xFFFFffffFFFFffffu)
34
35 The patch fixes it by shrinking emitted literals to required sizes:
36 StgWord64 a = (StgWord32)0xFFFFffffu; (a == 0xFFFFffffu)
37
38 Thanks to Reid Barton for tracking down and fixing the issue.
39
40 Signed-off-by: Sergei Trofimovich <slyfox@g.o>
41
42 Test Plan: validate on UNREG build (amd64)
43
44 Reviewers: simonmar, rwbarton, austin
45
46 Subscribers: simonmar, ezyang, carter
47
48 Differential Revision: https://phabricator.haskell.org/D173
49
50 diff --git a/compiler/cmm/PprC.hs b/compiler/cmm/PprC.hs
51 index 93a5d06..8605988 100644
52 --- a/compiler/cmm/PprC.hs
53 +++ b/compiler/cmm/PprC.hs
54 @@ -1221,8 +1221,9 @@ commafy xs = hsep $ punctuate comma xs
55 pprHexVal :: Integer -> Width -> SDoc
56 pprHexVal 0 _ = ptext (sLit "0x0")
57 pprHexVal w rep
58 - | w < 0 = parens (char '-' <> ptext (sLit "0x") <> go (-w) <> repsuffix rep)
59 - | otherwise = ptext (sLit "0x") <> go w <> repsuffix rep
60 + | w < 0 = parens (char '-' <>
61 + ptext (sLit "0x") <> intToDoc (-w) <> repsuffix rep)
62 + | otherwise = ptext (sLit "0x") <> intToDoc w <> repsuffix rep
63 where
64 -- type suffix for literals:
65 -- Integer literals are unsigned in Cmm/C. We explicitly cast to
66 @@ -1237,10 +1238,33 @@ pprHexVal w rep
67 else panic "pprHexVal: Can't find a 64-bit type"
68 repsuffix _ = char 'U'
69
70 + intToDoc :: Integer -> SDoc
71 + intToDoc i = go (truncInt i)
72 +
73 + -- We need to truncate value as Cmm backend does not drop
74 + -- redundant bits to ease handling of negative values.
75 + -- Thus the following Cmm code on 64-bit arch, like amd64:
76 + -- CInt v;
77 + -- v = {something};
78 + -- if (v == %lobits32(-1)) { ...
79 + -- leads to the following C code:
80 + -- StgWord64 v = (StgWord32)({something});
81 + -- if (v == 0xFFFFffffFFFFffffU) { ...
82 + -- Such code is incorrect as it promotes both operands to StgWord64
83 + -- and the whole condition is always false.
84 + truncInt :: Integer -> Integer
85 + truncInt i =
86 + case rep of
87 + W8 -> i `rem` (2^(8 :: Int))
88 + W16 -> i `rem` (2^(16 :: Int))
89 + W32 -> i `rem` (2^(32 :: Int))
90 + W64 -> i `rem` (2^(64 :: Int))
91 + _ -> panic ("pprHexVal/truncInt: C backend can't encode "
92 + ++ show rep ++ " literals")
93 +
94 go 0 = empty
95 go w' = go q <> dig
96 where
97 (q,r) = w' `quotRem` 16
98 dig | r < 10 = char (chr (fromInteger r + ord '0'))
99 | otherwise = char (chr (fromInteger r - 10 + ord 'a'))
100 -