p12tic / libsimdpp

Portable header-only C++ low level SIMD library
Boost Software License 1.0
1.24k stars 129 forks source link

Error When Doing Dynamic Dispatch in GCC 7.0.1 and Warning on Clang 5.0 #104

Open cwfitzgerald opened 6 years ago

cwfitzgerald commented 6 years ago

I was compiling the following code (almost directly from your example, with minimal changes):

#include <cinttypes>
#include <vector>

#include <simdpp/simd.h>

#include <simdpp/dispatch/get_arch_gcc_builtin_cpu_supports.h>
#include <simdpp/dispatch/get_arch_linux_cpuinfo.h>
#include <simdpp/dispatch/get_arch_raw_cpuid.h>

#if SIMDPP_HAS_GET_ARCH_RAW_CPUID
#define SIMDPP_USER_ARCH_INFO ::simdpp::get_arch_raw_cpuid()
#elif SIMDPP_HAS_GET_ARCH_GCC_BUILTIN_CPU_SUPPORTS
#define SIMDPP_USER_ARCH_INFO ::simdpp::get_arch_gcc_builtin_cpu_supports()
#elif SIMDPP_HAS_GET_ARCH_LINUX_CPUINFO
#define SIMDPP_USER_ARCH_INFO ::simdpp::get_arch_linux_cpuinfo()
#else
#error "Unsupported platform"
#endif

namespace SIMDPP_ARCH_NAMESPACE {
    std::size_t sumation(const std::vector<std::size_t>& array) {
        (void) array;
        return 1;
    }

} // namespace SIMDPP_ARCH_NAMESPACE

SIMDPP_MAKE_DISPATCHER((std::size_t)(sumation)((const std::vector<std::size_t>&) array))

I am using the following cmake file:

set(SOURCES sum.cpp)
set(HEADERS include/sum.hpp)

simdpp_get_compilable_archs(ARCHES)
simdpp_multiarch(ARCH_SOURCES ${SOURCES} ${ARCHES})

lint(FILES ${SOURCES})
format(FILES ${SOURCES} ${HEADERS})

add_library(sum SHARED ${ARCH_SOURCES})
target_include_directories(sum PUBLIC include)
target_include_directories(sum SYSTEM PRIVATE "../third-party/libsimdpp")

I get the following error on gcc-7:

FAILED: libsum/CMakeFiles/sum.dir/sum_simdpp_-x86_sse2.cpp.o 
/usr/bin/c++  -Dsum_EXPORTS -I../libsum/include -isystem ../libsum/../third-party/libsimdpp -fPIC   -fdiagnostics-color=always -Wall -Wcast-align -Wcast-qual -Wconversion -Wctor-dtor-privacy -Wdisabled-optimization -Wdouble-promotion -Wduplicated-branches -Wduplicated-cond -Wextra -Wformat=2 -Winit-self -Wlogical-op -Wno-gnu-zero-variadic-macro-arguments -Wmissing-include-dirs -Wno-sign-conversion -Wnoexcept -Wnull-dereference -Wold-style-cast -Woverloaded-virtual -Wpedantic -Wrestrict -Wshadow -Wstrict-aliasing=1 -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unknown-pragmas -Wuseless-cast -std=gnu++1z -I"/home/connor/Dropbox/cmake-test/libsum/"  -msse2 -DSIMDPP_ARCH_X86_SSE2 -MD -MT libsum/CMakeFiles/sum.dir/sum_simdpp_-x86_sse2.cpp.o -MF libsum/CMakeFiles/sum.dir/sum_simdpp_-x86_sse2.cpp.o.d -o libsum/CMakeFiles/sum.dir/sum_simdpp_-x86_sse2.cpp.o -c libsum/sum_simdpp_-x86_sse2.cpp
In file included from ../libsum/../third-party/libsimdpp/simdpp/types.h:44:0,
                 from ../libsum/../third-party/libsimdpp/simdpp/core/align.h:15,
                 from ../libsum/../third-party/libsimdpp/simdpp/simd.h:19,
                 from libsum/sum_simdpp_-x86_sse2.cpp:4:
../libsum/../third-party/libsimdpp/simdpp/types/empty_expr.h: In instantiation of ‘simdpp::arch_sse2::mask_int32<N, simdpp::arch_sse2::expr_empty>::operator simdpp::arch_sse2::uint32<N>() const [with unsigned int N = 4]’:
../libsum/../third-party/libsimdpp/simdpp/detail/insn/cmp_neq.h:195:52:   required from here
../libsum/../third-party/libsimdpp/simdpp/types/empty_expr.h:220:52: error: could not convert ‘((const simdpp::arch_sse2::mask_int32<4, simdpp::arch_sse2::expr_empty>*)this)->simdpp::arch_sse2::mask_int32<4, simdpp::arch_sse2::expr_empty>::e’ from ‘const simdpp::arch_sse2::mask_int32<4>’ to ‘simdpp::arch_sse2::uint32<4>’
     SIMDPP_INL operator uint32<N>() const { return e; }
                                                    ^

I get the following clang-5.0:

[19/23:  60% - 6 edges @ 2.5|5.7 edges/s 2.468s] Building CXX object libsum/CMakeFiles/sum.dir/sum_simdpp_-null.cpp.o
libsum/sum_simdpp_-null.cpp:28:1: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments]
SIMDPP_MAKE_DISPATCHER((std::size_t)(sumation)((const std::vector<std::size_t>&) array))
^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:373:5: note: expanded from macro 'SIMDPP_MAKE_DISPATCHER'
    SIMDPP_PP_CAT(SIMDPP_DETAIL_MAKE_DISPATCHER, SIMDPP_PP_SEQ_SIZE(DESC))(DESC)
    ^
../libsum/../third-party/libsimdpp/simdpp/detail/preprocessor/cat.hpp:22:33: note: expanded from macro 'SIMDPP_PP_CAT'
#    define SIMDPP_PP_CAT(a, b) SIMDPP_PP_CAT_I(a, b)
                                ^
../libsum/../third-party/libsimdpp/simdpp/detail/preprocessor/cat.hpp:29:35: note: expanded from macro 'SIMDPP_PP_CAT_I'
#    define SIMDPP_PP_CAT_I(a, b) a ## b
                                  ^
<scratch space>:127:1: note: expanded from here
SIMDPP_DETAIL_MAKE_DISPATCHER3
^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:302:5: note: expanded from macro 'SIMDPP_DETAIL_MAKE_DISPATCHER3'
    SIMDPP_DETAIL_MAKE_DISPATCHER_IMPL(                                         \
    ^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:281:5: note: expanded from macro 'SIMDPP_DETAIL_MAKE_DISPATCHER_IMPL'
    SIMDPP_DETAIL_RETURN_IF_NOT_VOID(R) selected(SIMDPP_DETAIL_FORWARD(ARGS));  \
    ^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:235:47: note: expanded from macro 'SIMDPP_DETAIL_RETURN_IF_NOT_VOID'
        SIMDPP_PP_IIF(SIMDPP_PP_PROBE_TO_BOOL(SIMDPP_DETAIL_PROBE_IF_VOID(R)),  \
                                              ^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:227:18: note: expanded from macro 'SIMDPP_DETAIL_PROBE_IF_VOID'
                 SIMDPP_DETAIL_PROBE_IF_VOID_1PARAM                             \
                 ^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:148:9: note: macro 'SIMDPP_PP_PROBE_TO_BOOL_I' defined here
#define SIMDPP_PP_PROBE_TO_BOOL_I(n1, n2, ...) n2
        ^
libsum/sum_simdpp_-null.cpp:28:1: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu-zero-variadic-macro-arguments]
SIMDPP_MAKE_DISPATCHER((std::size_t)(sumation)((const std::vector<std::size_t>&) array))
^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:373:5: note: expanded from macro 'SIMDPP_MAKE_DISPATCHER'
    SIMDPP_PP_CAT(SIMDPP_DETAIL_MAKE_DISPATCHER, SIMDPP_PP_SEQ_SIZE(DESC))(DESC)
    ^
../libsum/../third-party/libsimdpp/simdpp/detail/preprocessor/cat.hpp:22:33: note: expanded from macro 'SIMDPP_PP_CAT'
#    define SIMDPP_PP_CAT(a, b) SIMDPP_PP_CAT_I(a, b)
                                ^
../libsum/../third-party/libsimdpp/simdpp/detail/preprocessor/cat.hpp:29:35: note: expanded from macro 'SIMDPP_PP_CAT_I'
#    define SIMDPP_PP_CAT_I(a, b) a ## b
                                  ^
<scratch space>:127:1: note: expanded from here
SIMDPP_DETAIL_MAKE_DISPATCHER3
^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:302:5: note: expanded from macro 'SIMDPP_DETAIL_MAKE_DISPATCHER3'
    SIMDPP_DETAIL_MAKE_DISPATCHER_IMPL(                                         \
    ^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:281:5: note: expanded from macro 'SIMDPP_DETAIL_MAKE_DISPATCHER_IMPL'
    SIMDPP_DETAIL_RETURN_IF_NOT_VOID(R) selected(SIMDPP_DETAIL_FORWARD(ARGS));  \
    ^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:235:23: note: expanded from macro 'SIMDPP_DETAIL_RETURN_IF_NOT_VOID'
        SIMDPP_PP_IIF(SIMDPP_PP_PROBE_TO_BOOL(SIMDPP_DETAIL_PROBE_IF_VOID(R)),  \
                      ^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:137:49: note: expanded from macro 'SIMDPP_PP_PROBE_TO_BOOL'
        SIMDPP_PP_PROBE_TO_BOOL_I(__VA_ARGS__, 0)
                                                ^
../libsum/../third-party/libsimdpp/simdpp/dispatch/make_dispatcher.h:148:9: note: macro 'SIMDPP_PP_PROBE_TO_BOOL_I' defined here
#define SIMDPP_PP_PROBE_TO_BOOL_I(n1, n2, ...) n2
        ^
2 warnings generated.

If you need any more info, let me know. Works perfectly on gcc<=6.

p12tic commented 6 years ago

Thanks for the bug report! I see that you're using -std=gnu++1z for GCC, could that be the culprit? That would explain why no such failures are seen on the test farm. The test matrix will need to be expanded to cover cases like this.

Could you also check, what standard you're using for clang?

cwfitzgerald commented 6 years ago

I'm using -std=gnu++1z for both gcc and clang. It does appear to be the culprit with GCC, std=gnu++1y works fine, though clang still reports the warning. I think that's because I have -Wpedantic on and zero variation macro arguments is not allowed as per the standard (though it's a widely supported extension). I have disabled the warning for my build -Wno-gnu-zero-variadic-macro-arguments which is good enough for me, but thought I'd let you know about it.

CHChang810716 commented 6 years ago

I just modify the simdpp/types/empty_expr.h:220

SIMDPP_INL operator uint32<N>() const { return e; }

to

SIMDPP_INL operator uint32<N>() const { return uint32<N>(e); }

and the error gone.