Jeffrey Walton via llvm-dev
2018-Dec-01 10:17 UTC
[llvm-dev] Restrict global constructors to base ISA
I'm testing on older OS X 10.8 with older SSE4 hardware from about
2010. I've got updated gear from MacPorts and it includes GCC and
Clang. GCC is the compiler, and Clang is the assembler.
We perform a compile/link on a test file to ensure an ISA is supported
by the toolchain. If an ISA is available then we compile a source file
to the ISA as needed. Then, we guard the higher ISAs at runtime to
avoid SIGILLs. It worked well until we added AVX2.
For AVX2 we see this as expected:
$ CXX=/opt/local/bin/clang++-mp-5.0 make
/opt/local/bin/clang++-mp-5.0 ... -c chacha.cpp
/opt/local/bin/clang++-mp-5.0 ... -mavx2 -c chacha_avx.cpp
/opt/local/bin/clang++-mp-5.0 ... -msse2 -c chacha_simd.cpp
...
At runtime we catch a SIGILL due to chacha_avx.cpp as shown below. It
looks like global constructors are using instructions from AVX
(vxorps), which is beyond what the machine supports.
How do we tell Clang to use the base ISA for global constructors?
Thanks in advance.
=========
Here's the full command line used for a typical file:
/opt/local/bin/clang++-mp-5.0 -DNDEBUG -g2 -O3 -fPIC -pthread -pipe -c
cryptlib.cpp
Here's the source file. I don't believe it has global data provided by
us: https://github.com/weidai11/cryptopp/blob/master/chacha_avx.cpp
=========
(lldb) r v
...
* thread #1: tid = 0x19f83aa, 0x000000010016ec49
cryptest.exe`_GLOBAL__sub_I_chacha_avx.cpp at string:1322, queue
'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION
(code=EXC_I386_INVOP, subcode=0x0)
frame #0: 0x000000010016ec49
cryptest.exe`_GLOBAL__sub_I_chacha_avx.cpp at string:1322
1319 {
1320 size_type (&__a)[__n_words] = __r_.first().__r.__words;
1321 for (unsigned __i = 0; __i < __n_words; ++__i)
-> 1322 __a[__i] = 0;
1323 }
1324
1325 template <size_type __a> static
And:
(lldb) disass
cryptest.exe`_GLOBAL__sub_I_chacha_avx.cpp at chacha_avx.cpp:
0x10016ec30: pushq %rbp
0x10016ec31: movq %rsp, %rbp
0x10016ec34: pushq %r14
0x10016ec36: pushq %rbx
0x10016ec37: movq 0x24cf8a(%rip), %rax ; (void
*)0x00000001003e69f0: vtable for CryptoPP::NullNameValuePairs
0x10016ec3e: addq $0x10, %rax
0x10016ec42: movq %rax, 0x2dfb6f(%rip) ;
CryptoPP::s_nullNameValuePairs
-> 0x10016ec49: vxorps %xmm0, %xmm0, %xmm0
0x10016ec4d: vmovups %xmm0, 0x2dfb6b(%rip) ; CryptoPP::DEFAULT_CHANNEL
0x10016ec55: movq $0x0, 0x2dfb70(%rip) ;
CryptoPP::DEFAULT_CHANNEL + 12
0x10016ec60: leaq 0x2dfb59(%rip), %rsi ; CryptoPP::DEFAULT_CHANNEL
0x10016ec67: movq 0x24ba52(%rip), %rbx ; (void
*)0x00007fff8f09321e: std::__1::basic_string<char,
std::__1::char_traits<char>,
std::__1::allocator<char>>::~basic_string()
0x10016ec6e: leaq -0x16ec75(%rip), %r14 ; _mh_execute_header
...
Friedman, Eli via llvm-dev
2018-Dec-03 19:30 UTC
[llvm-dev] Restrict global constructors to base ISA
On 12/1/2018 2:17 AM, Jeffrey Walton via llvm-dev wrote:> I'm testing on older OS X 10.8 with older SSE4 hardware from about > 2010. I've got updated gear from MacPorts and it includes GCC and > Clang. GCC is the compiler, and Clang is the assembler. > > We perform a compile/link on a test file to ensure an ISA is supported > by the toolchain. If an ISA is available then we compile a source file > to the ISA as needed. Then, we guard the higher ISAs at runtime to > avoid SIGILLs. It worked well until we added AVX2. > > For AVX2 we see this as expected: > > $ CXX=/opt/local/bin/clang++-mp-5.0 make > /opt/local/bin/clang++-mp-5.0 ... -c chacha.cpp > /opt/local/bin/clang++-mp-5.0 ... -mavx2 -c chacha_avx.cpp > /opt/local/bin/clang++-mp-5.0 ... -msse2 -c chacha_simd.cpp > ... > > At runtime we catch a SIGILL due to chacha_avx.cpp as shown below. It > looks like global constructors are using instructions from AVX > (vxorps), which is beyond what the machine supports. > > How do we tell Clang to use the base ISA for global constructors?There isn't any way to specifically restrict the ISA for global constructors/inline functions/etc. The inverse works, though: you can specify the base ISA for the whole file, then mark specific functions using __attribute__((target("avx2"))). -Eli -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Jeffrey Walton via llvm-dev
2018-Dec-05 11:28 UTC
[llvm-dev] Restrict global constructors to base ISA
On Mon, Dec 3, 2018 at 2:30 PM Friedman, Eli <efriedma at codeaurora.org> wrote:> ... > > How do we tell Clang to use the base ISA for global constructors? > > There isn't any way to specifically restrict the ISA for global > constructors/inline functions/etc. The inverse works, though: you can > specify the base ISA for the whole file, then mark specific functions > using __attribute__((target("avx2"))).It looks like this is becoming more of a problem as CPU advance and folks try to add multiple implementations. https://stackoverflow.com/a/24136523/608639 . The problem with attributes is, it is too new. They did not appear until GCC 5 for x86_64, and GCC 6 for ARM. They also seem to be missing for some platforms, like MIPS and PowerPC. We support back to GCC 3 and Visual Studio 2002 for our sources so we need something more more available. Jeff
Maybe Matching Threads
- Landing Pad bug?
- Clang 5, UBsan, runtime error: addition of unsigned offset to X overflowed to Y
- Determine reason for failure at -O1
- [LLVMdev] Please benchmark new x86 vector shuffle lowering, planning to make it the default very soon!
- [LLVMdev] Please benchmark new x86 vector shuffle lowering, planning to make it the default very soon!