flang-compiler / flang

Flang is a Fortran language front-end designed for integration with LLVM.
Other
804 stars 136 forks source link

Linking CXX shared library libpgmath.dylib fails on macOS #780

Open jwhowarth opened 5 years ago

jwhowarth commented 5 years ago

Current flang git fails to link libpgmath.dylib on macOS with the following undefined symbols...

[100%] Linking CXX shared library libpgmath.dylib Undefined symbols for architecture x86_64: "_mth_i_dceil", referenced from: _mth_intrins_defs in dispatch.c.o fptr2name in dispatch.c.o (maybe you meant: mth_i_dceil_sse) "_mth_i_dfloor", referenced from: _mth_intrins_defs in dispatch.c.o fptr2name in dispatch.c.o (maybe you meant: mth_i_dfloor_sse) "_mth_i_floor", referenced from: _mth_intrins_defs in dispatch.c.o fptr2name in dispatch.c.o (maybe you meant: mth_i_floor_sse) ld: symbol(s) not found for architecture x86_64 clang-7: error: linker command failed with exit code 1 (use -v to see invocation) make[2]: [lib/libpgmath.dylib] Error 1 make[1]: [lib/CMakeFiles/pgmath.dir/all] Error 2 make: *** [all] Error 2

jwhowarth commented 5 years ago

The same linkage failure occurs whether the build-llvm.sh and build-flang-driver.sh uses LLVM clang 5.0.2 or Xcode 10.2's Apple Clang on Mojave to build the clang compiler used in build-flang.sh.

jwhowarth commented 5 years ago

Just to be clear, this is on a MacPro 2008 so it only has SSE 4,1 support.

d-parks commented 5 years ago

Would you be able to upload your build log of libpgmath?

jwhowarth commented 5 years ago

Do I need to enable some additional verbosity in build-flang.sh? Currently it only shows the progress lines as well as warnings and errors.

jwhowarth commented 5 years ago

Comparing a Ubuntu Linux build of Flang git, I see that...

nm ./common/CMakeFiles/common.dir/dceil.c.o | grep mth_i_dceil

shows a defined symbol for _mth_idceil whereas the same file in the macOS clang based build shows a defined symbol for mth_i_dceil_sse instead.

jwhowarth commented 5 years ago

The build of dceil.c.o on macOS appears as...

[ 70%] Building C object lib/common/CMakeFiles/common.dir/dceil.c.o cd /Users/howarth/flang_dir/flang/runtime/libpgmath/build/lib/common && /Users/howarth/flang_dir/install/bin/clang -DHOST_OSX -DMAXCPUS=256 -DMAXCPUSL=8 -DMAXCPUSR=4 -DOSX -DOSX86 -DOSX8664 -DPG_PIC -DTARGET_OSX -DTARGET_OSX_X86 -DTARGET_OSX_X8664 -DTARGET_X86 -DTARGET_X8664 -D__gnu_osx__ -I/Users/howarth/flang_dir/flang/runtime/libpgmath/lib/common -I/Users/howarth/flang_dir/flang/runtime/libpgmath/lib/x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -fPIC -m64 -O3 -fomit-frame-pointer -o CMakeFiles/common.dir/dceil.c.o -c /Users/howarth/flang_dir/flang/runtime/libpgmath/lib/common/dceil.c

jwhowarth commented 5 years ago

The same situation exists for ./lib/common/CMakeFiles/common.dir/dfloor.c.o which contains a symbol for _mth_i_dfloorsse on the macOS clang build rather than mth_i_dfloor in the Ubuntu Linux build. The build line on macOS for this is...

[ 71%] Building C object lib/common/CMakeFiles/common.dir/dfloor.c.o cd /Users/howarth/flang_dir/flang/runtime/libpgmath/build/lib/common && /Users/howarth/flang_dir/install/bin/clang -DHOST_OSX -DMAXCPUS=256 -DMAXCPUSL=8 -DMAXCPUSR=4 -DOSX -DOSX86 -DOSX8664 -DPG_PIC -DTARGET_OSX -DTARGET_OSX_X86 -DTARGET_OSX_X8664 -DTARGET_X86 -DTARGET_X8664 -D__gnu_osx__ -I/Users/howarth/flang_dir/flang/runtime/libpgmath/lib/common -I/Users/howarth/flang_dir/flang/runtime/libpgmath/lib/x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -fPIC -m64 -O3 -fomit-frame-pointer -o CMakeFiles/common.dir/dfloor.c.o -c /Users/howarth/flang_dir/flang/runtime/libpgmath/lib/common/dfloor.c

jwhowarth commented 5 years ago

The same situation also exists for ./lib/common/CMakeFiles/common.dir/floor.c.o which contains a symbol for _mth_i_floorsse on the macOS clang build rather than mth_i_floor in the Ubuntu Linux build. The build line on macOS for this is...

[ 74%] Building C object lib/common/CMakeFiles/common.dir/floor.c.o cd /Users/howarth/flang_dir/flang/runtime/libpgmath/build/lib/common && /Users/howarth/flang_dir/install/bin/clang -DHOST_OSX -DMAXCPUS=256 -DMAXCPUSL=8 -DMAXCPUSR=4 -DOSX -DOSX86 -DOSX8664 -DPG_PIC -DTARGET_OSX -DTARGET_OSX_X86 -DTARGET_OSX_X8664 -DTARGET_X86 -DTARGET_X8664 -D__gnu_osx__ -I/Users/howarth/flang_dir/flang/runtime/libpgmath/lib/common -I/Users/howarth/flang_dir/flang/runtime/libpgmath/lib/x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -fPIC -m64 -O3 -fomit-frame-pointer -o CMakeFiles/common.dir/floor.c.o -c /Users/howarth/flang_dir/flang/runtime/libpgmath/lib/common/floor.c

jwhowarth commented 5 years ago

Attached is the preprocessed source file for dceil.i from the macOS clang based build.

dceil.i.zip

jwhowarth commented 5 years ago

Attached is the preprocessed source file for dfloor.i from the macOS clang based build.

dfloor.i.zip

jwhowarth commented 5 years ago

Attached is the preprocessed source file for floor.i from the macOS clang based build.

floor.i.zip

jwhowarth commented 5 years ago

Complete build log from build_flang.sh execution.

flang_build.log.zip

d-parks commented 5 years ago

Thank you. Let me take a look. I might ask you to run with 'make VERBOSE=1' but let me start with what you've uploaded.

jwhowarth commented 5 years ago

The log was already done with 'make VERBOSE=1'. In case it helps, I have attached a compressed preprocessed source file for dceil.i from the Ubuntu Linux build that produces the expected __mth_i_dceil symbol (without the _sse suffix seen in the macOS clang based build). The Linux build uses the command below.

dceil.i.gz

cd /home/howarth/flang_dir/flang/runtime/libpgmath/build/lib/common && /home/howarth/flang_dir/install/bin/clang -DHOST_LINUX -DLINUX -DLINUX86 -DLINUX8664 -DMAXCPUS=256 -DMAXCPUSL=8 -DMAXCPUSR=8 -DPG_PIC -DTARGET_LINUX -DTARGET_LINUX_X86 -DTARGET_LINUX_X8664 -DTARGET_X86 -DTARGET_X8664 -D__gnu_linux__ -I/home/howarth/flang_dir/flang/runtime/libpgmath/lib/common -I/home/howarth/flang_dir/flang/runtime/libpgmath/lib/x86_64 -fPIC -m64 -O3 -o CMakeFiles/common.dir/dceil.c.o -c /home/howarth/flang_dir/flang/runtime/libpgmath/lib/common/dceil.c

jwhowarth commented 5 years ago

Looking at flang/runtime/libpgmath/lib/common/dceil.c the symbol naming would appear to be correct for a machine with SSE4,1 support being detected. My guess is this issue is due to clang compilers defaulting to SSE4,1 support being enabled on macOS which isn't the case for the generic x86_64 gcc compilers on Linux. So this is a section of code that never gets exercised on Linux in the default builds.

if defined(AVX)

double __mth_i_dceil_avx(double x) { return _mm_cvtsd_f64(_mm_ceil_sd(_mm_set1_pd(x), _mm_set1_pd(x))); }

elif defined(__SSE4_1__)

double __mth_i_dceil_sse(double x) { return _mm_cvtsd_f64(_mm_ceil_sd(_mm_set1_pd(x), _mm_set1_pd(x))); }

else

double __mth_i_dceil(double x) { return ceil(x); }

endif

d-parks commented 5 years ago

I don't believe that the entry points _sse and _avx are in the dispatch configuration tables, thus they should not be generated. I'll dig into this tomorrow.

d-parks commented 5 years ago

The dispatch configuration tables do not make reference to either the _sse or _avx entry points. __mth_i_ceil (dceil) should just be a pass through routine to libm. I'll look at enabling those entry points in the dispatch table and building the two additional variants.

jwhowarth commented 5 years ago

Should I watch for the fix to appear here or will it just go into master?

d-parks commented 5 years ago

Most likely the master - though I'll update you when there is a submitted fix.

d-parks commented 5 years ago

Sorry for the delay - my build environment does not define any advanced processor architectural features when invoked without any -march option. It defaults to

build-mac:osx dparks$ gcc -E -dM t.c | grep AVX build-mac:osx dparks$ gcc -E -dM t.c -march=sandybridge | grep AVX #define __AVX__ 1 build-mac:osx dparks$ gcc -E -dM t.c -march=haswell | grep AVX #define __AVX2__ 1 #define __AVX__ 1 build-mac:osx dparks$

SSSE3 is the highest feature I get with the default settings.

build-mac:osx dparks$ gcc --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.40) (based on LLVM 3.4svn) Target: x86_64-apple-darwin13.4.0 Thread model: posix build-mac:osx dparks$

As a temporary workaround, can you just disable the logic #if defined(__AVX__) and #elif defined(__SSE4_1__)? #if 0 && defined(__AVX__) ...

jwhowarth commented 5 years ago

Apple apparently updated their default SSE options in later Xcode releases to match the depreciation of pre-Core2 hardware that didn't support SSE 4,1. Xcode 10.2 produces the output below...

$ gcc --version Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1 Apple LLVM version 10.0.1 (clang-1001.0.46.4) Target: x86_64-apple-darwin18.7.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

$ gcc -dM -E - < /dev/null | egrep "SSE|AVX" | sort

define __SSE2_MATH__ 1

define SSE2 1

define SSE3 1

define __SSE4_1__ 1

define __SSE_MATH__ 1

define SSE 1

define SSSE3 1