Skip to content

Adding explicit optimization flags for interaction with GHC#11716

Open
zlonast wants to merge 2 commits into
haskell:masterfrom
zlonast:zlonast/optimizationCFlags
Open

Adding explicit optimization flags for interaction with GHC#11716
zlonast wants to merge 2 commits into
haskell:masterfrom
zlonast:zlonast/optimizationCFlags

Conversation

@zlonast
Copy link
Copy Markdown
Collaborator

@zlonast zlonast commented Apr 8, 2026

Cabal now adds explicit -optc-O2, -optcxx-O2 and -opta-O2 flags when
invoking GHC for C, C++ and assembler source files that are built with
optimization. These explicit flags are only inserted when the user has not
already provided an optimization flag (-O, -O0, -O1, -O2, -O3),
so that existing user choices are never overridden or duplicated.

Here are some examples

Example 1

no leakage between modules

library
  cc-options: -O3 -g3

executable Deduplication
  build-depends:
    , base
    , Deduplication
  cxx-options: -O1 -g1

to

Build profile: -w ghc-<GHCVER> -O1
exe: "-O1","-g0", ... ,"-optc-O2","-optc-g0","-optcxx-O1","-optcxx-g1","-opta-O2","-opta-g0"
lib: "-O1","-g0", ... ,"-optc-O3","-optc-g3","-optcxx-O2","-optcxx-g0","-opta-O2","-opta-g0",

expected behavior

Example 2

optimization: False
debug-info: True

to

Build profile: -w ghc-<GHCVER> -O1
exe/lib:"-O0","-g2", ... ,"-optc-O0","-optc-g2","-optcxx-O0","-optcxx-g2","-opta-O0","-opta-g2"

Example 3

implicit behavior -g0
to

"-O1","-g0" ... ,"-optc-O2","-optc-g0","-optcxx-O2","-optcxx-g0","-opta-O2","-opta-g0"

but

Build profile: -w ghc-<GHCVER> -O1

because
I don't want to contribute to all cabal tests.

Example 4

ghc-options: -O0

to

Build profile: -w ghc-<GHCVER> -O1
exe:"-O0","-g0", ... ,"-optc-O2","-optc-g0","-optcxx-O2","-optcxx-g0","-opta-O2","-opta-g0"
lib:"-O1","-g0", ... ,"-optc-O2","-optc-g0","-optcxx-O2","-optcxx-g0","-opta-O2","-opta-g0"

because it's local optimization

showBuildProfile: "-O" ++ fromOptimisationLevel (globalOptimization <> localOptimization)

Fan fact cabal codebase is all in OptimiSation and OptimiZation

Template Α: This PR modifies behaviour or interface

Include the following checklist in your PR:

Comment thread Cabal/src/Distribution/Simple/GHC/Internal.hs Outdated
@zlonast zlonast force-pushed the zlonast/optimizationCFlags branch 2 times, most recently from 374f8bf to 50720f6 Compare May 9, 2026 15:06
Comment thread cabal-install/src/Distribution/Client/ProjectOrchestration.hs
@zlonast zlonast force-pushed the zlonast/optimizationCFlags branch 12 times, most recently from 840a960 to c0b8ed7 Compare May 11, 2026 19:37
@zlonast
Copy link
Copy Markdown
Collaborator Author

zlonast commented May 11, 2026

How strange, I don't know what the problem is with BuildToolPaths and ghc 9.14.1

Comment thread cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs
Comment thread cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs
-- optimisation or requests a different level elsewhere.
sourceOptimization :: OptimisationLevel -> [String]
sourceOptimization = \case
NoOptimisation -> ["-O0"]
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I propose to put a clear flag instead of nothing NoOptimisation -> [], which logically fits the situation NoOptimisation -> ["-O0"]

Comment thread Cabal/src/Distribution/Simple/Setup/Config.hs
Comment thread Cabal/src/Distribution/Simple/Setup/Config.hs
| -- | @-O2@
GhcMaximumOptimisation
| -- | e.g. @-Odph@
GhcSpecialOptimisation String
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.. ghc-flag:: -O⟨n⟩
:shortdesc: Any -On where n > 2 is the same as -O2.
:type: dynamic
:reverse: -O0
:category: optimization-levels

.. index::
   single: optimise; aggressively

Any -On where n > 2 is the same as -O2.

@zlonast zlonast force-pushed the zlonast/optimizationCFlags branch 3 times, most recently from d87d3e0 to 65da48e Compare May 12, 2026 21:29
@zlonast
Copy link
Copy Markdown
Collaborator Author

zlonast commented May 13, 2026

I always try to pass flags, but it's better not to do this when linking, since for some reason cabal hooks die 🤔

@sheaf Could you please tell me if I'm trying to pass extra flags when linking. Is it my fault? Or is it ghc that's incorrectly passing them to gcc? Or is it cabal that's not filtering them? And where should I create an issue?

Because I can't always pass flags, I had to put a lot of NoFlag -> []

The only test where this appears is BuildToolPaths, which uses new cabal hooks.

https://github.com/haskell/cabal/actions/runs/25755559764/job/75643108252

  [1 of 3] Compiling SetupHooks       ( /tmp/cabal-testsuite-121237/cabal.dist/work/dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/SetupHooks.hs, /tmp/cabal-testsuite-121237/cabal.dist/work/dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/SetupHooks.o )
  [2 of 3] Compiling Main             ( /tmp/cabal-testsuite-121237/cabal.dist/work/dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/hooks.hs, /tmp/cabal-testsuite-121237/cabal.dist/work/dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/Main.o )
  [3 of 3] Linking /tmp/cabal-testsuite-121237/cabal.dist/work/./dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/hooks
  /usr/bin/ld: /tmp/cabal-testsuite-121237/cabal.dist/work/./dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/SetupHooks.o: in function `SetupHooks_init__spt':
  (.text+0x370f): undefined reference to `rcrt_closure'
  /usr/bin/ld: (.text+0x371e): undefined reference to `rcrK_closure'
  collect2: error: ld returned 1 exit status
  ghc-9.14.1: Uncaught exception ghc-9.14.1-c6c3:GHC.Utils.Panic.GhcException:
  
  `gcc' failed in phase `Linker'. (Exit code: 1)
  
  While handling `gcc' failed in phase `Linker'. (Exit code: 1)
  
  HasCallStack backtrace:
    throwIO, called at libraries/exceptions/src/Control/Monad/Catch.hs:343:12 in exceptions-0.10.11-acb5:Control.Monad.Catch
    throwM, called at libraries/exceptions/src/Control/Monad/Catch.hs:855:84 in exceptions-0.10.11-acb5:Control.Monad.Catch
    onException, called at compiler/GHC/Driver/MakeAction.hs:235:23 in ghc-9.14.1-c6c3:GHC.Driver.MakeAction

@zlonast zlonast mentioned this pull request May 13, 2026
4 tasks
@sheaf
Copy link
Copy Markdown
Collaborator

sheaf commented May 13, 2026

I always try to pass flags, but it's better not to do this when linking, since for some reason cabal hooks die 🤔

@sheaf Could you please tell me if I'm trying to pass extra flags when linking. Is it my fault? Or is it ghc that's incorrectly passing them to gcc? Or is it cabal that's not filtering them? And where should I create an issue?

Because I can't always pass flags, I had to put a lot of NoFlag -> []

The only test where this appears is BuildToolPaths, which uses new cabal hooks.

https://github.com/haskell/cabal/actions/runs/25755559764/job/75643108252

  [1 of 3] Compiling SetupHooks       ( /tmp/cabal-testsuite-121237/cabal.dist/work/dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/SetupHooks.hs, /tmp/cabal-testsuite-121237/cabal.dist/work/dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/SetupHooks.o )
  [2 of 3] Compiling Main             ( /tmp/cabal-testsuite-121237/cabal.dist/work/dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/hooks.hs, /tmp/cabal-testsuite-121237/cabal.dist/work/dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/Main.o )
  [3 of 3] Linking /tmp/cabal-testsuite-121237/cabal.dist/work/./dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/hooks
  /usr/bin/ld: /tmp/cabal-testsuite-121237/cabal.dist/work/./dist/build/x86_64-linux/ghc-9.14.1/pbts-0.1.0.0/setup/SetupHooks.o: in function `SetupHooks_init__spt':
  (.text+0x370f): undefined reference to `rcrt_closure'
  /usr/bin/ld: (.text+0x371e): undefined reference to `rcrK_closure'
  collect2: error: ld returned 1 exit status
  ghc-9.14.1: Uncaught exception ghc-9.14.1-c6c3:GHC.Utils.Panic.GhcException:
  
  `gcc' failed in phase `Linker'. (Exit code: 1)
  
  While handling `gcc' failed in phase `Linker'. (Exit code: 1)
  
  HasCallStack backtrace:
    throwIO, called at libraries/exceptions/src/Control/Monad/Catch.hs:343:12 in exceptions-0.10.11-acb5:Control.Monad.Catch
    throwM, called at libraries/exceptions/src/Control/Monad/Catch.hs:855:84 in exceptions-0.10.11-acb5:Control.Monad.Catch
    onException, called at compiler/GHC/Driver/MakeAction.hs:235:23 in ghc-9.14.1-c6c3:GHC.Driver.MakeAction

Ah yes. I think this is GHC bug #16981/#24773. I think what's happening is that, with this patch, we start to compile the SetupHooks.hs with optimisations, so we trigger the bug that we didn't trigger beforehand.

Let me investigate and suggest a fix, but I imagine it will simply involve implementing the changes described in GHC proposal #732.

@sheaf
Copy link
Copy Markdown
Collaborator

sheaf commented May 13, 2026

I have managed to reproduce the issue with commit f8ee456, but only on Linux (not on Windows).

I tried to mitigate by moving things to the top-level but this didn't fix the isssue. So I think this is a new (different) bug in GHC. I will try to minimise and report it. Do you know which GHC versions are affected; is it only GHC 9.14 and not prior versions?

@zlonast
Copy link
Copy Markdown
Collaborator Author

zlonast commented May 13, 2026

I have managed to reproduce the issue with commit f8ee456, but only on Linux (not on Windows).

I tried to mitigate by moving things to the top-level but this didn't fix the isssue. So I think this is a new (different) bug in GHC. I will try to minimise and report it. Do you know which GHC versions are affected; is it only GHC 9.14 and not prior versions?

I don't know. There's only one complex hooks test here.

CI crashed consistently on all three platforms with ghc 9.14.1.

@zlonast
Copy link
Copy Markdown
Collaborator Author

zlonast commented May 13, 2026

CI windows are also failed c0b8ed7

@zlonast
Copy link
Copy Markdown
Collaborator Author

zlonast commented May 13, 2026

origin:
          case flagToMaybe (ghcOptOptimisation opts) of
            Nothing -> []
            Just GhcNoOptimisation -> ["-O0"]
            Just GhcNormalOptimisation -> ["-O"]
            Just GhcMaximumOptimisation -> ["-O2"]
            Just (GhcSpecialOptimisation s) -> ["-O" ++ s] -- eg -Odph
        , case flagToMaybe (ghcOptDebugInfo opts) of
            Nothing -> []
            Just NoDebugInfo -> []
            Just MinimalDebugInfo -> ["-g1"]
            Just NormalDebugInfo -> ["-g2"]
            Just MaximalDebugInfo -> ["-g3"]

my failed attempt:

         ["-O" ++ fromOptimisationLevel (ghcOptOptimisation opts)]
       , ["-g" ++ fromDebugInfoLevel (ghcOptDebugInfo opts)]

I suspect you can easy to catch it with change Nothing -> [] to Nothing -> ["-O1"] and Nothing -> [] to Nothing -> ["-g2"]

@sheaf
Copy link
Copy Markdown
Collaborator

sheaf commented May 13, 2026

I wrote a reproducer and found that the issue has been fixed on the GHC 10.0 branch; I assume by this commit.

I would recommend adding the following to the SetupHooks.hs module:

{-# LANGUAGE CPP #-}

-- Disable optimisations to work around GHC bug #16981 (fixed with GHC 10.0)
#if __GLASGOW_HASKELL__ < 1000
{-# OPTIONS_GHC -O0 #-}
#endif

@zlonast zlonast force-pushed the zlonast/optimizationCFlags branch from b1b2abe to 8d95791 Compare May 15, 2026 14:28
@zlonast zlonast added re: -O0 Concerning building with `-O0` (`noopt`) re: -O2 Concerning `-O2` optimization level re: ghc-options Concerning passing options to GHC cabal-install: v2-build system Affecting v2-build and related commands that use v2-architecture (aka "nix local builds"). labels May 18, 2026
@zlonast zlonast force-pushed the zlonast/optimizationCFlags branch 2 times, most recently from 1fcf15e to 9b81d5e Compare May 19, 2026 08:49
@zlonast
Copy link
Copy Markdown
Collaborator Author

zlonast commented May 19, 2026

And here we have internet problems with windows ghc-9.12.4 :(

@ulysses4ever
Copy link
Copy Markdown
Collaborator

@zlonast do you not have permisions to restart CI jobs? we should look into it if so.

@zlonast
Copy link
Copy Markdown
Collaborator Author

zlonast commented May 19, 2026

@ulysses4ever I don't have that permission. I'd also like to be able to link an issue to a pr-s

@ulysses4ever
Copy link
Copy Markdown
Collaborator

@zlonast can you try now?

@zlonast
Copy link
Copy Markdown
Collaborator Author

zlonast commented May 19, 2026

@ulysses4ever Thank you :)

@zlonast zlonast force-pushed the zlonast/optimizationCFlags branch 3 times, most recently from f525a2e to 3cc9e18 Compare May 26, 2026 17:22
@zlonast zlonast force-pushed the zlonast/optimizationCFlags branch from 3cc9e18 to 4f0f103 Compare May 26, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

attention: needs-review cabal-install: v2-build system Affecting v2-build and related commands that use v2-architecture (aka "nix local builds"). re: -O0 Concerning building with `-O0` (`noopt`) re: -O2 Concerning `-O2` optimization level re: ghc-options Concerning passing options to GHC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants