#10560: -f and -O options interact in non-obvious, order dependent ways -------------------------------------+------------------------------------- Reporter: bgamari | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.1 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect | Unknown/Multiple warning at compile-time | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Revisions: -------------------------------------+------------------------------------- Comment (by svenpanne): Hmmm, GCC's behavior is a bit weird, and to be honest: It's the first time that I've heard of the fact that e.g. -Ofoo is processed before -fblah, regardless of the order on the command line. Re-reading GCC's documentation, it is explicitly stated that order is important, but the docs introduce the notion of "option kind", without actually specifying what those kinds are and in which order those kinds are processed (https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/Invoking-GCC.html). Obviously, the -Ofoo options are of a different kind than the -fblah options, and the -Ofoo ones are processed before the -fblah ones. *But* within these kinds, order matters: {{{ $ gcc -c -Q --help=optimizers -O3 -O0 | grep tree-vectorize -ftree-vectorize [disabled] $ gcc -c -Q --help=optimizers -O0 -O3 | grep tree-vectorize -ftree-vectorize [enabled] }}} OTOH, clang doesn't seem to have this notion of "kinds" and simply processes options in order: {{{ $ echo 'int x;' | clang -xc -fno-vectorize -O2 - -o /dev/null -\#\#\# 2>&1 | sed 's/\s/\n/g' | grep vectorize-loops "-vectorize-loops" $ echo 'int x;' | clang -xc -O2 -fno-vectorize - -o /dev/null -\#\#\# 2>&1 | sed 's/\s/\n/g' | grep vectorize-loops <no output> }}} Same for most other tools, including e.g. git: {{{ $ git log --pretty=short --oneline ab3926f Fix PR13851: Preserve metadata for the unswitched branch 9e7539a Remove broken banner. ... $ git log --oneline --pretty=short commit ab3926f Author: Weiming Zhao <weimingz@codeaurora.org> Fix PR13851: Preserve metadata for the unswitched branch commit 9e7539a Author: Rafael Espindola <rafael.espindola@gmail.com> Remove broken banner. ... }}} So in a nutshell: If we really want to mirror GCC's behavior (which is not 100% clear to me), we have to introduce "option kinds", partition our flags into those kinds, and impose an order on those kinds. Furthermore, one can't simply expand "meta" flags and process those expanded flags afterwards (see the -O3 -O0 vs. -O0 -O3 example above), the expansion can only be done after the corresponding "kind phase" has been processed. Much fun documenting all this stuff. :-) IMHO this is far too complicated, and GCC seems to be an outlier regarding this, just processing things in order (as we currently do?) is the easiest thing. But I'll leave the final decision up to those implementing and documenting any change, as long as we don't introduce any ad hoc warnings. Final thought: clang's optimizer options for -O0, -O1, ... are *not* subsets of the previous optimization level, so one has to think about meta options removing flags. o_O I hope we won't do this... -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10560#comment:17> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler