clang-cl не допускает перегрузки операторов для __m128, потому что это не класс или перечисление? Обходной путь, чтобы сделать его похожим на MSVC?

#c #clang #operator-overloading #intrinsics #clang-cl

#c #clang #перегрузка оператора #встроенные #clang-cl

Вопрос:

Следующий код отлично строится cl в соответствии с, но не выполняется в соответствии с clang-cl :

 #define NUDGE_FORCEINLINE __forceinline

NUDGE_FORCEINLINE __m128 operator-(__m128 a) {
  return _mm_xor_ps(a, _mm_set1_ps(-0.0f));
}
 

Это сообщение об ошибке:

 ..nudge.cpp(65,26): error: overloaded 'operator-' must have at least one parameter of class or enumeration type
NUDGE_FORCEINLINE __m128 operator-(__m128 a) {
                         ^
 

Код взят из rasmusbarr / nudge, эксперимента, который, похоже, был заброшен с 2017 года.

Настройка (CMake / VSCode):

  • cl с VS Build Tools 2019 v16.8.2
  • clang-cl с C Clang Tools for Windows 10.0.0 (VS Build Tools 2019 v16.8.2)
 cmake_minimum_required(VERSION 3.18.0)
project(nudge LANGUAGES C CXX)

add_executable(tests "nudge.cpp" "tests/main.cpp")
target_include_directories(tests PRIVATE ${CMAKE_SOURCE_DIR})
 

Исследования:

Я наткнулся на эти два источника (1, 2), которые, похоже, указывают на то, что причина может быть в том, что clang-cl не считает __m128 структурным типом. Они исправили это в (1), но, похоже, они просто отключают SSE для некоторых платформ.

Хотя это был долгий путь, я попытался скомпилировать с версией VS immintrin.h и intrin.h , но этот путь ни к чему не привел.

Я также заметил, что кто-то еще, кто строил этот эксперимент, использовал стандарт c 11, поэтому я тоже попробовал это, установив set(CMAKE_CXX_STANDARD 11) в cmake. Никаких изменений.

Вопрос:

Как я могу изменить код (или изменить флаги компилятора), чтобы создать rasmusbarr / nudge с помощью clang-cl?

Спасибо

Комментарии:

1. Обычный clang допускает перегрузки функций, которые отличаются только на __m128i vs __m128d . или long long аргумент. godbolt.org/z/b7eYE8 . О, но, по-видимому, перегрузки операторов разные. godbolt.org/z/GPc6Po . Вы могли бы использовать одну из других библиотек-оболочек C , таких как VCL, или, возможно, использовать оболочку класса для __m128 вместо __m128 прямого, возможно, используя макрос препроцессора C в качестве взлома существующего кода.

2. Как будет __m128 выглядеть класс-оболочка для?

3. Clang уже предоставляет operator-(__m128) , что делает именно то, что вы хотите: godbolt.org/z/c75fWf

4. Я отключил весь код перегрузки оператора, и, похоже, он создается и работает нормально. Я протестирую остальные операторы с помощью godbolt.