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 |
- |