The clang compiler does not support a feature it reportedly supports - clang

I'm trying to tailor compiler flags of clang-11 to the apple-m1 CPU, which clang-11 doesn't know about yet.
The output of /usr/bin/clang -E - -mcpu=apple-m1 -### on macOS outputs a command with flags like these in it: "-target-feature" "+zcz"
From that you can infer the following features of the CPU:
armv8.5a+fp-armv8+neon+crc+crypto+dotprod+fp16fml+ras+lse+rdm+rcpc+zcm+zcz+fullfp16+sm4+sha3+sha2+aes
However, out of these, +fp-armv8+neon+zcm+zcz+fullfp16 are not recognised to be valid by any clang compiler:
$ cc -march=armv8.5a+zcz test.c
clang-11: error: the clang compiler does not support '-march=armv8.5a+zcz'
How can I tell clang to optimise for those target flags?

Related

Using llvm linker (lld) with mingw

I would like to have complete Win32 development toolchain without Microsoft SDKs. mingw64 works, but its linker is very slow. As an alternative, I am trying to use clang for windows. I can get clang 7.0.1 (but not 8.0.0) work with mingw headers/libraries, however only using mingw's ld.exe. If I force ldd.exe to be used (-fuse-ld=lld), everything compiles and links fine, but the application immediately crashes when started. Is there anything I can do here, like change something in the commandline?
This is how commandline and --verbose for the link step looks like:
Linking...
clang++ -static -o "C:\upp\out\MyApps\CLANG.Debug.Debug_Full\main.exe"
-ggdb -L"C:\upp\bin/mingw64/64/x86_64-w64-mingw32/lib"
-L"C:\uppbin/mingw64/64/opt/lib" -L"C:\upp\bin/SDL2/lib/x64"
-L"C:\upp\bin/pgsql/x64/bin"
-L"C:\upp\bin/mysql/lib64"
-Wl,--stack,20000000 --verbose -target x86_64-pc-windows-gnu
-fuse-ld=lld
"C:/upp/out/MyApps/main/CLANG.Debug.Debug_Full.Main\main.o"
-Wl,--start-group -Wl,--end-group
clang version 7.0.1 (tags/RELEASE_701/final)
Target: x86_64-pc-windows-gnu
Thread model: posix
InstalledDir: C:\xxx\LLVM2\bin
"C:\\xxx\\LLVM2\\bin\\ld.lld" -m i386pep -Bstatic
-o "C:\\upp\\out\\MyApps\\CLANG.Debug.Debug_Full\\main.exe"
"C:\\upp\\bin\\mingw64\\64\\x86_64-w64-mingw32\\lib\\crt2.o"
"C:\\upp\\bin\\mingw64\\64\\lib\\gcc\\x86_64-w64-mingw32\\8.1.0\\crtbegin.o"
"-LC:\\upp\\bin/mingw64/64/x86_64-w64-mingw32/lib"
"-LC:\\upp\\bin/mingw64/64/opt/lib"
"-LC:\\upp\\bin/SDL2/lib/x64" "-LC:\\upp\\bin/pgsql/x64/bin"
"-LC:\\upp\\bin/mysql/lib64"
"-LC:\\upp\\bin\\mingw64\\64\\lib\\gcc\\x86_64-w64-mingw32\\8.1.0"
"-LC:\\upp\\bin\\mingw64\\64\\x86_64-w64-mingw32\\lib"
"-LC:\\upp\\bin\\mingw64\\64\\lib"
"-LC:\\upp\\bin\\mingw64\\64\\x86_64-w64-mingw32/sys-root/mingw/lib"
--stack 20000000
"C:/upp/out/MyApps/main/CLANG.Debug.Debug_Full.Main\\main.o"
--start-group --end-group -lstdc++ --start-group -lmingw32
-lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt -ladvapi32 -lshell32
-luser32 -lkernel32 --end-group
"C:\\upp\\bin\\mingw64\\64\\lib\\gcc\\x86_64-w64-mingw32\\8.1.0\\crtend.o"
The llvm-mingw toolchain is very easy to use and provides latest clang / libc++ / lld without any dependency on the Microsoft headers: https://github.com/mstorsjo/llvm-mingw
It links against the Microsoft ucrt and as such is compatible with MSVC-built DLLs (for the C API / ABI, not the C++ since it uses a different standard library implementation)

Qbs does not pick Clang in the tool chain configuration

I have installed LLVM 5.0 on Windows 10 x64. When I call clang++ --version from cmd the message below is displayed.
clang version 5.0.0 (tags/RELEASE_500/final)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\LLVM\bin
But when I call qbs setup-toolchains --detect in the resulting list neither clang nor clang++ is in. If I call qbs config --list profiles both clang and clang++ are not in the list. Am I missing something?
On Windows, the --detect option only looks for MSVC and mingw installations. Use the explicit mode instead:
qbs setup-toolchains C:\LLVM\bin\clang.exe clang

clang-3.8 and compiler-rt vs libgcc

I have been using clang-3.5 to happily build bitcode versions of musl libc and
use the result to produce nice stand alone executables.
Recent attempts with clang-3.8 have not been so happy. It seems that
the bitcode clang-3.8 generates uses functions defined in
compiler-rt/lib/builtins
Typical examples of functions I find polluting the bitcode are mulxc3, mulsc3, and muldc3. I can solve this by linking against libgcc, or even the llvm alternative if I had any clear idea of what that was. Though I would rather prevent the problem from happening in the first place.
I have seen mention of flags like rtlib=compiler-rt etc, but have found precious little documentation on the subject.
So here are some simple questions.
Is it possible to prevent clang from using the compiler-rt/lib/builtins
in the emitted bitcode? Or if not
Does llvm produce a version of libgcc that I could use. Actually I would
probably build a bitcode version of it, but that is besides the point.
Love to hear some guidance on this.
Added 12/8/2016: So I will illustrate my issues with a particular workflow that
people can reproduce if they wish, or, more likely, just point out where I am being stupid.
So start by checking out:
musllv
and follow the instructions in the README.to compile (here I am using clang-3.8 on ubuntu 14.04)
WLLVM_CONFIGURE_ONLY=1 CC=wllvm ./configure --target=LLVM --build=LLVM
make
cd lib
extract-bc -b libc.a
you will also need the bitcode of a simple executable. I will use nweb.c here.
wllvm nweb.c -o nweb
extract-bc nweb
Now we can do things like:
clang -static -nostdlib nweb.bc libc.a.bc crt1.o libc.a -o nweb
This workflow goes smoothly for clang-3.5 but for clang-3.8 we get:
clang -static -nostdlib nweb.bc libc.a.bc crt1.o libc.a -o nweb
/tmp/libc-f734a3.o: In function `cpowl':
libc.a.bc:(.text+0xbb9a): undefined reference to `__mulxc3'
/tmp/libc-f734a3.o: In function `cpowf':
libc.a.bc:(.text+0x38f7d): undefined reference to `__mulsc3'
/tmp/libc-f734a3.o: In function `csqrt':
libc.a.bc:(.text+0x78fc3): undefined reference to `__muldc3'
/tmp/libc-f734a3.o: In function `cpow':
libc.a.bc:(.text+0xafafc): undefined reference to `__muldc3'
clang-3.8: error: linker command failed with exit code 1 (use -v to seeinvocation)
So as #paul-brannan points out we could try
clang -static -nostdlib --rtlib=compiler-rt nweb.bc libc.a.bc crt1.o libc.a -o nweb
But this is where I am probably being stupid, because I get:
clang-3.8: warning: argument unused during compilation: '--rtlib=compiler-rt'
irregardless of whether I use it as a linking or compiling flag.
OK so I finally managed to make headway on this. I built llvm-3.8.1 together with the compiler-rt project using wllvm and wllvm++.
One of the build products was libclang_rt.builtins-x86_64.a,
and from this archive I was able to extract the bitcode module
libclang_rt.builtins-x86_64.bc
using the command:
extract-bc -b libclang_rt.builtins-x86_64.a
This bitcode module has definitions for those pesky instrinsics like
__mulxc3, __mulsc3, and __muldc3.
Hallelujah!

clang: cancel effect of the -x option for subsequent files

clang has an option, -x, which can be used to specify the language of subsequent source files passed to it. This caused problems when used like this:
clang -x c++ one.cc a.o b.o c.o
clang will try to interpret the object files a.o, b.o, c.o as source code.
Is there a way to cancel the effect of the -x option so I can pass object files on the same command line?
clang -x c++ one.cc SOMEOPTION a.o b.o c.o
What should SOMEOPTION be to allow clang to interpret the .o files as object files?
I need to use this convoluted command line because I am using a system that calls the compiler automatically to compile some code it generates and there are limits to how much it can be hacked.
could you put the arguments the other way 'round
clang a.o b.o c.o -x c++ one.cc
or compile each file and then link them in a later run
clang -x c++ one.cc -o one.cc.o
clang a.o b.o c.o one.cc.o
This is how in my experience it is actualy used.

Rebar: Cross Compilation Options

I'm trying use rebar to generate a 32-bit arch release on 64-bit arch system. It's unclear to me how I need to modify an application's rebar.config to be able to do this.
I have taken a look at the rebar source to see how they are detecting my environment: rebar_utils.erl gets the architecture as "x86_64-unknown-linux-gnu" and this is set in rebar_port_compiler as the "default_env". I'm wondering how I can get rebar to compile for another target architecture.
I have tried the following port_env options
{port_env, [{"CFLAGS", "$CFLAGS -fPIC -m32"},{"LDFLAGS", "-arch i386"}]}.
With those options (and a 32-bit Erlang installation in my path), when I run rebar get-deps compile my dependencies are still being built as 64-bit and thus ld skips over my 32-bit libraries (and ultimately fails because it cant find a 64-bit implementation)
/usr/bin/ld: skipping incompatible <PATH TO 32-bit erlang install>/lib/erlang/lib/erl_interface-3.7.14/lib/liberl_interface.a when searching for -lerl_interface
/usr/bin/ld: cannot find -lerl_interface
collect2: ld returned 1 exit status
ERROR: sh(cc c_src/epam.o $LDFLAGS -shared -L"<PATH TO 32-bit erlang install>/lib/erlang/lib/erl_interface-3.7.14/lib" -lerl_interface -lei -o priv/lib/epam.so)
What do I need to do to force my dependencies to compile as 32 bit? My attempt here isn't working.
The port_env settings in rebar.config can make use of the ERLANG_ARCH environment variable to determine whether the Erlang runtime was built for a 32- or 64-bit system. For example, the following port_env definition sets either -m32 or -m64 as appropriate for the C compiler for the x86_64, i686, and i386 chip architectures:
{port_env, [{"x86_64", "CFLAGS", "$CFLAGS -m$ERLANG_ARCH"},
{"i[36]86", "CFLAGS", "$CFLAGS -m$ERLANG_ARCH"}]}.
The first string in each tuple is a regular expression matched against the system architecture string of the Erlang runtime as returned by the erlang:system_info(system_architecture) function. In this example, the additional -m$ERLANG_ARCH option is added only when the regular expression matches, and all other architectures get the default CFLAGS setting.

Resources