
#14452: `-optc-O3` getting shadowed by automatically injected -O flags -------------------------------------+------------------------------------- Reporter: hvr | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.2.1 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Consider the following example: {{{#!hs {-# LANGUAGE CApiFFI #-} {-# OPTIONS_GHC -optc-O3 #-} module M where foreign import capi unsafe "stdlib.h exit" c_exit :: Int -> IO () }}} However, the `-optc-O3` flag has no effect, unless `ghc` is called without any `-O` flags, or with `-O0`. Here's the resulting C compiler invocations for different `-O` flags: {{{ $ ghc -fforce-recomp -v -c m.hs |& grep O3 gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -O3 -x c /tmp/ghc14023_0/ghc_2.c -o /tmp/ghc14023_0/ghc_3.s -Wimplicit -S -include /opt/ghc/8.2.1/lib/ghc-8.2.1/include/ghcversion.h -I. -I/opt/ghc/8.2.1/lib/ghc-8.2.1/base-4.10.0.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/integer-gmp-1.0.1.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/include }}} {{{ $ ghc -fforce-recomp -O0 -v -c m.hs |& grep O3 gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -O3 -x c /tmp/ghc14045_0/ghc_2.c -o /tmp/ghc14045_0/ghc_3.s -Wimplicit -S -include /opt/ghc/8.2.1/lib/ghc-8.2.1/include/ghcversion.h -I. -I/opt/ghc/8.2.1/lib/ghc-8.2.1/base-4.10.0.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/integer-gmp-1.0.1.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/include }}} {{{ $ ghc -fforce-recomp -O1 -v -c m.hs |& grep O3 gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -O3 -x c /tmp/ghc14073_0/ghc_2.c -o /tmp/ghc14073_0/ghc_3.s -Wimplicit -S -O -include /opt/ghc/8.2.1/lib/ghc-8.2.1/include/ghcversion.h -I. -I/opt/ghc/8.2.1/lib/ghc-8.2.1/base-4.10.0.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/integer-gmp-1.0.1.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/include }}} {{{ $ ghc -fforce-recomp -O2 -v -c m.hs |& grep O3 gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -O3 -x c /tmp/ghc14093_0/ghc_2.c -o /tmp/ghc14093_0/ghc_3.s -Wimplicit -S -O2 -include /opt/ghc/8.2.1/lib/ghc-8.2.1/include/ghcversion.h -I. -I/opt/ghc/8.2.1/lib/ghc-8.2.1/base-4.10.0.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/integer-gmp-1.0.1.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/include }}} {{{ $ ghc -fforce-recomp -O3 -v -c m.hs |& grep O3 gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -O3 -x c /tmp/ghc14119_0/ghc_2.c -o /tmp/ghc14119_0/ghc_3.s -Wimplicit -S -O2 -include /opt/ghc/8.2.1/lib/ghc-8.2.1/include/ghcversion.h -I. -I/opt/ghc/8.2.1/lib/ghc-8.2.1/base-4.10.0.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/integer-gmp-1.0.1.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/include }}} To summarise, here's the resulting effective `-O`-level passed to `gcc`: ||= GHC invocation =||= GCC invocation =||= Effective C `-O`-level =|| || `ghc` || `gcc -O3` || `-O3` || || `ghc -O0` || `gcc -O3` || `-O3` || || `ghc -O1` || `gcc -O3 -O1` || `-O1` || || `ghc -O2` || `gcc -O3 -O2` || `-O2` || || `ghc -O3` || `gcc -O3 -O2` || `-O2` || Consequently, the only way to have C code compiled with `-O3` is to force GHC into `-O0` mode; this is obviously not ideal, as it easily kills any benefit you'd gain from passing `-O3` to the C compiler... ;-) I see a few alternatives on how to resolve this: 1. Have GHC recognise `-optc-O[0-9]` and suppress automatically injecting any `-O<n>` of its own 2. Have GHC inject its automatic `-O`-flags before user-provided `-optc` flags 3. Have GHC inject `-optc` flags as late as possible on the C compiler command-line 4. Implement a new variant of the `-optc` flag which injects its flags as late as possible on the C compiler command-line -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14452 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler