MacOS, AVX, GCC, and LLVM

I spent some time last night getting the the development branch of GNU
Radio to compile on MacOS X 10.7. In the process, I saw some people
having issues with compiler/assembler AVX support, Apple’s ancient GPLv2
“as”, and Xcode’s LLVM. I succeeded in building and running GNU Radio
using Xcode 4.3.2’s tools (no MacPorts gcc, llvm, or cctools). I’m
posting what I learned, in hopes somebody knows how to fix this from the
GNU Radio source side (instead of patching CMake, as I did).

The problem I saw, having to do with Clang compiler flag detection for
ORC during cmake:

-- Performing Test have_maltivec
-- Performing Test have_maltivec - Success
-- Performing Test have_mfpu_neon
-- Performing Test have_mfpu_neon - Success
-- Performing Test have_mfloat_abi_softfp
-- Performing Test have_mfloat_abi_softfp - Success
-- Performing Test have_funsafe_math_optimizations
-- Performing Test have_funsafe_math_optimizations - Success
...
-- Performing Test have_mpopcnt
-- Performing Test have_mpopcnt - Success

Note that I’m compiling on a Sandy Bridge Intel processor, so Altivec
(PPC), NEON (ARM), and float-ABI (ARM?) aren’t available. Also, LLVM 3.0
doesn’t support -mpopcnt, and apparently doesn’t support
-munsafe_math_optimizations. And yet, the detections are showing
“Success”. Sure enough, when I “make”, volk bombs out with:

cc1: error: unrecognized command line option "-mfpu=neon"
cc1: error: unrecognized command line option "-mfloat-abi=softfp"

Examining build/volk/CMakeFiles/CMakeOutput.log, the command line
executed for detecting the Altivec flag is:

/usr/bin/c++    -Dhave_maltivec   -maltivec -o 

CMakeFiles/cmTryCompileExec.dir/src.cxx.o -c
/Users/jboone/tmp/gnuradio/build/volk/CMakeFiles/CMakeTmp/src.cxx

Creating my own src.cxx (“int main() { return 0; }”) and trying this out
yields:

clang: warning: argument unused during compilation: '-maltivec'

Clang warns about the unrecognized flag, but CMake doesn’t consider it
an error. Why? Examining volk/lib/CMakeLists.txt, I see that CMake’s
CheckCXXCompilerFlag is included, and CHECK_CXX_COMPILER_FLAG is called
with each flag to test.

Looking at CMake’s CHECK_CXX_COMPILER_FLAG, I see it tests the
compiler’s stdout (or stderr?) against these regular expressions:

 # Some compilers do not fail with a bad flag
 FAIL_REGEX "unrecognized .*option"                     # GNU
 FAIL_REGEX "unknown .*option"                          # Clang
 FAIL_REGEX "ignoring unknown option"                   # MSVC
 FAIL_REGEX "warning D9002"                             # MSVC, any 

lang
FAIL_REGEX “[Uu]nknown option” # HP
FAIL_REGEX “[Ww]arning: [Oo]ption” # SunPro
FAIL_REGEX “command option .* is not recognized” # XL
FAIL_REGEX “not supported in this configuration; ignored” #
AIX
FAIL_REGEX “File with unknown suffix passed to linker” # PGI

None of these regex tests will catch the Clang warning above.

My first inclination was to see if I could set a Clang flag (like
“-Werror”) to cause unused arguments to produce an error. But I can’t
tell how to do that with CMake. If somebody knows how to do this from
within the GNU Radio sources, that would be ideal. Instead, I patched
CMake as follows:

— /opt/local/share/cmake-2.8/Modules/CheckCXXCompilerFlag.cmake.orig
2012-05-04 23:41:16.000000000 -0700
+++ /opt/local/share/cmake-2.8/Modules/CheckCXXCompilerFlag.cmake
2012-05-04 23:43:19.000000000 -0700
@@ -29,6 +29,7 @@
# Some compilers do not fail with a bad flag
FAIL_REGEX “unrecognized .*option” # GNU
FAIL_REGEX “unknown .*option” # Clang

  • FAIL_REGEX "argument unused during compilation"        # Clang
    FAIL_REGEX "ignoring unknown option"                   # MSVC
    FAIL_REGEX "warning D9002"                             # MSVC, any 
    

lang
FAIL_REGEX “[Uu]nknown option” # HP

This results in more sensible flag detection for ORC during cmake:

-- Performing Test have_maltivec
-- Performing Test have_maltivec - Failed
-- Performing Test have_mfpu_neon
-- Performing Test have_mfpu_neon - Failed
-- Performing Test have_mfloat_abi_softfp
-- Performing Test have_mfloat_abi_softfp - Failed
-- Performing Test have_funsafe_math_optimizations
-- Performing Test have_funsafe_math_optimizations - Failed
...
-- Performing Test have_mpopcnt
-- Performing Test have_mpopcnt - Failed
...
-- GCC missing xgetbv, Overruled arch avx
-- Check size of void*[8]
-- Check size of void*[8] - done
-- CPU width is 64 bits, Overruled arch 32
-- Available architectures: 

