Simon Jakobi pushed to branch wip/sjakobi/T25450-print-cpu at Glasgow Haskell Compiler / GHC

Commits:

14 changed files:

Changes:

  • changelog.d/print-enabled-cpu-features
    1
    +section: compiler
    
    2
    +synopsis: Add --print-enabled-cpu-features flag
    
    3
    +issues: #25450
    
    4
    +mrs: !16117
    
    5
    +
    
    6
    +description:
    
    7
    +  GHC now supports a new mode flag ``--print-enabled-cpu-features``, which
    
    8
    +  prints a JSON object describing the CPU features currently enabled for code
    
    9
    +  generation, together with a set of ``-m...`` flags that reproduce the
    
    10
    +  effective feature set for the current target.
    
    11
    +  Dynamic options such as ``-mavx2`` and ``-mbmi2`` are respected. ::
    
    12
    +
    
    13
    +    $ ghc -mavx2 --print-enabled-cpu-features
    
    14
    +    {"tag":"enabled-cpu-features","version":1,"target":"x86_64-linux-gnu",
    
    15
    +     "features":["SSE","SSE2","SSE3","SSSE3","SSE4.1","SSE4.2","AVX","AVX2"],
    
    16
    +     "as_m_flags":["-mavx2"]}

  • compiler/GHC/Driver/DynFlags.hs
    ... ... @@ -1615,6 +1615,7 @@ initPromotionTickContext dflags =
    1615 1615
     
    
    1616 1616
     -- -----------------------------------------------------------------------------
    
    1617 1617
     -- SSE, AVX, FMA
    
    1618
    +-- See Note [Keeping enabledCpuFeatures in sync] in GHC.Driver.Session
    
    1618 1619
     
    
    1619 1620
     isSse3Enabled :: DynFlags -> Bool
    
    1620 1621
     isSse3Enabled dflags = sseAvxVersion dflags >= Just SSE3 || isAvxEnabled dflags
    
    ... ... @@ -1705,11 +1706,14 @@ We handle this as follows:
    1705 1706
     
    
    1706 1707
     -- -----------------------------------------------------------------------------
    
    1707 1708
     -- LA664
    
    1709
    +-- See Note [Keeping enabledCpuFeatures in sync] in GHC.Driver.Session
    
    1710
    +
    
    1708 1711
     isLa664Enabled :: DynFlags -> Bool
    
    1709 1712
     isLa664Enabled dflags = la664 dflags
    
    1710 1713
     
    
    1711 1714
     -- -----------------------------------------------------------------------------
    
    1712 1715
     -- BMI2
    
    1716
    +-- See Note [Keeping enabledCpuFeatures in sync] in GHC.Driver.Session
    
    1713 1717
     
    
    1714 1718
     isBmiEnabled :: DynFlags -> Bool
    
    1715 1719
     isBmiEnabled dflags = case platformArch (targetPlatform dflags) of
    

  • compiler/GHC/Driver/Session.hs
    ... ... @@ -196,6 +196,8 @@ module GHC.Driver.Session (
    196 196
     
    
    197 197
             -- * Compiler configuration suitable for display to the user
    
    198 198
             compilerInfo,
    
    199
    +        showEnabledCpuFeatures,
    
    200
    +        enabledCpuFeatures,
    
    199 201
     
    
    200 202
             targetHasRTSWays,
    
    201 203
     
    
    ... ... @@ -277,6 +279,7 @@ import GHC.Utils.TmpFs
    277 279
     import GHC.Utils.Fingerprint
    
    278 280
     import GHC.Utils.Outputable
    
    279 281
     import GHC.Utils.Error (emptyDiagOpts, logInfo)
    
    282
    +import GHC.Utils.Json
    
    280 283
     import GHC.Settings
    
    281 284
     import GHC.CmmToAsm.CFG.Weight
    
    282 285
     import GHC.Core.Opt.CallerCC
    
    ... ... @@ -3677,6 +3680,132 @@ compilerInfo dflags
    3677 3680
         queryCmdMaybe p f = expandDirectories (query (maybe "" (prgPath . p) . f))
    
    3678 3681
         queryFlagsMaybe p f = query (maybe "" (unwords . map escapeArg . prgFlags . p) . f)
    
    3679 3682
     
    
    3683
    +showEnabledCpuFeatures :: DynFlags -> String
    
    3684
    +showEnabledCpuFeatures dflags = showSDocUnsafe $ renderJSON $ JSObject
    
    3685
    +  [ ("tag", JSString "enabled-cpu-features")
    
    3686
    +    -- Schema version of this JSON object; bump it whenever the shape or
    
    3687
    +    -- meaning of the fields changes, so consumers can detect incompatibility.
    
    3688
    +  , ("version", JSInt 1)
    
    3689
    +  , ("target", JSString (platformMisc_targetPlatformString (platformMisc dflags)))
    
    3690
    +  , ("features", JSArray (map JSString features))
    
    3691
    +    -- A set of `-m...` flags that, passed to GHC for this target, reproduce
    
    3692
    +    -- the effective feature set above. Note this need not be the flags the
    
    3693
    +    -- user actually passed: implied features are folded in, and a feature
    
    3694
    +    -- enabled by default may be reproduced by the empty set.
    
    3695
    +  , ("as_m_flags", JSArray (map JSString asMFlags))
    
    3696
    +  ]
    
    3697
    +  where
    
    3698
    +    (features, asMFlags) = enabledCpuFeatures dflags
    
    3699
    +
    
    3700
    +{- Note [Keeping enabledCpuFeatures in sync]
    
    3701
    +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    3702
    +`enabledCpuFeatures` must be updated whenever a new CPU feature flag is added
    
    3703
    +to GHC. The three places to touch are, all in GHC.Driver.DynFlags:
    
    3704
    +
    
    3705
    +  1. The flag registration (e.g. `make_ord_flag defGhcFlag "mnewfeat" ...`)
    
    3706
    +  2. The corresponding `is*Enabled` predicate
    
    3707
    +  3. The `enabledCpuFeatures` function below — add the feature to `features`
    
    3708
    +     and, if it has a GHC `-m...` flag, to `as_m_flags` via the appropriate
    
    3709
    +     architecture branch.
    
    3710
    +
    
    3711
    +See Note [Implications between X86 CPU feature flags] in GHC.Driver.DynFlags
    
    3712
    +for the implication structure that `x86FeaturesAndFlags` and `x86AsMFlags`
    
    3713
    +must respect.
    
    3714
    +-}
    
    3715
    +
    
    3716
    +enabledCpuFeatures :: DynFlags -> ([String], [String])
    
    3717
    +enabledCpuFeatures dflags = case platformArch (targetPlatform dflags) of
    
    3718
    +  ArchX86_64 -> x86FeaturesAndFlags dflags
    
    3719
    +  ArchX86    -> x86FeaturesAndFlags dflags
    
    3720
    +  ArchLoongArch64 ->
    
    3721
    +    ( fmaFeature ++ [ "LA664"   | isLa664Enabled dflags ]
    
    3722
    +    , fmaFlag    ++ [ "-mla664" | isLa664Enabled dflags ]
    
    3723
    +    )
    
    3724
    +  _ -> (fmaFeature, fmaFlag)
    
    3725
    +  where
    
    3726
    +    -- `-mfma` is a cross-platform flag. On x86 it is folded into the
    
    3727
    +    -- SSE/AVX hierarchy (handled in x86FeaturesAndFlags); on every other
    
    3728
    +    -- architecture FMA stands on its own and gates FMA codegen via
    
    3729
    +    -- isFmaEnabled in stgToCmmAllowFMAInstr. `fma dflags` is the source of
    
    3730
    +    -- truth (it defaults to True on AArch64).
    
    3731
    +    fmaFeature = [ "FMA"   | fma dflags ]
    
    3732
    +    fmaFlag    = [ "-mfma" | fma dflags ]
    
    3733
    +
    
    3734
    +x86FeaturesAndFlags :: DynFlags -> ([String], [String])
    
    3735
    +x86FeaturesAndFlags dflags =
    
    3736
    +  -- SSE/SSE2 are determined by the target platform rather than a dynamic
    
    3737
    +  -- flag, hence those predicates take Platform while the others take DynFlags.
    
    3738
    +  ( [ "SSE"      | isSseEnabled platform ]
    
    3739
    + ++ [ "SSE2"     | isSse2Enabled platform ]
    
    3740
    + ++ [ "SSE3"     | isSse3Enabled dflags ]
    
    3741
    + ++ [ "SSSE3"    | isSsse3Enabled dflags ]
    
    3742
    + ++ [ "SSE4.1"   | isSse4_1Enabled dflags ]
    
    3743
    + ++ [ "SSE4.2"   | isSse4_2Enabled dflags ]
    
    3744
    + ++ [ "AVX"      | isAvxEnabled dflags ]
    
    3745
    + ++ [ "AVX2"     | isAvx2Enabled dflags ]
    
    3746
    + ++ [ "AVX512F"  | isAvx512fEnabled dflags ]
    
    3747
    + ++ [ "AVX512BW" | isAvx512bwEnabled dflags ]
    
    3748
    + ++ [ "AVX512CD" | isAvx512cdEnabled dflags ]
    
    3749
    + ++ [ "AVX512DQ" | isAvx512dqEnabled dflags ]
    
    3750
    + ++ [ "AVX512ER" | isAvx512erEnabled dflags ]
    
    3751
    + ++ [ "AVX512PF" | isAvx512pfEnabled dflags ]
    
    3752
    + ++ [ "AVX512VL" | isAvx512vlEnabled dflags ]
    
    3753
    + ++ [ "BMI1"     | isBmiEnabled dflags ]
    
    3754
    + ++ [ "BMI2"     | isBmi2Enabled dflags ]
    
    3755
    + ++ [ "FMA"      | isFmaEnabled dflags ]
    
    3756
    + ++ [ "GFNI"     | isGfniEnabled dflags ]
    
    3757
    +  , x86AsMFlags dflags
    
    3758
    +  )
    
    3759
    +  where
    
    3760
    +    platform = targetPlatform dflags
    
    3761
    +
    
    3762
    +x86AsMFlags :: DynFlags -> [String]
    
    3763
    +x86AsMFlags dflags =
    
    3764
    +     avx512Flags
    
    3765
    +  ++ vectorFlags
    
    3766
    +  ++ bmiFlags
    
    3767
    +  ++ fmaFlags
    
    3768
    +  ++ gfniFlags
    
    3769
    +  where
    
    3770
    +    avx512Extensions =
    
    3771
    +      [ ("-mavx512bw", avx512bw dflags)
    
    3772
    +      , ("-mavx512cd", avx512cd dflags)
    
    3773
    +      , ("-mavx512dq", avx512dq dflags)
    
    3774
    +      , ("-mavx512er", avx512er dflags)
    
    3775
    +      , ("-mavx512pf", avx512pf dflags)
    
    3776
    +      , ("-mavx512vl", avx512vl dflags)
    
    3777
    +      ]
    
    3778
    +
    
    3779
    +    hasAvx512Extension = any snd avx512Extensions
    
    3780
    +    hasAvx512 = avx512f dflags || hasAvx512Extension
    
    3781
    +
    
    3782
    +    avx512Flags =
    
    3783
    +      [ "-mavx512f" | avx512f dflags && not hasAvx512Extension ]
    
    3784
    +      ++ [ flag | (flag, True) <- avx512Extensions ]
    
    3785
    +
    
    3786
    +    vectorFlags
    
    3787
    +      | hasAvx512 = []
    
    3788
    +      | otherwise =
    
    3789
    +          case sseAvxVersion dflags of
    
    3790
    +            Just AVX2  -> ["-mavx2"]
    
    3791
    +            Just AVX1  -> ["-mavx"]
    
    3792
    +            Just SSE42 -> ["-msse4.2"]
    
    3793
    +            Just SSE4  -> ["-msse4"]
    
    3794
    +            Just SSSE3 -> ["-mssse3"]
    
    3795
    +            Just SSE3  -> ["-msse3"]
    
    3796
    +            _          -> []
    
    3797
    +
    
    3798
    +    bmiFlags = case bmiVersion dflags of
    
    3799
    +      Just BMI2 -> ["-mbmi2"]
    
    3800
    +      Just BMI1 -> ["-mbmi"]
    
    3801
    +      Nothing   -> []
    
    3802
    +
    
    3803
    +    fmaFlags
    
    3804
    +      | fma dflags && not hasAvx512 = ["-mfma"]
    
    3805
    +      | otherwise = []
    
    3806
    +
    
    3807
    +    gfniFlags = [ "-mgfni" | gfni dflags ]
    
    3808
    +
    
    3680 3809
     -- | Query if the target RTS has the given 'Ways'. It's computed from
    
    3681 3810
     -- the @"RTS ways"@ field in the settings file.
    
    3682 3811
     targetHasRTSWays :: DynFlags -> Ways -> Bool
    

  • docs/users_guide/using.rst
    ... ... @@ -488,6 +488,16 @@ The available mode flags are:
    488 488
         List the flags passed to the C compiler for the linking step
    
    489 489
         during GHC build.
    
    490 490
     
    
    491
    +.. ghc-flag:: --print-enabled-cpu-features
    
    492
    +    :shortdesc: display the effective enabled CPU features for code generation
    
    493
    +    :type: mode
    
    494
    +    :category: modes
    
    495
    +
    
    496
    +    Print a JSON object describing the CPU features currently enabled for code
    
    497
    +    generation, together with a set of ``-m...`` flags that reproduce the
    
    498
    +    effective feature set for the current target.
    
    499
    +    Dynamic options such as ``-mavx2`` and ``-mbmi2`` are respected.
    
    500
    +
    
    491 501
     .. ghc-flag:: --print-debug-on
    
    492 502
         :shortdesc: print whether GHC was built with ``-DDEBUG``
    
    493 503
         :type: mode
    

  • ghc/GHC/Driver/Session/Lint.hs
    1 1
     {-# LANGUAGE CPP #-}
    
    2 2
     {-# LANGUAGE NondecreasingIndentation #-}
    
    3
    -module GHC.Driver.Session.Lint (checkOptions) where
    
    3
    +module GHC.Driver.Session.Lint (checkOptions, unknownFlagsErr) where
    
    4 4
     
    
    5 5
     import GHC.Driver.Backend
    
    6 6
     import GHC.Driver.Phases
    

  • ghc/GHC/Driver/Session/Mode.hs
    ... ... @@ -77,6 +77,7 @@ isShowGhciUsageMode _ = False
    77 77
     
    
    78 78
     data PostLoadMode
    
    79 79
       = ShowInterface FilePath  -- ghc --show-iface
    
    80
    +  | PrintEnabledCpuFeatures -- ghc --print-enabled-cpu-features
    
    80 81
       | DoMkDependHS            -- ghc -M
    
    81 82
       | StopBefore StopPhase    -- ghc -E | -C | -S
    
    82 83
                                 -- StopBefore StopLn is the default
    
    ... ... @@ -90,12 +91,13 @@ data PostLoadMode
    90 91
       | DoFrontend ModuleName   -- ghc --frontend Plugin.Module
    
    91 92
     
    
    92 93
     doMkDependHSMode, doMakeMode, doInteractiveMode, doRunMode,
    
    93
    -  doAbiHashMode, showUnitsMode :: Mode
    
    94
    +  doAbiHashMode, printEnabledCpuFeaturesMode, showUnitsMode :: Mode
    
    94 95
     doMkDependHSMode = mkPostLoadMode DoMkDependHS
    
    95 96
     doMakeMode = mkPostLoadMode DoMake
    
    96 97
     doInteractiveMode = mkPostLoadMode DoInteractive
    
    97 98
     doRunMode = mkPostLoadMode DoRun
    
    98 99
     doAbiHashMode = mkPostLoadMode DoAbiHash
    
    100
    +printEnabledCpuFeaturesMode = mkPostLoadMode PrintEnabledCpuFeatures
    
    99 101
     showUnitsMode = mkPostLoadMode ShowPackages
    
    100 102
     
    
    101 103
     showInterfaceMode :: FilePath -> Mode
    
    ... ... @@ -203,6 +205,8 @@ mode_flags =
    203 205
       , defFlag "-show-options"         (PassFlag (setMode showOptionsMode))
    
    204 206
       , defFlag "-supported-languages"  (PassFlag (setMode showSupportedExtensionsMode))
    
    205 207
       , defFlag "-supported-extensions" (PassFlag (setMode showSupportedExtensionsMode))
    
    208
    +  , defFlag "-print-enabled-cpu-features"
    
    209
    +                                     (PassFlag (setMode printEnabledCpuFeaturesMode))
    
    206 210
       , defFlag "-show-packages"        (PassFlag (setMode showUnitsMode))
    
    207 211
       ] ++
    
    208 212
       [ defFlag k'                      (PassFlag (setMode (printSetting k)))
    

  • ghc/Main.hs
    ... ... @@ -229,55 +229,64 @@ main' postLoadMode units dflags0 args flagWarnings = do
    229 229
            liftIO $ exitWith (ExitFailure 1)) $ do
    
    230 230
              liftIO $ printOrThrowDiagnostics logger4 (initPrintConfig dflags4) diag_opts flagWarnings'
    
    231 231
     
    
    232
    -  liftIO $ showBanner postLoadMode dflags4
    
    233
    -
    
    234
    -  let (dflags5, srcs, objs) = parseTargetFiles dflags4 (map unLoc fileish_args)
    
    235
    -
    
    236
    -  -- we've finished manipulating the DynFlags, update the session
    
    237
    -  _ <- GHC.setSessionDynFlags dflags5
    
    238
    -  dflags6 <- GHC.getSessionDynFlags
    
    239
    -
    
    240
    -  -- Must do this before loading plugins
    
    241
    -  liftIO $ initUniqSupply (initialUnique dflags6) (uniqueIncrement dflags6)
    
    242
    -
    
    243
    -  -- Initialise plugins here because the plugin author might already expect this
    
    244
    -  -- subsequent call to `getLogger` to be affected by a plugin.
    
    245
    -  initializeSessionPlugins
    
    246
    -  hsc_env <- getSession
    
    247
    -  logger <- getLogger
    
    248
    -
    
    249
    -
    
    250
    -        ---------------- Display configuration -----------
    
    251
    -  case verbosity dflags6 of
    
    252
    -    v | v == 4 -> liftIO $ dumpUnitsSimple hsc_env
    
    253
    -      | v >= 5 -> liftIO $ dumpUnits       hsc_env
    
    254
    -      | otherwise -> return ()
    
    255
    -
    
    256
    -        ---------------- Final sanity checking -----------
    
    257
    -  liftIO $ checkOptions postLoadMode dflags6 srcs objs units
    
    258
    -
    
    259
    -  ---------------- Do the business -----------
    
    260
    -  handleSourceError (\e -> do
    
    261
    -       GHC.printException e
    
    262
    -       liftIO $ exitWith (ExitFailure 1)) $ do
    
    263
    -    case postLoadMode of
    
    264
    -       ShowInterface f        -> liftIO $ showIface logger
    
    265
    -                                                    (hsc_dflags hsc_env)
    
    266
    -                                                    (hsc_units  hsc_env)
    
    267
    -                                                    (hsc_NC     hsc_env)
    
    268
    -                                                    f
    
    269
    -       DoMake                 -> doMake units srcs
    
    270
    -       DoMkDependHS           -> doMkDependHS (map fst srcs)
    
    271
    -       StopBefore p           -> liftIO (oneShot hsc_env p srcs)
    
    272
    -       DoInteractive          -> ghciUI units srcs Nothing
    
    273
    -       DoEval exprs           -> ghciUI units srcs $ Just $ reverse exprs
    
    274
    -       DoRun                  -> doRun units srcs args
    
    275
    -       DoAbiHash              -> abiHash (map fst srcs)
    
    276
    -       ShowPackages           -> liftIO $ showUnits hsc_env
    
    277
    -       DoFrontend f           -> doFrontend f srcs
    
    278
    -       DoBackpack             -> doBackpack (map fst srcs)
    
    279
    -
    
    280
    -  liftIO $ dumpFinalStats logger
    
    232
    +  case postLoadMode of
    
    233
    +    PrintEnabledCpuFeatures -> liftIO $ do
    
    234
    +      -- This mode bypasses parseTargetFiles/checkOptions, so reject any
    
    235
    +      -- leftover flag-like arguments (e.g. a mistyped -mavx22) ourselves;
    
    236
    +      -- otherwise the typo would be silently ignored.
    
    237
    +      let unknown_opts = [ f | f@('-':_) <- map unLoc fileish_args ]
    
    238
    +      when (not (null unknown_opts)) (unknownFlagsErr unknown_opts)
    
    239
    +      putStrLn (showEnabledCpuFeatures dflags4)
    
    240
    +    _ -> do
    
    241
    +      liftIO $ showBanner postLoadMode dflags4
    
    242
    +
    
    243
    +      let (dflags5, srcs, objs) = parseTargetFiles dflags4 (map unLoc fileish_args)
    
    244
    +
    
    245
    +      -- we've finished manipulating the DynFlags, update the session
    
    246
    +      _ <- GHC.setSessionDynFlags dflags5
    
    247
    +      dflags6 <- GHC.getSessionDynFlags
    
    248
    +
    
    249
    +      -- Must do this before loading plugins
    
    250
    +      liftIO $ initUniqSupply (initialUnique dflags6) (uniqueIncrement dflags6)
    
    251
    +
    
    252
    +      -- Initialise plugins here because the plugin author might already expect this
    
    253
    +      -- subsequent call to `getLogger` to be affected by a plugin.
    
    254
    +      initializeSessionPlugins
    
    255
    +      hsc_env <- getSession
    
    256
    +      logger <- getLogger
    
    257
    +
    
    258
    +
    
    259
    +            ---------------- Display configuration -----------
    
    260
    +      case verbosity dflags6 of
    
    261
    +        v | v == 4 -> liftIO $ dumpUnitsSimple hsc_env
    
    262
    +          | v >= 5 -> liftIO $ dumpUnits       hsc_env
    
    263
    +          | otherwise -> return ()
    
    264
    +
    
    265
    +            ---------------- Final sanity checking -----------
    
    266
    +      liftIO $ checkOptions postLoadMode dflags6 srcs objs units
    
    267
    +
    
    268
    +      ---------------- Do the business -----------
    
    269
    +      handleSourceError (\e -> do
    
    270
    +           GHC.printException e
    
    271
    +           liftIO $ exitWith (ExitFailure 1)) $ do
    
    272
    +        case postLoadMode of
    
    273
    +           ShowInterface f        -> liftIO $ showIface logger
    
    274
    +                                                        (hsc_dflags hsc_env)
    
    275
    +                                                        (hsc_units  hsc_env)
    
    276
    +                                                        (hsc_NC     hsc_env)
    
    277
    +                                                        f
    
    278
    +           DoMake                 -> doMake units srcs
    
    279
    +           DoMkDependHS           -> doMkDependHS (map fst srcs)
    
    280
    +           StopBefore p           -> liftIO (oneShot hsc_env p srcs)
    
    281
    +           DoInteractive          -> ghciUI units srcs Nothing
    
    282
    +           DoEval exprs           -> ghciUI units srcs $ Just $ reverse exprs
    
    283
    +           DoRun                  -> doRun units srcs args
    
    284
    +           DoAbiHash              -> abiHash (map fst srcs)
    
    285
    +           ShowPackages           -> liftIO $ showUnits hsc_env
    
    286
    +           DoFrontend f           -> doFrontend f srcs
    
    287
    +           DoBackpack             -> doBackpack (map fst srcs)
    
    288
    +
    
    289
    +      liftIO $ dumpFinalStats logger
    
    281 290
     
    
    282 291
     doRun :: [String] -> [(FilePath, Maybe Phase)] -> [Located String] -> Ghc ()
    
    283 292
     doRun units srcs args = do
    
    ... ... @@ -515,4 +524,3 @@ abiHash strs = do
    515 524
       f <- fingerprintBinMem bh
    
    516 525
     
    
    517 526
       putStrLn (showPpr dflags f)
    518
    -

  • testsuite/tests/driver/all.T
    1
    +def normalise_enabled_cpu_target(msg):
    
    2
    +    return re.sub(r'"target":"[^"]+"', '"target":"TARGET"', msg)
    
    3
    +
    
    4
    +def normalise_unknown_flag(msg):
    
    5
    +    # Keep only the stable 'unrecognised flag' line; the program-name prefix,
    
    6
    +    # the suggestion list, and the usage trailer vary across configurations.
    
    7
    +    m = re.search(r'unrecognised flag: \S+', msg)
    
    8
    +    return m.group(0) + '\n' if m else msg
    
    9
    +
    
    1 10
     test('driver011', [extra_files(['A011.hs'])], makefile_test, ['test011'])
    
    2 11
     
    
    3 12
     test('driver012', [extra_files(['A012.hs'])], makefile_test, ['test012'])
    
    ... ... @@ -221,6 +230,41 @@ test('T9938B', [], makefile_test, [])
    221 230
     test('T9963', exit_code(1), run_command,
    
    222 231
          ['{compiler} --interactive -ignore-dot-ghci --print-libdir'])
    
    223 232
     
    
    233
    +test('print_enabled_cpu_features',
    
    234
    +     [unless(arch('x86_64') or arch('i386'), skip),
    
    235
    +      normalise_fun(normalise_enabled_cpu_target)],
    
    236
    +     run_command,
    
    237
    +     ['{compiler} --print-enabled-cpu-features'])
    
    238
    +
    
    239
    +test('print_enabled_cpu_features_avx2',
    
    240
    +     [unless(arch('x86_64') or arch('i386'), skip),
    
    241
    +      normalise_fun(normalise_enabled_cpu_target)],
    
    242
    +     run_command,
    
    243
    +     ['{compiler} -mavx2 --print-enabled-cpu-features'])
    
    244
    +
    
    245
    +test('print_enabled_cpu_features_bmi2',
    
    246
    +     [unless(arch('x86_64') or arch('i386'), skip),
    
    247
    +      normalise_fun(normalise_enabled_cpu_target)],
    
    248
    +     run_command,
    
    249
    +     ['{compiler} -mbmi2 --print-enabled-cpu-features'])
    
    250
    +
    
    251
    +test('print_enabled_cpu_features_fma',
    
    252
    +     [unless(arch('x86_64') or arch('i386'), skip),
    
    253
    +      normalise_fun(normalise_enabled_cpu_target)],
    
    254
    +     run_command,
    
    255
    +     ['{compiler} -mfma --print-enabled-cpu-features'])
    
    256
    +
    
    257
    +test('print_enabled_cpu_features_avx512',
    
    258
    +     [unless(arch('x86_64'), skip),
    
    259
    +      normalise_fun(normalise_enabled_cpu_target)],
    
    260
    +     run_command,
    
    261
    +     ['{compiler} -mavx512dq -mavx512vl --print-enabled-cpu-features'])
    
    262
    +
    
    263
    +test('print_enabled_cpu_features_unknown_flag',
    
    264
    +     [normalise_fun(normalise_unknown_flag), exit_code(1)],
    
    265
    +     run_command,
    
    266
    +     ['{compiler} -mavx22 --print-enabled-cpu-features'])
    
    267
    +
    
    224 268
     test('T10219', normal, run_command,
    
    225 269
          # `-x hspp` in make mode should work.
    
    226 270
          # Note: need to specify `-x hspp` before the filename.
    

  • testsuite/tests/driver/print_enabled_cpu_features.stdout
    1
    +{"tag":"enabled-cpu-features","version":1,"target":"TARGET","features":["SSE","SSE2"],"as_m_flags":[]}

  • testsuite/tests/driver/print_enabled_cpu_features_avx2.stdout
    1
    +{"tag":"enabled-cpu-features","version":1,"target":"TARGET","features":["SSE","SSE2","SSE3","SSSE3","SSE4.1","SSE4.2","AVX","AVX2"],"as_m_flags":["-mavx2"]}

  • testsuite/tests/driver/print_enabled_cpu_features_avx512.stdout
    1
    +{"tag":"enabled-cpu-features","version":1,"target":"TARGET","features":["SSE","SSE2","SSE3","SSSE3","SSE4.1","SSE4.2","AVX","AVX2","AVX512F","AVX512DQ","AVX512VL","FMA"],"as_m_flags":["-mavx512dq","-mavx512vl"]}

  • testsuite/tests/driver/print_enabled_cpu_features_bmi2.stdout
    1
    +{"tag":"enabled-cpu-features","version":1,"target":"TARGET","features":["SSE","SSE2","BMI1","BMI2"],"as_m_flags":["-mbmi2"]}

  • testsuite/tests/driver/print_enabled_cpu_features_fma.stdout
    1
    +{"tag":"enabled-cpu-features","version":1,"target":"TARGET","features":["SSE","SSE2","SSE3","SSSE3","SSE4.1","SSE4.2","AVX","FMA"],"as_m_flags":["-mfma"]}

  • testsuite/tests/driver/print_enabled_cpu_features_unknown_flag.stderr
    1
    +ghc: unrecognised flag: -mavx22
    
    2
    +did you mean one of:
    
    3
    +  -mavx2
    
    4
    +  -mavx
    
    5
    +
    
    6
    +Usage: For basic information, try the `--help' option.