diff options
author | Cheng Shao <terrorjack@type.dance> | 2023-01-31 17:07:17 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2023-01-31 20:47:03 -0500 |
commit | f0eefa3cf058879246991747dcd18c811402f9e5 (patch) | |
tree | ec85c5fc686c158b329bb9db53ffb367a4046a66 /compiler/GHC/Wasm/ControlFlow/FromCmm.hs | |
parent | 22089f693cf6e662a58a7011adb94d7f768ad2d7 (diff) | |
download | haskell-wip/T21776.tar.gz |
compiler: properly handle non-word-sized CmmSwitch scrutinees in the wasm NCGwip/T21776
Currently, the wasm NCG has an implicit assumption: all CmmSwitch
scrutinees are 32-bit integers. This is not always true; #22864 is one
counter-example with a 64-bit scrutinee. This patch fixes the logic by
explicitly converting the scrutinee to a word that can be used as a
br_table operand. Fixes #22871. Also includes a regression test.
Diffstat (limited to 'compiler/GHC/Wasm/ControlFlow/FromCmm.hs')
-rw-r--r-- | compiler/GHC/Wasm/ControlFlow/FromCmm.hs | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/compiler/GHC/Wasm/ControlFlow/FromCmm.hs b/compiler/GHC/Wasm/ControlFlow/FromCmm.hs index 0667345162..85eb8e534b 100644 --- a/compiler/GHC/Wasm/ControlFlow/FromCmm.hs +++ b/compiler/GHC/Wasm/ControlFlow/FromCmm.hs @@ -75,7 +75,7 @@ flowLeaving platform b = let (offset, target_labels) = switchTargetsToTable targets (lo, hi) = switchTargetsRange targets default_label = switchTargetsDefault targets - scrutinee = smartPlus platform e offset + scrutinee = smartExtend platform $ smartPlus platform e offset range = inclusiveInterval (lo+toInteger offset) (hi+toInteger offset) in Switch scrutinee range target_labels default_label CmmCall { cml_cont = Nothing, cml_target = e } -> TailCall e @@ -314,6 +314,14 @@ structuredControl platform txExpr txBlock g = nodeBody :: CmmBlock -> CmmActions nodeBody (BlockCC _first middle _last) = middle +-- | A CmmSwitch scrutinee may have any width, but a br_table operand +-- must be exactly word sized, hence the extension here. (#22871) +smartExtend :: Platform -> CmmExpr -> CmmExpr +smartExtend p e | w0 == w1 = e + | otherwise = CmmMachOp (MO_UU_Conv w0 w1) [e] + where + w0 = cmmExprWidth p e + w1 = wordWidth p smartPlus :: Platform -> CmmExpr -> Int -> CmmExpr smartPlus _ e 0 = e |