[Git][ghc/ghc][wip/ncg-simd] SIMD cleanups

sheaf (@sheaf) gitlab at gitlab.haskell.org
Tue Jun 25 15:48:17 UTC 2024



sheaf pushed to branch wip/ncg-simd at Glasgow Haskell Compiler / GHC


Commits:
e1b8066a by sheaf at 2024-06-25T17:47:43+02:00
SIMD cleanups

- - - - -


4 changed files:

- compiler/GHC/Cmm/Opt.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToC.hs


Changes:

=====================================
compiler/GHC/Cmm/Opt.hs
=====================================
@@ -80,10 +80,10 @@ cmmMachOpFoldM
     -> [CmmExpr]
     -> Maybe CmmExpr
 cmmMachOpFoldM _ (MO_V_Broadcast {}) _ = Nothing
-  -- SIMD NCG TODO: constant folding doesn't work correctly for Broadcast instructions,
-  -- perhaps due to the fact that the argument is a scalar but the result is a vector.
 cmmMachOpFoldM _ (MO_VF_Broadcast {}) _ = Nothing
-
+  -- SIMD NCG TODO: supporting constant folding for vector operations
+  -- would require augmenting getRegister' to handle them.
+  -- See the code for "getRegister' platform _ (CmmLit lit)".
 cmmMachOpFoldM _ op [CmmLit (CmmInt x rep)]
   = Just $! case op of
       MO_S_Neg _ -> CmmLit (CmmInt (-x) rep)


=====================================
compiler/GHC/CmmToAsm/X86/CodeGen.hs
=====================================
@@ -1104,7 +1104,7 @@ getRegister' platform is32Bit (CmmMachOp mop [x]) = do -- unary MachOps
                      | sse && sse2   -> vector_float_negate_sse l w x
                      | otherwise
                        -> sorry "Please enable the -mavx or -msse, -msse2 flag"
-      -- SIMD NCG TODO
+      -- SIMD NCG TODO: add integer negation
       MO_VS_Neg {} -> needLlvm mop
 
       MO_VF_Broadcast l W32 | avx       -> vector_float_broadcast_avx l W32 x
@@ -1384,15 +1384,15 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps
         | otherwise
         -> sorry "Please use -fllvm for wide shuffle instructions"
 
-      MO_VF_Extract l W32   | avx       -> vector_float_unpack l W32 x y
-                            | sse       -> vector_float_unpack_sse l W32 x y
+      MO_VF_Extract l W32   | avx       -> vector_float_extract l W32 x y
+                            | sse       -> vector_float_extract_sse l W32 x y
                             | otherwise
                               -> sorry "Please enable the -mavx or -msse flag"
-      MO_VF_Extract l W64   | sse2      -> vector_float_unpack l W64 x y
+      MO_VF_Extract l W64   | sse2      -> vector_float_extract l W64 x y
                             | otherwise -> sorry "Please enable the -msse2 flag"
       MO_VF_Extract {} -> incorrectOperands
 
-      MO_V_Extract l W64    | sse2      -> vector_int_unpack_sse l W64 x y
+      MO_V_Extract l W64    | sse2      -> vector_int_extract_sse l W64 x y
                             | otherwise -> sorry "Please enable the -msse2 flag"
       -- SIMD NCG TODO: W32, W16, W8
       MO_V_Extract {} -> needLlvm mop
@@ -1653,7 +1653,8 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps
       let format   = case w of
                        W32 -> VecFormat l FmtFloat
                        W64 -> VecFormat l FmtDouble
-                       _ -> pprPanic "Operation not supported for width " (ppr w)
+                       _ -> pprPanic "Floating-point AVX vector operation not supported at this width"
+                             (text "width:" <+> ppr w)
           code dst = case op of
             VA_Add -> arithInstr VADD
             VA_Sub -> arithInstr VSUB
@@ -1677,7 +1678,8 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps
       let format   = case w of
                        W32 -> VecFormat l FmtFloat
                        W64 -> VecFormat l FmtDouble
-                       _ -> pprPanic "Operation not supported for width " (ppr w)
+                       _ -> pprPanic "Floating-point SSE vector operation not supported at this width"
+                             (text "width:" <+> ppr w)
           code dst = case op of
             VA_Add -> arithInstr ADD
             VA_Sub -> arithInstr SUB
@@ -1691,12 +1693,12 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps
                   (instr format (OpReg reg2) (OpReg dst))
       return (Any format code)
     --------------------
-    vector_float_unpack :: Length
-                        -> Width
-                        -> CmmExpr
-                        -> CmmExpr
-                        -> NatM Register
-    vector_float_unpack l W32 expr (CmmLit lit)
+    vector_float_extract :: Length
+                         -> Width
+                         -> CmmExpr
+                         -> CmmExpr
+                         -> NatM Register
+    vector_float_extract l W32 expr (CmmLit lit)
       = do
       (r, exp) <- getSomeReg expr
       let format   = VecFormat l FmtFloat
@@ -1705,9 +1707,9 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps
             = case lit of
                 CmmInt 0 _ -> exp `snocOL` (MOV FF32 (OpReg r) (OpReg dst))
                 CmmInt _ _ -> exp `snocOL` (VPSHUFD format imm (OpReg r) dst)
-                _          -> panic "Error in offset while unpacking"
+                _          -> pprPanic "Unsupported AVX floating-point vector extract offset" (ppr lit)
       return (Any format code)
-    vector_float_unpack l W64 expr (CmmLit lit)
+    vector_float_extract l W64 expr (CmmLit lit)
       = do
       (r, exp) <- getSomeReg expr
       let format   = VecFormat l FmtDouble
@@ -1717,18 +1719,18 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps
                               (MOV FF64 (OpReg r) (OpReg dst))
                 CmmInt 1 _ -> exp `snocOL`
                               (MOVHLPS format r dst)
-                _          -> panic "Error in offset while unpacking"
+                _          -> pprPanic "Unsupported AVX floating-point vector extract offset" (ppr lit)
       return (Any format code)
-    vector_float_unpack _ w c e
-      = pprPanic "Unpack not supported for : " (pdoc platform c $$ pdoc platform e $$ ppr w)
+    vector_float_extract _ w c e
+      = pprPanic "Unsupported AVX floating-point vector extract" (pdoc platform c $$ pdoc platform e $$ ppr w)
     -----------------------
 
-    vector_float_unpack_sse :: Length
-                            -> Width
-                            -> CmmExpr
-                            -> CmmExpr
-                            -> NatM Register
-    vector_float_unpack_sse l W32 expr (CmmLit lit)
+    vector_float_extract_sse :: Length
+                             -> Width
+                             -> CmmExpr
+                             -> CmmExpr
+                             -> NatM Register
+    vector_float_extract_sse l W32 expr (CmmLit lit)
       = do
       (r,exp) <- getSomeReg expr
       let format   = VecFormat l FmtFloat
@@ -1737,18 +1739,18 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps
             = case lit of
                 CmmInt 0 _ -> exp `snocOL` (MOVU format (OpReg r) (OpReg dst))
                 CmmInt _ _ -> exp `snocOL` (PSHUFD format imm (OpReg r) dst)
-                _          -> panic "Error in offset while unpacking"
+                _          -> pprPanic "Unsupported SSE floating-point vector extract offset" (ppr lit)
       return (Any format code)
-    vector_float_unpack_sse _ w c e
-      = pprPanic "Unpack not supported for : " (pdoc platform c $$ pdoc platform e $$ ppr w)
+    vector_float_extract_sse _ w c e
+      = pprPanic "Unsupported SSE floating-point vector extract" (pdoc platform c $$ pdoc platform e $$ ppr w)
     -----------------------
 
-    vector_int_unpack_sse :: Length
-                          -> Width
-                          -> CmmExpr
-                          -> CmmExpr
-                          -> NatM Register
-    vector_int_unpack_sse l at 2 W64 expr (CmmLit lit)
+    vector_int_extract_sse :: Length
+                           -> Width
+                           -> CmmExpr
+                           -> CmmExpr
+                           -> NatM Register
+    vector_int_extract_sse l at 2 W64 expr (CmmLit lit)
       = do
       (r, exp) <- getSomeReg expr
       let fmt = VecFormat l FmtInt64
@@ -1762,8 +1764,8 @@ getRegister' platform is32Bit (CmmMachOp mop [x, y]) = do -- dyadic MachOps
                               (MOVD II64 (OpReg tmp) (OpReg dst))
                 _          -> panic "Error in offset while unpacking"
       return (Any fmt code)
-    vector_int_unpack_sse _ w c e
-      = pprPanic "Unpack not supported for : " (pdoc platform c $$ pdoc platform e $$ ppr w)
+    vector_int_extract_sse _ w c e
+      = pprPanic "Unsupported SSE floating-point vector extract" (pdoc platform c $$ pdoc platform e $$ ppr w)
 
     vector_shuffle_float :: Length -> Width -> CmmExpr -> CmmExpr -> [Int] -> NatM Register
     vector_shuffle_float l w v1 v2 is = do


=====================================
compiler/GHC/CmmToAsm/X86/Instr.hs
=====================================
@@ -202,9 +202,13 @@ data Instr
         -- This carries a BlockId so it can be used in unwinding information.
         | DELTA  Int
 
-        -- Moves.
+        -- | X86 scalar move instruction.
+        --
+        -- When used at a vector format, only moves the lower 64 bits of data;
+        -- the rest of the data in the destination may either be zeroed or
+        -- preserved, depending on the specific format.
         | MOV Format Operand Operand
-             -- ^ N.B. Due to AT&T assembler quirks, when used with 'II64'
+             -- N.B. Due to AT&T assembler quirks, when used with 'II64'
              -- 'Format' immediate source and memory target operand, the source
              -- operand is interpreted to be a 32-bit sign-extended value.
              -- True 64-bit operands need to be either first moved to a register or moved


=====================================
compiler/GHC/CmmToC.hs
=====================================
@@ -820,9 +820,6 @@ pprMachOp_for_C platform mop = case mop of
         MO_SF_Round    _from to -> parens (machRep_F_CType to)
         MO_FS_Truncate _from to -> parens (machRep_S_CType platform to)
 
