On 12/06/17 18:11, Joseph Myers wrote: > On Mon, 12 Jun 2017, Richard Earnshaw (lists) wrote: > >> It does. The problem seems to be a generic one in the driver in that >> the rewrite rules are always passed the first instance of -march and not >> the last. Indeed, with the aarch64 compiler, if I write >> >> gcc -mcpu=native -mcpu=cortex-a53 >> >> then the driver will rewrite this as >> >> ./cc1 -mcpu=cortex-a53 -mcpu=<expansion of native cpu name> >> >> which doesn't seem to be the right thing at all. >> >> So we either have a generic problem with all option rewriting, or there >> are some subtle details of it that we've not figured out yet. >> >> Joseph, is there a way to get the rewrite rules to receive the *last* >> instance of a flag rather than the first? Or is the current behaviour >> simply wrong? > > I think there are at least two separate issues here. > > In the AArch64 port (and other ports), the specs for -mcpu=native use > %{mcpu=native:%<mcpu=native %:local_cpu_detect(cpu)} as part of > DRIVER_SELF_SPECS. Options added by DRIVER_SELF_SPECS are added at the > end of the command line (after OPTION_DEFAULT_SPECS has been processed). > Thus, if there is any -mcpu=native option, the options from generated by > local_cpu_detect will be added. >
Yes, this seems like a bug in all implementations of native detect routines. To make the behaviour sane I think they will all need to be reworked to pass all relevant -m<opt>= variants into some code that checks first that "native" is the last option and only then to apply the substitution. > In patch 14 of this series, you have specs of the form %{mcpu=*: cpu %*} > inside a canon_arch call. According to the comment in gcc.c documenting > specs > > %{S*:X} substitutes X if one or more switches whose names start > with -S was given to GCC. Normally X is substituted only > once, no matter how many such switches appeared. However, > if %* appears somewhere in X, then X will be substituted > once for each matching switch, with the %* replaced by the > part of that switch that matched the '*'. A space will be > appended after the last substition unless there is more > text in current sequence. > > this ought to mean that every -mcpu= option results in a corresponding cpu > <something> in the arguments to canon_arch (in the same order as the > original options). If it doesn't, that sounds like a bug in the %* > handling. > So when I investigated this further this afternoon I made the following observations. Firstly, sometimes all the -march options were being passed through and sometimes only the first. That seemed odd, so I dug a bit further. It seems the later options are cancelled by the %<march=* component of %{march=*: arch %* %<march=*}. But only sometimes... It seems that the gating criteria for whether or not they are cancelled is that if -marm is on the command line the second and subsequent options are cancelled; if it isn't (and I'm guessing, if -mthumb is also not present) then the subsequent -march options are passed through. Now why would that make a difference? After all, -marm/-mthumb isn't used at all in this rule. At this stage I can only speculate that %{march=*: arch %*} is also used by the the TARGET_MODE_SPEC_FUNCTION rule and that this is somehow causing the array to be cached? I need to do some more digging here, but it seems that at the very least the behaviour is not consistent. Whether or not this rule should be supportable or not is still TBD. In fact I probably don't need the %<march=* part of the rule. I hadn't realized that is was possible to maintain all such options and just interpret the last one. So for my purposes that might be the best solution, since my canon_arch generated option will simply override any existing -march options. > Overridden options can be removed before specs processing if a cycle of > options is marked with Negative in the .opt files (see prune_options), but > that doesn't apply to options with arguments. If you had a system for > pruning e.g. all but the last -mcpu= option (for options where it's just > the last argument that matters), you'd also want to make sure that prior > options do still generate errors if the option argument is invalid. > R.