Bug 56038

Summary: declarations in xmmintrin.h conflict with mingw-w64 intrin.h in c++ mode
Product: gcc Reporter: Erik van Pienbroek <erik-gcc-bugzilla>
Component: targetAssignee: Not yet assigned to anyone <unassigned>
Status: UNCONFIRMED ---    
Severity: normal CC: jacek, jason, jason, ktietz, mkretz, net147, nightstrike, vanboxem.ruben
Priority: P3 Keywords: rejects-valid
Version: 4.8.0   
Target Milestone: ---   
Host: Target: i686-w64-mingw32
Build: gcc 4.8 20130106 snapshot, r194954 Known to work:
Known to fail: Last reconfirmed:
Attachments: Add extern "C" modifier in intrinsics headers for C++

Description Erik van Pienbroek 2013-01-18 22:04:54 UTC
While testing gcc 4.8 (for the target i686-w64-mingw32) I stumbled across a compile failure while trying to build Qt5. Here's a minimal testcase to reproduce this compile failure:

#include <algorithm>
#include <intrin.h>

int main()
{
	return 0;
}

When trying to build this with gcc 4.8 and a recent mingw-w64 trunk snapshot the following error occurs:

$ i686-w64-mingw32-g++ -O2 -msse2 -std=c++11 test.cpp
In file included from /usr/lib64/gcc/i686-w64-mingw32/4.8.0/include/x86intrin.h:34:0,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/bits/opt_random.h:33,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/random:51,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/bits/stl_algo.h:67,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/algorithm:63,
                 from test.cpp:1:
/usr/lib64/gcc/i686-w64-mingw32/4.8.0/include/xmmintrin.h:997:1: error: previous declaration of 'int _m_pextrw(__m64, int)' with 'C++' linkage
 _m_pextrw (__m64 const __A, int const __N)
 ^
In file included from test.cpp:2:0:
/usr/i686-w64-mingw32/sys-root/mingw/include/intrin.h:561:5: error: conflicts with new declaration with 'C' linkage
     __MACHINEX86X_NOX64(int _m_pextrw(__m64,int))
     ^
In file included from /usr/lib64/gcc/i686-w64-mingw32/4.8.0/include/x86intrin.h:34:0,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/bits/opt_random.h:33,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/random:51,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/bits/stl_algo.h:67,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/algorithm:63,
                 from test.cpp:1:
/usr/lib64/gcc/i686-w64-mingw32/4.8.0/include/xmmintrin.h:1018:1: error: previous declaration of '__m64 _m_pinsrw(__m64, int, int)' with 'C++' linkage
 _m_pinsrw (__m64 const __A, int const __D, int const __N)
 ^
In file included from test.cpp:2:0:
/usr/i686-w64-mingw32/sys-root/mingw/include/intrin.h:566:5: error: conflicts with new declaration with 'C' linkage
     __MACHINEX86X_NOX64(__m64 _m_pinsrw(__m64,int,int))
     ^
In file included from /usr/lib64/gcc/i686-w64-mingw32/4.8.0/include/x86intrin.h:34:0,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/bits/opt_random.h:33,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/random:51,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/bits/stl_algo.h:67,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/algorithm:63,
                 from test.cpp:1:
/usr/lib64/gcc/i686-w64-mingw32/4.8.0/include/xmmintrin.h:1119:1: error: previous declaration of '__m64 _m_pshufw(__m64, int)' with 'C++' linkage
 _m_pshufw (__m64 __A, int const __N)
 ^
In file included from test.cpp:2:0:
/usr/i686-w64-mingw32/sys-root/mingw/include/intrin.h:578:5: error: conflicts with new declaration with 'C' linkage
     __MACHINEX86X_NOX64(__m64 _m_pshufw(__m64,int))
     ^
In file included from /usr/lib64/gcc/i686-w64-mingw32/4.8.0/include/x86intrin.h:34:0,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/bits/opt_random.h:33,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/random:51,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/bits/stl_algo.h:67,
                 from /usr/i686-w64-mingw32/sys-root/mingw/include/c++/algorithm:63,
                 from test.cpp:1:
/usr/lib64/gcc/i686-w64-mingw32/4.8.0/include/xmmintrin.h:716:1: error: previous declaration of '__m128 _mm_shuffle_ps(__m128, __m128, int)' with 'C++' linkage
 _mm_shuffle_ps (__m128 __A, __m128 __B, int const __mask)
 ^
In file included from test.cpp:2:0:
/usr/i686-w64-mingw32/sys-root/mingw/include/intrin.h:656:5: error: conflicts with new declaration with 'C' linkage
     __MACHINEX86X_NOIA64(__m128 _mm_shuffle_ps(__m128,__m128,int const))
     ^


The above testcase built fine with gcc 4.7 and the exact same version of mingw-w64, so I consider this a regression in gcc 4.8

With the (pretty straightforward) change below I managed to resolve the issue:

--- gcc/config/i386/xmmintrin.h.orig	2013-01-18 14:57:27.762645582 +0100
+++ gcc/config/i386/xmmintrin.h	2013-01-18 14:58:27.604561940 +0100
@@ -37,6 +37,10 @@
 /* Get _mm_malloc () and _mm_free ().  */
 #include <mm_malloc.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* The Intel API is flexible enough that we must allow aliasing with other
    vector types, and their scalar components.  */
 typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
@@ -1241,6 +1245,10 @@
   (row3) = __builtin_ia32_movhlps (__t3, __t2);				\
 } while (0)
 
+#ifdef __cplusplus
+}
+#endif
+
 /* For backward source compatibility.  */
 #ifdef __SSE2__
 # include <emmintrin.h>


I don't know if this change is the correct fix, but it resolves the qt5 build failure for me.
Comment 1 Matthias Kretz (Vir) 2013-02-15 10:40:46 UTC
I also just came across this issue with GCC 4.7.2 on Windows. It appears that all the intrin.h headers are missing the extern "C" part. Since the functions are always inline and thus the symbols never show up anywhere this has not been a problem before. But now that another header declares those functions a second time something must be done.

Maybe what also needs to happen is that in the mingw environment the intrin.h header does not declare the SSE/AVX intrinsics, but instead includes the proper xxxintrin.h headers.

In any case, I believe the intrinsics should always be declared with C linkage.
Comment 2 Jonathan Liu 2013-03-25 04:12:41 UTC
I can reproduce this with MinGW-w64 GCC 4.8.0 x86 DW2/SJLJ. It does not occur with MinGW-w64 GCC 4.8.0 x86_64 SEH/SJLJ.
Comment 3 Kai Tietz 2013-03-25 08:20:59 UTC
Issue is an old one ... I had even posted already a patch for this subject.  See as reference http://gcc.gnu.org/ml/gcc-patches/2010-03/msg00033.html link.

The only way to solve this in a sane way is by moving it into C namespace for C++.
Comment 4 Jonathan Liu 2013-03-25 10:38:33 UTC
Created attachment 29719 [details]
Add extern "C" modifier in intrinsics headers for C++
Comment 5 Kai Koehne 2013-03-26 12:26:04 UTC
Can confirm that the patch fixes the issue when applied locally.
Comment 6 Kai Koehne 2013-06-10 08:37:50 UTC
The issue is still there with 4.8.1 . It understand that the discussion on Kai Tietz' original patch has stalled ... Any suggestion on how we can move this forward?
Comment 7 Ruben Van Boxem 2013-09-20 07:28:57 UTC
Can this patch please be either applied or rejected for a valid reason?

As far as I understand, something might be "broken" in the compiler wrt inlining:
http://gcc.gnu.org/ml/gcc-patches/2010-03/msg00059.html
which affects this issue indirectly. Nearly three years have passed since the original discussion.
Comment 8 Jacek Caban 2013-09-20 14:36:30 UTC
It would be great if this could be fixed in GCC so that we wouldn't need to work around linkage differences in headers, but this should not be a problem for mingw-w64 since rev 6303, which added a work around to intrin.h.
Comment 9 H.J. Lu 2013-09-20 15:35:31 UTC
Does mingw provide its own SSE/MMX intrinsic implementations?
Can mingw just include <xmmintrin.h> where SSE/MMX instrincis
is needed?
Comment 10 Jason Merrill 2013-09-20 16:07:59 UTC
(In reply to H.J. Lu from comment #9)
> Does mingw provide its own SSE/MMX intrinsic implementations?
> Can mingw just include <xmmintrin.h> where SSE/MMX instrincis
> is needed?

Right.  Why does mingw need to declare these functions itself?
Comment 11 tim.lebedkov 2014-03-22 15:34:22 UTC
Qt 5.2.1 cannot be build in 32 bit with mingw-w64 4.8.2 because of this bug. Why is it not fixed?
Comment 12 Erik van Pienbroek 2014-03-23 19:17:04 UTC
(In reply to tim.lebedkov from comment #11)
> Qt 5.2.1 cannot be build in 32 bit with mingw-w64 4.8.2 because of this bug.
> Why is it not fixed?

A fix for this issue was applied in the intrin.h of mingw-w64 v3.1.0 (which was released in January 2014). Here's the commit in question: http://sourceforge.net/p/mingw-w64/code/6303/ You might want to consider updating your toolchain.

I can't judge whether the fix applied in mingw-w64 is correct or whether something needs to be changed in gcc itself as well. Therefore I'm leaving this bug open for now. If the gcc devs think otherwise feel free to close this bug. Qt5 itself can now be built properly against gcc 4.8.2 and mingw-w64 v3.1.0 without any issues.