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: 2019-07-01 04:45 UTC (History)
2 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!)