-        MO_V_Shuffle {} -> text "__builtin_shufflevector"
-        MO_VF_Shuffle {} -> text "__builtin_shufflevector"
-
         MO_RelaxedRead _ -> pprTrace "offending mop:"
                                 (text "MO_RelaxedRead")
                                 (panic $ "PprC.pprMachOp_for_C: MO_S_MulMayOflo"
@@ -833,88 +830,93 @@ pprMachOp_for_C platform mop = case mop of
                                 (panic $ "PprC.pprMachOp_for_C: MO_S_MulMayOflo"
                                       ++ " should have been handled earlier!")
 
+        MO_AlignmentCheck {} -> panic "-falignment-sanitisation not supported by unregisterised backend"
+
+-- SIMD vector instructions: currently unsupported
+        MO_V_Shuffle {} -> pprTrace "offending mop:"
+                                (text "MO_V_Shuffle")
+                                (panic $ "PprC.pprMachOp_for_C: MO_V_Shuffle"
+                                      ++ "unsupported by the unregisterised backend")
+        MO_VF_Shuffle {} -> pprTrace "offending mop:"
+                                (text "MO_VF_Shuffle")
+                                (panic $ "PprC.pprMachOp_for_C: MO_VF_Shuffle"
+                                      ++ "unsupported by the unregisterised backend")
         MO_V_Insert {}    -> pprTrace "offending mop:"
                                 (text "MO_V_Insert")
                                 (panic $ "PprC.pprMachOp_for_C: MO_V_Insert"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_V_Extract {}   -> pprTrace "offending mop:"
                                 (text "MO_V_Extract")
                                 (panic $ "PprC.pprMachOp_for_C: MO_V_Extract"
-                                      ++ " should have been handled earlier!")
-
+                                      ++ "unsupported by the unregisterised backend")
         MO_V_Add {}       -> pprTrace "offending mop:"
                                 (text "MO_V_Add")
                                 (panic $ "PprC.pprMachOp_for_C: MO_V_Add"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_V_Sub {}       -> pprTrace "offending mop:"
                                 (text "MO_V_Sub")
                                 (panic $ "PprC.pprMachOp_for_C: MO_V_Sub"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_V_Mul {}       -> pprTrace "offending mop:"
                                 (text "MO_V_Mul")
                                 (panic $ "PprC.pprMachOp_for_C: MO_V_Mul"
-                                      ++ " should have been handled earlier!")
-
+                                      ++ "unsupported by the unregisterised backend")
         MO_VS_Quot {}     -> pprTrace "offending mop:"
                                 (text "MO_VS_Quot")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VS_Quot"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_VS_Rem {}      -> pprTrace "offending mop:"
                                 (text "MO_VS_Rem")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VS_Rem"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_VS_Neg {}      -> pprTrace "offending mop:"
                                 (text "MO_VS_Neg")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VS_Neg"
-                                      ++ " should have been handled earlier!")
-
+                                      ++ "unsupported by the unregisterised backend")
         MO_VU_Quot {}     -> pprTrace "offending mop:"
                                 (text "MO_VU_Quot")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VU_Quot"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_VU_Rem {}      -> pprTrace "offending mop:"
                                 (text "MO_VU_Rem")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VU_Rem"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_V_Broadcast {} -> pprTrace "offending mop:"
                                  (text "MO_V_Broadcast")
                                  (panic $ "PprC.pprMachOp_for_C: MO_V_Broadcast"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_VF_Broadcast {} -> pprTrace "offending mop:"
                                  (text "MO_VF_Broadcast")
                                  (panic $ "PprC.pprMachOp_for_C: MO_VF_Broadcast"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_VF_Insert {}   -> pprTrace "offending mop:"
                                 (text "MO_VF_Insert")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VF_Insert"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_VF_Extract {}  -> pprTrace "offending mop:"
                                 (text "MO_VF_Extract")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VF_Extract"
-                                      ++ " should have been handled earlier!")
-
+                                      ++ "unsupported by the unregisterised backend")
         MO_VF_Add {}      -> pprTrace "offending mop:"
                                 (text "MO_VF_Add")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VF_Add"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_VF_Sub {}      -> pprTrace "offending mop:"
                                 (text "MO_VF_Sub")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VF_Sub"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_VF_Neg {}      -> pprTrace "offending mop:"
                                 (text "MO_VF_Neg")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VF_Neg"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_VF_Mul {}      -> pprTrace "offending mop:"
                                 (text "MO_VF_Mul")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VF_Mul"
-                                      ++ " should have been handled earlier!")
+                                      ++ "unsupported by the unregisterised backend")
         MO_VF_Quot {}     -> pprTrace "offending mop:"
                                 (text "MO_VF_Quot")
                                 (panic $ "PprC.pprMachOp_for_C: MO_VF_Quot"
-                                      ++ " should have been handled earlier!")
-
-        MO_AlignmentCheck {} -> panic "-falignment-sanitisation not supported by unregisterised backend"
+                                      ++ "unsupported by the unregisterised backend")
 
 signedOp :: MachOp -> Bool      -- Argument type(s) are signed ints
 signedOp (MO_S_Quot _)    = True



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e1b8066a1b6852ff04261a539ce73aa450a3b6a8

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e1b8066a1b6852ff04261a539ce73aa450a3b6a8
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20240625/e997e112/attachment-0001.html>


More information about the ghc-commits mailing list