Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot link against a MSVC built Vc because it needs Vc_CDECL on some symbols #289

Closed
amyspark opened this issue Jul 6, 2021 · 2 comments · Fixed by #291
Closed

Cannot link against a MSVC built Vc because it needs Vc_CDECL on some symbols #289

amyspark opened this issue Jul 6, 2021 · 2 comments · Fixed by #291
Milestone

Comments

@amyspark
Copy link
Contributor

amyspark commented Jul 6, 2021

Vc version / revision Operating System Compiler & Version Compiler Flags Assembler & Version CPU
1.4.2 Windows MSVC 19.29.30038.1 /MD /O1 /Ob1 /DNDEBUG /fp:fast N/A Ryzen 7 2700x

Testcase

#include <Vc/Vc>
#include <Vc/support.h>
#include <iostream>

int main() {
  if (Vc::isImplementationSupported(Vc::AVX2Impl)) {
    std::cout << "AVX2" << std::endl;
  } else if (Vc::isImplementationSupported(Vc::AVXImpl)) {
    std::cout << "AVX" << std::endl;
  } else if (Vc::isImplementationSupported(Vc::SSE41Impl)) {
    std::cout << "SSE 4.1" << std::endl;
  } else if (Vc::isImplementationSupported(Vc::SSSE3Impl)) {
    std::cout << "SSSE3" << std::endl;
  } else if (Vc::isImplementationSupported(Vc::SSE2Impl)) {
    std::cout << "SSE2" << std::endl;
  } else {
    std::cout << "Scalar" << std::endl;
  }

  Vc::float_v a;
  a[0] = rand();
  a[1] = rand();
  a[2] = rand();
  a[3] = rand();
  std::cout << a << std::endl;
  std::cout << a.sorted() << std::endl;
}
cmake_minimum_required(VERSION 3.10)

project (test)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Vc 1.3.0 REQUIRED)

add_executable(main main.cpp)

target_compile_options(main PRIVATE "/fp:fast")

target_link_libraries(main PUBLIC Vc::Vc)

Actual Results

CMake finds and instantiates Vc::Vc, compilation succeeds, but linking fails:

[cmake] Not searching for unused variables given on the command line.
[cmake] -- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.19042.
[cmake] msvc_version.c
[cmake] c1: fatal error C1083: No se puede abrir el archivo origen: 'E:/VcDevel/install/lib/cmake/Vc/msvc_version.c': No such file or directory
[cmake] -- Detected Compiler: MSVC 
[cmake] -- Detected CPU: zen
[cmake] -- Configuring done
[cmake] -- Generating done
[cmake] -- Build files have been written to: E:/VcDevelTest/build
[main] Building folder: VcDevelTest 
[build] Starting build
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build e:/VcDevelTest/build --config MinSizeRel --target ALL_BUILD -j 2 --
[build] Microsoft (R) Build Engine versión 16.10.2+857e5a733 para .NET Framework
[build] Copyright (C) Microsoft Corporation. Todos los derechos reservados.
[build] 
[build]   main.cpp
[build] E:\VcDevel\install\include\Vc\sse\detail.h(679,15): warning C4244: 'return': conversión de 'short' a 'Vc_1::schar'; posible pérdida de datos [E:\VcDevelTest\build\main.vcxproj]
[build] E:\VcDevel\install\include\Vc\avx\detail.h(737,48): warning C4146: operador unario menos aplicado a un tipo unsigned; el resultado aún no tiene signo [E:\VcDevelTest\build\main.vcxproj]
[build] E:\VcDevel\install\include\Vc\avx\detail.h(738,48): warning C4146: operador unario menos aplicado a un tipo unsigned; el resultado aún no tiene signo [E:\VcDevelTest\build\main.vcxproj]
[build] E:\VcDevel\install\include\Vc\avx/vector.h(324,53): warning C4244: '=': conversión de 'U' a 'float'; posible pérdida de datos [E:\VcDevelTest\build\main.vcxproj]
[build]           with
[build]           [
[build]               U=int
[build]           ]
[build] E:\VcDevel\install\include\Vc\avx/vector.h(323): message : al compilar la función del miembro clase plantilla "void Vc_1::Vector<float,Vc_1::VectorAbi::Avx>::set<ValueType>(Vc_1::Vector<float,Vc_1::VectorAbi::Avx> &,int,U &&) noexcept(<expr>)" [E:\VcDevelTest\build\main.vcxproj]
[build]           with
[build]           [
[build]               ValueType=int,
[build]               U=int
[build]           ]
[build] E:\VcDevel\install\include\Vc\common\elementreference.h(79): message : al compilar la función del miembro clase plantilla "Vc_1::Detail::ElementReference<Vc_1::Vector<float,Vc_1::VectorAbi::Avx>,U> &Vc_1::Detail::ElementReference<U,U>::operator =<int>(T &&) noexcept(<expr>) &&" [E:\VcDevelTest\build\main.vcxproj]
[build]           with
[build]           [
[build]               U=Vc_1::Vector<float,Vc_1::VectorAbi::Avx>,
[build]               T=int
[build]           ]
[build] E:\VcDevel\install\include\Vc\avx/vector.h(326,31): warning C4244: 'argumento': conversión de 'U' a 'float'; posible pérdida de datos [E:\VcDevelTest\build\main.vcxproj]
[build]           with
[build]           [
[build]               U=int
[build]           ]
[build] E:\VcDevel\install\include\Vc\common\elementreference.h(82): message : Vea la referencia a la creación de una instancia de la función plantilla "void Vc_1::Vector<float,Vc_1::VectorAbi::Avx>::set<ValueType>(Vc_1::Vector<float,Vc_1::VectorAbi::Avx> &,int,U &&) noexcept" que se está compilando [E:\VcDevelTest\build\main.vcxproj]
[build]           with
[build]           [
[build]               ValueType=int,
[build]               U=int
[build]           ]
[build] E:\VcDevel\install\include\Vc\common\elementreference.h(82): message : Vea la referencia a la creación de una instancia de la función plantilla "void Vc_1::Vector<float,Vc_1::VectorAbi::Avx>::set<ValueType>(Vc_1::Vector<float,Vc_1::VectorAbi::Avx> &,int,U &&) noexcept" que se está compilando [E:\VcDevelTest\build\main.vcxproj]
[build]           with
[build]           [
[build]               ValueType=int,
[build]               U=int
[build]           ]
[build] E:\VcDevelTest\src\main.cpp(23): message : Vea la referencia a la creación de una instancia de la función plantilla "Vc_1::Detail::ElementReference<Vc_1::Vector<float,Vc_1::VectorAbi::Avx>,U> &Vc_1::Detail::ElementReference<U,U>::operator =<int>(T &&) noexcept &&" que se está compilando [E:\VcDevelTest\build\main.vcxproj]
[build]           with
[build]           [
[build]               U=Vc_1::Vector<float,Vc_1::VectorAbi::Avx>,
[build]               T=int
[build]           ]
[build] E:\VcDevelTest\src\main.cpp(23): message : Vea la referencia a la creación de una instancia de la función plantilla "Vc_1::Detail::ElementReference<Vc_1::Vector<float,Vc_1::VectorAbi::Avx>,U> &Vc_1::Detail::ElementReference<U,U>::operator =<int>(T &&) noexcept &&" que se está compilando [E:\VcDevelTest\build\main.vcxproj]
[build]           with
[build]           [
[build]               U=Vc_1::Vector<float,Vc_1::VectorAbi::Avx>,
[build]               T=int
[build]           ]
[build] main.obj : error LNK2019: símbolo externo "public: static void __cdecl Vc_1::CpuId::init(void)" (?init@CpuId@Vc_1@@SAXXZ) sin resolver al que se hace referencia en la función "void __cdecl `dynamic initializer for 'public: static struct Vc_1::detail::RunCpuIdInit<0> Vc_1::detail::RunCpuIdInit<0>::tmp''(void)" (??__E?tmp@?$RunCpuIdInit@$0A@@detail@Vc_1@@2U123@A@@YAXXZ) [E:\VcDevelTest\build\main.vcxproj]
[build] main.obj : error LNK2019: símbolo externo "bool __cdecl Vc_1::isImplementationSupported(enum Vc_1::Implementation)" (?isImplementationSupported@Vc_1@@YA_NW4Implementation@1@@Z) sin resolver al que se hace referencia en la función main [E:\VcDevelTest\build\main.vcxproj]
[build] main.obj : error LNK2019: símbolo externo "class Vc_1::Vector<float,struct Vc_1::VectorAbi::Avx> __cdecl Vc_1::Detail::sorted<7,float,struct Vc_1::enable_if_default_type>(class Vc_1::Vector<float,struct Vc_1::VectorAbi::Avx>)" (??$sorted@$06MUenable_if_default_type@Vc_1@@@Detail@Vc_1@@YA?AV?$Vector@MUAvx@VectorAbi@Vc_1@@@1@V21@@Z) sin resolver al que se hace referencia en la función main [E:\VcDevelTest\build\main.vcxproj]
[build] E:\VcDevelTest\build\MinSizeRel\main.exe : fatal error LNK1120: 3 externos sin resolver [E:\VcDevelTest\build\main.vcxproj]
[build] Build finished with exit code 1

Expected Results

Compilation and linking successful with no errors.

@amyspark
Copy link
Contributor Author

amyspark commented Jul 6, 2021

I ran DUMPLIB on Vc.lib, since I couldn't notice why it was complaining on those symbols:

Open for log
E:/VcDevel 
❯ grep 'sorted<7' install/test.txt 
023 00000000 SECT5  notype ()    External     | ??$sorted@$06FUenable_if_default_type@Vc_1@@@Detail@Vc_1@@YQ?AV?$Vector@FUAvx@VectorAbi@Vc_1@@@1@V21@@Z (class Vc_1::Vector<short,struct Vc_1::VectorAbi::Avx> __vectorcall Vc_1::Detail::sorted<7,short,struct Vc_1::enable_if_default_type>(class Vc_1::Vector<short,struct Vc_1::VectorAbi::Avx>))
025 00000000 SECT7  notype ()    External     | ??$sorted@$06GUenable_if_default_type@Vc_1@@@Detail@Vc_1@@YQ?AV?$Vector@GUAvx@VectorAbi@Vc_1@@@1@V21@@Z (class Vc_1::Vector<unsigned short,struct Vc_1::VectorAbi::Avx> __vectorcall Vc_1::Detail::sorted<7,unsigned short,struct Vc_1::enable_if_default_type>(class Vc_1::Vector<unsigned short,struct Vc_1::VectorAbi::Avx>))
026 00000000 SECT9  notype ()    External     | ??$sorted@$06HUenable_if_default_type@Vc_1@@@Detail@Vc_1@@YQ?AV?$Vector@HUAvx@VectorAbi@Vc_1@@@1@V21@@Z (class Vc_1::Vector<int,struct Vc_1::VectorAbi::Avx> __vectorcall Vc_1::Detail::sorted<7,int,struct Vc_1::enable_if_default_type>(class Vc_1::Vector<int,struct Vc_1::VectorAbi::Avx>))
027 00000000 SECTB  notype ()    External     | ??$sorted@$06IUenable_if_default_type@Vc_1@@@Detail@Vc_1@@YQ?AV?$Vector@IUAvx@VectorAbi@Vc_1@@@1@V21@@Z (class Vc_1::Vector<unsigned int,struct Vc_1::VectorAbi::Avx> __vectorcall Vc_1::Detail::sorted<7,unsigned int,struct Vc_1::enable_if_default_type>(class Vc_1::Vector<unsigned int,struct Vc_1::VectorAbi::Avx>))
028 00000000 SECTD  notype ()    External     | ??$sorted@$06MUenable_if_default_type@Vc_1@@@Detail@Vc_1@@YQ?AV?$Vector@MUAvx@VectorAbi@Vc_1@@@1@V21@@Z (class Vc_1::Vector<float,struct Vc_1::VectorAbi::Avx> __vectorcall Vc_1::Detail::sorted<7,float,struct Vc_1::enable_if_default_type>(class Vc_1::Vector<float,struct Vc_1::VectorAbi::Avx>))
029 00000000 SECTF  notype ()    External     | ??$sorted@$06NUenable_if_default_type@Vc_1@@@Detail@Vc_1@@YQ?AV?$Vector@NUAvx@VectorAbi@Vc_1@@@1@V21@@Z (class Vc_1::Vector<double,struct Vc_1::VectorAbi::Avx> __vectorcall Vc_1::Detail::sorted<7,double,struct Vc_1::enable_if_default_type>(class Vc_1::Vector<double,struct Vc_1::VectorAbi::Avx>))
01B 00000000 SECT3  notype ()    External     | ??$sorted@$06F@Detail@Vc_1@@YQ?AV?$Vector@FUSse@VectorAbi@Vc_1@@@1@V21@@Z (class Vc_1::Vector<short,struct Vc_1::VectorAbi::Sse> 
__vectorcall Vc_1::Detail::sorted<7,short>(class Vc_1::Vector<short,struct Vc_1::VectorAbi::Sse>))
01C 00000000 SECT5  notype ()    External     | ??$sorted@$06G@Detail@Vc_1@@YQ?AV?$Vector@GUSse@VectorAbi@Vc_1@@@1@V21@@Z (class Vc_1::Vector<unsigned short,struct Vc_1::VectorAbi::Sse> __vectorcall Vc_1::Detail::sorted<7,unsigned short>(class Vc_1::Vector<unsigned short,struct Vc_1::VectorAbi::Sse>))
01D 00000000 SECT7  notype ()    External     | ??$sorted@$06H@Detail@Vc_1@@YQ?AV?$Vector@HUSse@VectorAbi@Vc_1@@@1@V21@@Z (class Vc_1::Vector<int,struct Vc_1::VectorAbi::Sse> __vectorcall Vc_1::Detail::sorted<7,int>(class Vc_1::Vector<int,struct Vc_1::VectorAbi::Sse>))
01E 00000000 SECT9  notype ()    External     | ??$sorted@$06I@Detail@Vc_1@@YQ?AV?$Vector@IUSse@VectorAbi@Vc_1@@@1@V21@@Z (class Vc_1::Vector<unsigned int,struct Vc_1::VectorAbi::Sse> __vectorcall Vc_1::Detail::sorted<7,unsigned int>(class Vc_1::Vector<unsigned int,struct Vc_1::VectorAbi::Sse>))
01F 00000000 SECTB  notype ()    External     | ??$sorted@$06M@Detail@Vc_1@@YQ?AV?$Vector@MUSse@VectorAbi@Vc_1@@@1@V21@@Z (class Vc_1::Vector<float,struct Vc_1::VectorAbi::Sse> 
__vectorcall Vc_1::Detail::sorted<7,float>(class Vc_1::Vector<float,struct Vc_1::VectorAbi::Sse>))

