gcc 11.3.0 on macOS/Apple Silicon and SHA-3 instructions - macos

I have gcc 11.3.0 installed using Homebrew on a MacBook Air with Apple Silicon M1 CPU. The binary is the aarch64 native version, not Rosetta emulated. The installed OS is macOS Monterey 12.3.
I'm having an issue compiling a program which uses the ARMv8.2-A SHA-3 extension instructions, which are supported by the M1 CPU. This is a minimal reproducible example:
#include <arm_neon.h>
int main() {
uint64x2_t a = {0}, b = {0}, c = {0};
veor3q_u64(a, b, c);
return 0;
}
This code compiles just fine with the Apple supplied clang compiler.
I compiled it using the following command line for gcc 11:
gcc-11 -o test test.c -march=armv8-a+sha3
This results in the following error:
In file included from test.c:1:
test.c: In function 'main':
/opt/homebrew/Cellar/gcc/11.3.0/lib/gcc/11/gcc/aarch64-apple-darwin21/11/include/arm_neon.h:32320:1: error: inlining failed in call to 'always_inline' 'veor3q_u64': target specific option mismatch
32320 | veor3q_u64 (uint64x2_t __a, uint64x2_t __b, uint64x2_t __c)
| ^~~~~~~~~~
test.c:5:5: note: called from here
5 | veor3q_u64(a, b, c);
| ^~~~~~~~~~~~~~~~~~~
Is this a bug in this particular hardware/software combination, or is there some command-line option I can pass to gcc to make this particular program compile?

Solved the problem. It turns out that gcc requires -march=armv8.2-a+sha3 rather than just -march=armv8-a+sha3 to compile this intrinsic. Indeed, in gcc's version of arm_neon.h, one can find this right before the block of intrinsics which includes veor3q_u64:
#pragma GCC target ("arch=armv8.2-a+sha3")

Related

Compiling code with gcc on macOS Monterey 12.5.1 results in clang error

I am compiling C++, Fortran, and OpenMPI code using Homebrew installed packages. I also use the make (GNU Make 4.3) and cmake (3.24.1) packages installed with Homebrew.
I compile the test programs as follows:
### C++ ###
int main (int argc, char** argv)
{
int x=2;
return 0;
}
$ g++ test.cc
> clang: error: invalid version number in '-mmacosx-version-min=12.5'
### Fortran ###
program hello
print *, "Hello, world!"
end program hello
$ gfortran test.f90
> clang: error: invalid version number in '-mmacosx-version-min=12.5'
I get a clang error: clang: error: invalid version number in '-mmacosx-version-min=12.5' when using gcc-12 and gfortran-12. The version number requirement in the above error changes depending on the gcc version installed. For example, gcc-10 and gcc-11 result in clang: error: invalid version number in '-mmacosx-version-min=12.0'.
What's interesting is that the error invoked is coming from Apple clang even though I am not using it for compiling any of the programs.
Some relevant specs:
macOS Monterey 12.5.1
xcode-select version 2395
xcode-select path: /Library/Developer/CommandLineTools
$ /usr/bin/clang --version
Apple clang version 13.1.6 (clang-1316.0.21.2.5)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Update: I now installed gfortran using the intel standalone installer here, I still get the same error.
Someone who seem to have had the same problem:
Found solution: reinstalling the Command Line Tools and exporting SYSTEM_VERSION_COMPAT=1 worked for me. Another possible solution could be to force the compilation to occur through GCC only, but this is not something I tried.
note: compilation was performed without including MPI software.
note2: pkg-config had to be installed as an extra dependency, but this was probably required by CMake.
https://groups.google.com/g/hande-user/c/dtGvyFTJFWE

Strange error message for isprint() using arm-none-eabi-gcc

I have the following code:
#include <ctype.h>
void myfn(void)
{
uint8_t any0 = 'c';
char any1 = 'c';
if (isprint(any0))
{
return;
}
if (isprint(any1))
{
return;
}
}
When I compile it with gcc for arm, I get the following error:
error: array subscript has type 'char' [-Werror=char-subscripts]
if (isprint(any1))
^
If I pass an unit8_t to isprint, the compiler is happy, but not if I pass it a char.
The prototype for isprint is:
int isprint(int c);
It expects an int as parameter, I give it a char.
I would expect it to complain about the type of the parameter, but not something unrelated as 'array subscript'.
The error goes away if I change the call to:
if (isprint((uint8_t)any1))
Is there something I have overlooked?
The compiler I use is:
GNU C (15:4.9.3+svn231177-1) version 4.9.3 20150529 (prerelease) (arm-none-eabi)
compiled by GNU C version 5.2.1 20151129, GMP version 6.1.0, MPFR version 3.1.3, MPC version 1.0.3
warning: MPFR header version 3.1.3 differs from library version 3.1.4.
Commandline options:
'-v' '-fshort-enums' '-specs=nosys.specs' '-specs=nano.specs'
'-mfloat-abi=soft' '-save-temps' '-Werror' '-Wpedantic' '-pedantic-errors' '-mthumb' '-fno-builtin' '-mcpu=cortex-m0' '-Wall' '-std=gnu99' '-ffunction-sections'
'-fdata-sections' '-fomit-frame-pointer' '-mabi=aapcs' '-fno-unroll-loops' '-ffast-math' '-ftree-vectorize' '-Og' '-g'
If I compile the same code with the gcc compiler for AVR /usr/bin/avr-gcc (using similar commandline options and I intentionally added option -Werror=char-subscripts), it doesn't complain about isprint. So it seems to be something related to the ARM compiler.
It turned out that the implementation of isprint for ARM is a macro and, more importantly, header file ctype.h contains the following comment:
These macros are intentionally written in a manner that will trigger
a gcc -Wall warning if the user mistakenly passes a 'char' instead of
an int containing an 'unsigned char'.
For AVR, header file ctype.h contains:
extern int isprint(int __c) __ATTR_CONST__;
This explains the difference in behaviour when compiling for AVR or for ARM.

Enable OpenMP support in clang in Mac OS X (sierra & Mojave)

I am using Mac OS X Sierra, and I found that clang (LLVM version 8.1.0 (clang-802.0.38)) does not support OpenMP:
when I run clang -fopenmp program_name.c, I got the following error:
clang: error: unsupported option '-fopenmp'
It seems that clang does not support -fopenmp flag.
I could not find any openmp library in homebrew. According to LLVM website, LLVM already supports OpenMP. But I could not find a way to enable it during compiling.
Does this mean that the default clang in Mac does not support OpenMP?
Could you provide any suggestions?
(When I switch to GCC to compile the same program (gcc is installed using brew install gcc --without-multilib), and the compilation is successful.)
Try using Homebrew's llvm:
brew install llvm
You then have all the llvm binaries in /usr/local/opt/llvm/bin.
Compile the OpenMP Hello World program. Put omp_hello.c
/******************************************************************************
* FILE: omp_hello.c
* DESCRIPTION:
* OpenMP Example - Hello World - C/C++ Version
* In this simple example, the master thread forks a parallel region.
* All threads in the team obtain their unique thread number and print it.
* The master thread only prints the total number of threads. Two OpenMP
* library routines are used to obtain the number of threads and each
* thread's number.
* AUTHOR: Blaise Barney 5/99
* LAST REVISED: 04/06/05
******************************************************************************/
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
int nthreads, tid;
/* Fork a team of threads giving them their own copies of variables */
#pragma omp parallel private(nthreads, tid)
{
/* Obtain thread number */
tid = omp_get_thread_num();
printf("Hello World from thread = %d\n", tid);
/* Only master thread does this */
if (tid == 0)
{
nthreads = omp_get_num_threads();
printf("Number of threads = %d\n", nthreads);
}
} /* All threads join master thread and disband */
}
in a file and use:
/usr/local/opt/llvm/bin/clang -fopenmp -L/usr/local/opt/llvm/lib omp_hello.c -o hello
You might also have to set the CPPFLAGS with -I/usr/local/opt/llvm/include.
The makefile should look like this:
CPP = /usr/local/opt/llvm/bin/clang
CPPFLAGS = -I/usr/local/opt/llvm/include -fopenmp
LDFLAGS = -L/usr/local/opt/llvm/lib
omp_hello: omp_hello.c
$(CPP) $(CPPFLAGS) $^ -o $# $(LDFLAGS)
Update
In macOS 10.14 (Mojave) you might get an error like
/usr/local/Cellar/llvm/7.0.1/lib/clang/7.0.1/include/omp.h:118:13: fatal error: 'stdlib.h' file not found
If this happens, the macOS SDK headers are missing from /usr/include. They moved into the SDK itself with Xcode 10. Install the headers into /usr/include with
open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
Other people have given one solution (using Homebrew llvm). You can also use OpenMP with Apple Clang and Homebrew libomp (brew install libomp). Just replace a command like clang -fopenmp test.c with clang -Xpreprocessor -fopenmp test.c -lomp.
MacOS Mojave with CMake
Install LLVM with openmp and libomp with brew
brew update
brew install llvm libomp
add include directories and link directories in CMakeList.txt
include_directories("/usr/local/include" "/usr/local/opt/llvm/include")
link_directories("/usr/local/lib" "/usr/local/opt/llvm/lib")
run CMake with the new compilers
cmake -DCMAKE_C_COMPILER="/usr/local/opt/llvm/bin/clang" -DCMAKE_CXX_COMPILER="/usr/local/opt/llvm/bin/clang++" ..
The clang version is 7.0.1 at time of writing
Conda-Based Compilation Environment
Conda uses clang for OSX compilation (umbrella package cxx-compiler), but I hit similar issues with using llvm-openmp and the -fopenmp flag throwing errors. Solution is rather similar to other answers, but I am including here in case others have more exactly this issue.
Specific solution was to include the Conda environment's include/ directory in the CFLAGS, namely:
CFLAGS="-I${CONDA_PREFIX}/include"
Note, I also needed to add -lstdc++ -Wl,-rpath ${CONDA_PREFIX}/lib -L${CONDA_PREFIX}/lib when linking, similar to this GitHub Issue.

c++ thread-local storage clang-503.0.40 (Mac OSX)

After I declared a variable in this way:
#include <thread>
namespace thread_space
{
thread_local int s;
} //etc.
i tried to compile my code using 'g++ -std=c++0x -pthread [sourcefile]'. I get the following error:
example.C:6:8: error: thread-local storage is unsupported for the current target
static thread_local int s;
^
1 error generated.
If i try to compile the same code on Linux with GCC 4.8.1 whit the same flags, i get a functioning executable file. I'm using clang-503.0.40 (the one which comes with Xcode 5.1.1) on a MacBook Pro running OSX 10.9.3. Can anybody explain me what i'm doing wrong?
Thank you!!
Try clang++ -stdlib=libc++ -std=c++11. OS X's outdated libstdc++ doesn't support TLS.
Edit
Ok, this works for the normal clang version but not for the Xcode one.
I did a diff against Apple's clang (503.0.38) and the normal released one and found the following difference:
.Case("cxx_thread_local",
- LangOpts.CPlusPlus11 && PP.getTargetInfo().isTLSSupported() &&
- !PP.getTargetInfo().getTriple().isOSDarwin())
+ LangOpts.CPlusPlus11 && PP.getTargetInfo().isTLSSupported())
So I think this is a bug in Apple's clang version (or they kept it in there on purpose - but still weird, because -v says based on 3.4).
Alternatively, you can use compiler extensions such as __thread (GCC/Clang) or __declspec(thread) (Visual Studio).
Wrap it in a macro and you can easily port your code across different compilers and language versions:
#if HAS_CXX11_THREAD_LOCAL
#define ATTRIBUTE_TLS thread_local
#elif defined (__GNUC__)
#define ATTRIBUTE_TLS __thread
#elif defined (_MSC_VER)
#define ATTRIBUTE_TLS __declspec(thread)
#else // !C++11 && !__GNUC__ && !_MSC_VER
#error "Define a thread local storage qualifier for your compiler/platform!"
#endif
...
ATTRIBUTE_TLS static unsigned int tls_int;
The clang compiler included in the Xcode 8 Beta and GM releases supports the C++11 thread_local keyword with both -std=c++11 and -std=c++14 (as well as the GCC variants).
Earlier versions of Xcode apparently supported C-style thread local storage using the keywords __thread or _Thread_local, according to the WWDC 2016 video "What's New in LLVM" (see the discussion beginning at 5:50).
Seems like you might need to set the minimum OS X version you target to 10.7 or higher.

EXEC_BAD_ACCESS in MLPACK library with -std=c++11

I have encounter EXEC_BAD_ACCESS error in my local environment (Mac OS X 10.9.2, boost 1.55.0, mlpack 1.0.8, llvm 5.1 clang-503.0.38), and I have narrowed down the error in a very simple snippet:
#include "mlpack/methods/range_search/range_search.hpp"
int main(int argc, const char *argv[])
{
return 0;
}
The g++ version is
iMac:build dongli$ g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
and compile the snippet by
g++ -std=c++11 main.cpp -o main -lmlpack -I/usr/include/libxml2
(you may change to your case)
Run main in terminal will give you
iMac:build dongli$ ./main
Bus error: 10
and run it in lldb will give you more information
iMac:build dongli$ lldb ./main
Current executable set to './main' (x86_64).
(lldb) r
Process 79449 launched: './main' (x86_64)
Process 79449 stopped
* thread #1: tid = 0xb4a75, 0x00000001000500eb libmlpack.1.0.dylib`long double boost::math::lanczos::lanczos17m64::lanczos_sum<long double>(long double const&) + 59, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x100001d80)
frame #0: 0x00000001000500eb libmlpack.1.0.dylib`long double boost::math::lanczos::lanczos17m64::lanczos_sum<long double>(long double const&) + 59
libmlpack.1.0.dylib`long double boost::math::lanczos::lanczos17m64::lanczos_sum<long double>(long double const&) + 59:
-> 0x1000500eb: fstpt (%rax)
0x1000500ed: fldt 0x26c8d(%rip) ; .memset_pattern99 + 1296
0x1000500f3: fstpt 0x10(%rax)
0x1000500f6: fldt 0x26c94(%rip) ; .memset_pattern99 + 1312
As you can see, it point me to boost::math::lanczos::lanczos17m64::lanczos_sum, but I have no idea what is the problem.
But when -std=c++11 is absent, no error occurs. I also tried to reinstall boost with --c++11 by homebrew.
Thanks in advance!
EDIT:
I have only installed one boost:
iMac:~ dongli$ ls /usr/local/Cellar/boost/
1.55.0
with command:
brew install boost --c++11
You could
check that the actual shared library file is marked executable and is accessible to the user that runs the application?
It that isn't it, this probably means that at runtime you find a conflicting version of the library. Fix/override the runtime library path, or compile against the same version of the library if so
After I removed all the C++11 features from my codes (e.g., initializer_list and default template argument), and removed the -std=c++11 option, the error is gone. I think I have installed boost, mlpack with -std=c++11 by using homebrew, but the error persisted, so my experience is not use the new features if they are not necessary.

Resources