summaryrefslogtreecommitdiff
path: root/compiler/GHC/Cmm/Parser.y
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2021-05-14 17:31:38 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-05-19 23:38:58 -0400
commitf192e623f579e09b7b5442cc707a40482b76e81e (patch)
treec3ff3e66998283eec51b72b49e96c7e8b53fc511 /compiler/GHC/Cmm/Parser.y
parentd3ef2dc2bdfec457d5e0973f3e8f3e92767c16af (diff)
downloadhaskell-f192e623f579e09b7b5442cc707a40482b76e81e.tar.gz
Cmm: fix sinking after suspendThread
Suppose a safe call: myCall(x,y,z) It is lowered into three unsafe calls in Cmm: r = suspendThread(...); myCall(x,y,z); resumeThread(r); Consider the following situation for myCall arguments: x = Sp[..] -- stack y = Hp[..] -- heap z = R1 -- global register r = suspendThread(...); myCall(x,y,z); resumeThread(r); The sink pass assumes that unsafe calls clobber memory (heap and stack), hence x and y assignments are not sunk after `suspendThread`. The sink pass also correctly handles global register clobbering for all unsafe calls, except `suspendThread`! `suspendThread` is special because it releases the capability the thread is running on. Hence the sink pass must also take into account global registers that are mapped into memory (in the capability). In the example above, we could get: r = suspendThread(...); z = R1 myCall(x,y,z); resumeThread(r); But this transformation isn't valid if R1 is (BaseReg->rR1) as BaseReg is invalid between suspendThread and resumeThread. This caused argument corruption at least with the C backend ("unregisterised") in #19237. Fix #19237
Diffstat (limited to 'compiler/GHC/Cmm/Parser.y')
-rw-r--r--compiler/GHC/Cmm/Parser.y3
1 files changed, 3 insertions, 0 deletions
diff --git a/compiler/GHC/Cmm/Parser.y b/compiler/GHC/Cmm/Parser.y
index 4576eb9b38..a83feff8cf 100644
--- a/compiler/GHC/Cmm/Parser.y
+++ b/compiler/GHC/Cmm/Parser.y
@@ -1027,6 +1027,9 @@ callishMachOps platform = listToUFM $
( "memmove", memcpyLikeTweakArgs MO_Memmove ),
( "memcmp", memcpyLikeTweakArgs MO_Memcmp ),
+ ( "suspendThread", (MO_SuspendThread,) ),
+ ( "resumeThread", (MO_ResumeThread,) ),
+
("prefetch0", (MO_Prefetch_Data 0,)),
("prefetch1", (MO_Prefetch_Data 1,)),
("prefetch2", (MO_Prefetch_Data 2,)),