generic;64;3dnow;abm;mmx;sse;sse2;orc;norc;sse3;ssse3;sse4_a;sse4_1;sse4_2
– Available machines:
generic_orc;sse2_64_orc;sse3_64_orc;ssse3_64_orc;sse4_1_64_orc

…and more importantly, I can compile GNU Radio and run
gnuradio-companion.

I see some similar patch history for CMake that suggests my fix is a
good one:

http://public.kitware.com/Bug/view.php?id=12394

I looked at the CMake repository, and it looks like they haven’t yet
identified or fixed this problem:

http://cmake.org/gitweb?p=cmake.git;a=blob;f=Modules/CheckCXXCompilerFlag.cmake;hb=HEAD

So I’ll submit a patch to CMake. Of course, until a new CMake is
released, MacOS builders will run into this problem. So if anybody
familiar with CMake knows a way to fix this from GNU Radio, that would
be splendid!

    - Jared

On Sat, May 5, 2012 at 2:16 PM, Jared B. [email protected]
wrote:

– Performing Test have_funsafe_math_optimizations
Examining build/volk/CMakeFiles/CMakeOutput.log, the command line executed for
detecting the Altivec flag is:

  • FAIL_REGEX “argument unused during compilation” # Clang
    – Performing Test have_mfloat_abi_softfp
    – CPU width is 64 bits, Overruled arch 32

So I’ll submit a patch to CMake. Of course, until a new CMake is released, MacOS
builders will run into this problem. So if anybody familiar with CMake knows a way
to fix this from GNU Radio, that would be splendid!

  • Jared

Hi Jared,
Thanks for the information and reporting this. Obviously, this would
be a cmake patch issue, not ours, but hopefully helpful for people
working with GNU Radio in the same environment. Glad to hear you got
things working, though!

Tom

On May 8, 2012, at 2:29 PM, Josh B. wrote:

there is question of how to fix/who to blame:

  1. cmake is at fault, and that patch needs to be in there

The CMake team has already incorporated a patch against forthcoming
CMake 2.8.9:

http://public.kitware.com/Bug/view.php?id=13194

However, I don’t think the patch is ideal – regex on compiler output
seems like running with scissors to me. It’d be better for Clang to
report an error by shell return code. But see below, because I don’t
think CMake has an alternative to output string parsing, at the moment.

  1. clang is at fault and should error/not warn.

This is what I believe, but in the short term, it appears the CMake
people have already had to deal with warnings that are errors as far as
CMake is concerned.

Is there a clang flag to force unknown flags to become errors?
I think you can just pass another flag to CHECK_CXX_COMPILER_FLAG along
with the one being check.

I tried using clang -Werror, but that does not change the return code –
it’s “0” with or without -Werror. I noodled around with
-fdiagnostics-show-category=id and -fdiagnostics-show-category=name, but
didn’t get any reaction from Clang. I even dug through the Clang source
and tried to target the specific warning by name, like this:

/usr/bin/c++ -Werror=unused-command-line-argument -Dhave_maltivec
-maltivec -o test.cxx.o -c test.cxx

Still, I get “0”.

It looks like the Clang team is aware of and has addressed this problem
in time for the forthcoming LLVM 3.1 release:

http://llvm.org/bugs/show_bug.cgi?id=12181

And if thats not possible we could switch to CHECK_CXX_SOURCE_COMPILES
to help with the flag tests.

  1. volk has a way to specify compiler specific flags. But its probably
    wrong to use this if clang is using GCC flags and reporting as GNU.
    http://gnuradio.org/cgit/gnuradio.git/tree/volk/gen/archs.xml

Unless there’s a workable Clang flag scheme I haven’t tried, I’m not
sure this would address the problem for LLVM releases < 3.1, due to what
I described above re: return codes.

Perhaps attempting to compile a single inline assembly instruction for
the architecture/instruction set in question would yield a proper
failure, regardless of Clang’s behavior?

  • Jared

Note that I’m compiling on a Sandy Bridge Intel processor, so Altivec
(PPC), NEON (ARM), and float-ABI (ARM?) aren’t available. Also, LLVM
3.0 doesn’t support -mpopcnt, and apparently doesn’t support
-munsafe_math_optimizations. And yet, the detections are showing
“Success”. Sure enough, when I “make”, volk bombs out with:

cc1: error: unrecognized command line option “-mfpu=neon” cc1: error:
unrecognized command line option “-mfloat-abi=softfp”

OK so, thats a pretty thorough analysis of the issue. I guess there
there is question of how to fix/who to blame:

  1. cmake is at fault, and that patch needs to be in there

  2. clang is at fault and should error/not warn.

Is there a clang flag to force unknown flags to become errors?
I think you can just pass another flag to CHECK_CXX_COMPILER_FLAG along
with the one being check.

And if thats not possible we could switch to CHECK_CXX_SOURCE_COMPILES
to help with the flag tests.

  1. volk has a way to specify compiler specific flags. But its probably
    wrong to use this if clang is using GCC flags and reporting as GNU.
    http://gnuradio.org/cgit/gnuradio.git/tree/volk/gen/archs.xml

-Josh