E:/VcDevel 
❯ grep 'CpuId::init' install/test.txt
013 00000000 UNDEF  notype ()    External     | ?init@CpuId@Vc_1@@SQXXZ (public: static void __vectorcall Vc_1::CpuId::init(void))
031 00000000 SECT7  notype ()    External     | ?init@CpuId@Vc_1@@SQXXZ (public: static void __vectorcall Vc_1::CpuId::init(void))
096 00000000 SECT13 notype       Static       | ?done@?2??init@CpuId@Vc_1@@SQXXZ@4_NA (bool `public: static void __vectorcall Vc_1::CpuId::init(void)'::`3'::done)

E:/VcDevel 
❯ grep 'isImplementationSupported' install/test.txt
015 00000000 SECT7  notype ()    External     | ?isImplementationSupported@Vc_1@@YQ_NW4Implementation@1@@Z (bool __vectorcall Vc_1::isImplementationSupported(enum Vc_1::Implementation))
025 00000000 SECT9  notype       Static       | $unwind$?isImplementationSupported@Vc_1@@YQ_NW4Implementation@1@@Z
028 00000000 SECTA  notype       Static       | $pdata$?isImplementationSupported@Vc_1@@YQ_NW4Implementation@1@@Z

All the functions are being specified as __vectorcall at compile time.

@bernhardmgruber
Copy link
Collaborator

There was a discussion on __vectorcall a while back: #147, but I am far too new on the project to know anything.
I believe __vectorcall is specified by default because /Gv is added as switch to MSVC, see: https://github.com/VcDevel/Vc/blob/1.4/cmake/VcMacros.cmake#L340.
It was added here: 65b58e7.

I honestly don't know why we default to __vectorcall, but I believe I read something about the compiler failing to pass function arguments, which are vectors, through registers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants