Bug 80782 - Configure options to use llvm/clang assembler on Mac
Summary: Configure options to use llvm/clang assembler on Mac
Status: WAITING
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-05-16 16:52 UTC by René J.V. Bertin
Modified: 2022-05-24 17:07 UTC (History)
3 users (show)

See Also:
Host: *-*-darwin*
Target: *-*-darwin*
Build: *-*-darwin*
Known to work:
Known to fail:
Last reconfirmed: 2017-05-17 00:00:00


Attachments
wrapper to make "clang-as" callable as [g]as (969 bytes, application/x-shellscript)
2017-05-16 16:52 UTC, René J.V. Bertin
Details

Note You need to log in before you can comment on or make changes to this bug.
Description René J.V. Bertin 2017-05-16 16:52:05 UTC
Created attachment 41367 [details]
wrapper to make "clang-as" callable as [g]as

Apple provides an ageing GNU as fork as part of its cctools package: it's based on gas 1.38 and thus lacks support for CPU instruction sets added after that release.

As a result, GCC generates code that fails to assemble when using optimisation for any CPU that has support for AVX or newer intrinsics. A pity and often annoying because the failure can happen only late during a build process.

The easiest way around this would be to use the assembler that is actually used by clang.

I'm attaching a wrapper script that I have been using to build boost, R and a few KF5 applications with full optimisation for an i7 CPU on Mac OS X 10.9.5 . (The resulting R binary is consistently a few percent faster than the same code built with clang 4.0)

For some reason I fail to understand the GCC build process fails when using this wrapper: the tconfig.h header file is not generated. I have worked around that by providing a shunt in the wrapper that just hands off the command to the regular as executable, but there must be a more elegant way.
Comment 1 Andrew Pinski 2017-05-16 16:57:51 UTC
The support is already there ...
Comment 2 Andrew Pinski 2017-05-16 17:00:35 UTC
.

*** This bug has been marked as a duplicate of bug 71767 ***
Comment 3 Marc Glisse 2017-05-16 17:23:28 UTC
(In reply to Andrew Pinski from comment #1)
> The support is already there ...

So, what is the correct configure option to let gcc use it by default?
Comment 4 René J.V. Bertin 2017-05-16 19:10:55 UTC
The current support apparently has its glitches but above all it has nothing to do with gcc itself; it consists of using an existing `as` option to "Use  the  clang(1) integrated assembler instead of the GNU based system assembler". That's apparently the default for `as` so I don't understand why it doesn't invoke clang when used through gcc.

> So, what is the correct configure option to let gcc use it by default?

Write a wrapper script that just prepends or appends `-q` to the arguments and then calls the actual `as` command, and use that wrapper with the `--with-as` option? Crossing fingers that GCC itself will build...

What I had in mind was calling `clang -cc1as` or even `llvm-as` directly, with the proper arguments. That ought to give better control over the generated object code than relying on a 3rd party (Apple) to implement the GNU -> clang argument translation.
Comment 5 René J.V. Bertin 2017-05-17 09:01:29 UTC
(In reply to René J.V. Bertin from comment #4)

> Write a wrapper script that just prepends or appends `-q` to the arguments
> and then calls the actual `as` command, and use that wrapper with the
> `--with-as` option? Crossing fingers that GCC itself will build...

I tested that yesterday evening using a very simple wrapper that prepends `-q` to the arguments and then execs `as`. Clearly `as -q` does a better job in translating the commandline arguments to clang-lingo than my wrapper script did (and fortunately so, I dare say). The build completed fine, and is functional - on Mac OS X 10.9.5 and `as` configured to invoke clang 4.0 .

I'm thus reopening this ticket. It is NOT a duplicate of the aforementioned bug report.

I cannot edit the original description but it should be reworded/completed to include something like the following:

It would be useful if GCC could be configured to include platform-specific arguments for the default assembler, in this case `-q`. Setting up that assembler correctly so that it works properly when invoked by GCC is an independent responsibility that falls to the installing user, not GCC.
Comment 6 Jonathan Wakely 2017-05-17 09:36:27 UTC
(In reply to René J.V. Bertin from comment #4)
> Write a wrapper script that just prepends or appends `-q` to the arguments
> and then calls the actual `as` command, and use that wrapper with the
> `--with-as` option? Crossing fingers that GCC itself will build...

I assume something like --with-as=llvm-as doesn't work. It would require configure to know how to detect the llvm assembler and know how to invoke it correctly.
 
> What I had in mind was calling `clang -cc1as` or even `llvm-as` directly,
> with the proper arguments. That ought to give better control over the
> generated object code than relying on a 3rd party (Apple) to implement the
> GNU -> clang argument translation.

If Apple's gas already understands the llvm assembler options then leveraging that seems sensible. So all that would be needed is a way to configure GCC to always use -Wa,-q
Comment 7 René J.V. Bertin 2017-05-17 17:12:01 UTC
(In reply to Jonathan Wakely from comment #6)

> I assume something like --with-as=llvm-as doesn't work.

Nope.

> It would require
> configure to know how to detect the llvm assembler and know how to invoke it
> correctly.

The latter is the bigger problem, and not for configure to solve but for the compiler driver.

> If Apple's gas already understands the llvm assembler options then
> leveraging that seems sensible. So all that would be needed is a way to
> configure GCC to always use -Wa,-q

Indeed. As I said in my previous comment:
"It would be useful if GCC could be configured to include platform-specific arguments for the default assembler, in this case `-q`."

I presume that --with-as="/path/to/as -q" would try to execute an executable called "as -q" but haven't tried.
Comment 8 Andrew Pinski 2017-05-17 17:17:47 UTC
This should be easy to do as a target specific specs.  There should be already one which is used for arguments to as.

From config/darwin.h:

 410 /* When we detect that we're cctools or llvm as, we need to insert the right
 411    additional options.  */
 412 #if HAVE_GNU_AS
 413 #define ASM_OPTIONS ""
 414 #else
 415 #define ASM_OPTIONS "%{v} %{w:-W} %{I*}"
 416 #endif
 417 
 418 /* Default Darwin ASM_SPEC, very simple. */
 419 #define ASM_SPEC "-arch %(darwin_arch) \
 420   " ASM_OPTIONS " \
 421   %{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} \
 422   %{static}" ASM_MMACOSX_VERSION_MIN_SPEC

This was added with:
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=aaa50706381cfe490cbc7de0f3ec64c76448aaf4
Comment 9 Andrew Pinski 2017-05-17 17:19:33 UTC
(In reply to René J.V. Bertin from comment #7)
> (In reply to Jonathan Wakely from comment #6)
> 
> > I assume something like --with-as=llvm-as doesn't work.
> 
> Nope.

What GCC version did you try?  6.x or 7.x?  There seems to be code to support llvm-as in GCC 7.1.0 as shown in comment #8.
Comment 10 Dominique d'Humieres 2017-05-17 17:29:53 UTC
AFAICT clang-as is available with recent Xcode (8, but probably also 7):

% as -v
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.6.0

The old gnu as can be used with the -Q option

% as -Q -v
Apple Inc version cctools-898, GNU assembler version 1.38
Comment 11 René J.V. Bertin 2017-05-17 21:45:34 UTC
I'm using 6.3.0 (that was the latest release when I started). It has the same code in config/darwin.h though:

```
/* When we detect that we're cctools or llvm as, we need to insert the right
   additional options.  */
#if HAVE_GNU_AS
#define ASM_OPTIONS ""
#else
#define ASM_OPTIONS "%{v} %{w:-W} %{I*}"
#endif

/* Default Darwin ASM_SPEC, very simple. */
#define ASM_SPEC "-arch %(darwin_arch) \
  " ASM_OPTIONS " \
  %{Zforce_cpusubtype_ALL:-force_cpusubtype_ALL} \
  %{static}" ASM_MMACOSX_VERSION_MIN_SPEC
```

I take it that the -q option would be added to the 1st (empty) ASM_OPTIONS declaration?

On my older 10.9.5 with Xcode 6.x I have

%  xcrun -run as -v
Apple Inc version cctools-862, GNU assembler version 1.38
% xcrun -run as -v -q
Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)

and from MacPorts:

% /opt/local/bin/as -v 
Apple Inc version cctools-895, GNU assembler version 1.38
% /opt/local/bin/as -v -q
clang version 4.0.0 (tags/RELEASE_400/final)

I haven't yet figured out why the latter defaults to GNU as despite what its manpage says, but it seems clear that one cannot take anything for granted as to -q being the actual default.

In fact, is there code that requires the old GNU as?
Comment 12 Iain Sandoe 2019-03-24 13:55:28 UTC
AFAIK the use of the clang assembler (i.e. calling cctools as which then spawns clang -cc1as) is working on all open branches (and on the closed 6.5).

please could you be more specific about exactly what's not working?
 - i.e if you're on an older version of the OS.
 - version of Xcode.

Note that the default for which assembler backend is called does depend on the Xcode version.
Comment 13 Eric Gallager 2019-04-01 07:18:11 UTC
(In reply to Iain Sandoe from comment #12)
> AFAIK the use of the clang assembler (i.e. calling cctools as which then
> spawns clang -cc1as) is working on all open branches (and on the closed 6.5).
> 
> please could you be more specific about exactly what's not working?
>  - i.e if you're on an older version of the OS.
>  - version of Xcode.
> 
> Note that the default for which assembler backend is called does depend on
> the Xcode version.

This is probably material for a separate bug, but the MacPorts package for GCC 8 uses the clang assembler from the clang-3.4 port on my system, and apparently all includes flags get passed to it, so it prints out all sorts of messages like:

clang: warning: argument unused during compilation: '-I .'

when compiling with it. The driver specs might need to be hacked to stop passing '-I' flags to the assembler that it won't use. Currently I'm working around it by prefixing all '-I' flags with '-Wp,' so that only the preprocessor sees them, but that doesn't work for other tools (e.g. splint) that accept '-I' flags but not '-Wp,' flags. It also breaks fortran-style includes in gfortran since apparently they're different from the kind seen in the C preprocessor.
Comment 14 Eric Gallager 2019-07-01 04:45:55 UTC
(In reply to Eric Gallager from comment #13)
> (In reply to Iain Sandoe from comment #12)
> > AFAIK the use of the clang assembler (i.e. calling cctools as which then
> > spawns clang -cc1as) is working on all open branches (and on the closed 6.5).
> > 
> > please could you be more specific about exactly what's not working?
> >  - i.e if you're on an older version of the OS.
> >  - version of Xcode.
> > 
> > Note that the default for which assembler backend is called does depend on
> > the Xcode version.
> 
> This is probably material for a separate bug, but the MacPorts package for
> GCC 8 uses the clang assembler from the clang-3.4 port on my system, and
> apparently all includes flags get passed to it, so it prints out all sorts
> of messages like:
> 
> clang: warning: argument unused during compilation: '-I .'
> 
> when compiling with it. The driver specs might need to be hacked to stop
> passing '-I' flags to the assembler that it won't use. Currently I'm working
> around it by prefixing all '-I' flags with '-Wp,' so that only the
> preprocessor sees them, but that doesn't work for other tools (e.g. splint)
> that accept '-I' flags but not '-Wp,' flags. It also breaks fortran-style
> includes in gfortran since apparently they're different from the kind seen
> in the C preprocessor.

Note that these excess warnings cause so many testsuite fails that the resulting log becomes too big to mail to the gcc-testresults mailing list. (3.4MB!)
Comment 15 Eric Gallager 2022-05-24 15:05:59 UTC
(In reply to Iain Sandoe from comment #12)
> please could you be more specific about exactly what's not working?
>  - i.e if you're on an older version of the OS.
>  - version of Xcode.

So I'm assuming that this is the part that this is still in WAITING for?
Comment 16 Iain Sandoe 2022-05-24 15:35:29 UTC
(In reply to Eric Gallager from comment #15)
> (In reply to Iain Sandoe from comment #12)
> > please could you be more specific about exactly what's not working?
> >  - i.e if you're on an older version of the OS.
> >  - version of Xcode.
> 
> So I'm assuming that this is the part that this is still in WAITING for?

I guess so...

cctools 'as' already automatically calls 'clang -cc1as' where the system supports it and GCC's configuration process detects that this is in force (where it matters to assembler options).

... so we are already using this on the platform versions for which Apple defaults to using the LLVM back end (i.e. clang -cc1as) for the assembler.

For some versions of Xcode (before this became the default) it would be possible modify the configure to add the '-q' flag to force the use of 'clang -cc1as' instead of the GAS-1.38 based assembler - however, at that point we would clearly be making it possible to generate instructions that the OS toolchain was not expecting, so not sure of how useful it would be.

from the original description:

> As a result, GCC generates code that fails to assemble when using optimisation for >any CPU that has support for AVX or newer intrinsics. A pity and often annoying >because the failure can happen only late during a build process.

We should not be trying to generate such instructions on systems that do not support them - so this implies some different issue is in play.