Bug 91806

Summary: configure does not test whether assembler supports sse4.1
Product: Mesa Reporter: Jonathan Gray <jsg>
Component: Mesa coreAssignee: mesa-dev
Status: RESOLVED FIXED QA Contact: mesa-dev
Severity: normal    
Priority: medium    
Version: git   
Hardware: Other   
OS: OpenBSD   
Whiteboard:
i915 platform: i915 features:

Description Jonathan Gray 2015-08-30 08:47:17 UTC
The sse4.1 test does not seem to check whether the code can be assembled.
Changing AC_COMPILE_IFELSE to AC_LINK_IFELSE does not seem to change this.

With gcc 4.9 and binutils 2.17 which does not include sse4.1 instructions:

libtool: compile:  /usr/local/bin/egcc -DPACKAGE_NAME=\"Mesa\" -DPACKAGE_TARNAME=\"mesa\" -DPACKAGE_VERSION=\"11.1.0-devel\" "-DPACKAGE_STRING=\"Mesa 11.1.0-devel\"" "-DPACKAGE_BUGREPORT=\"https://bugs.freedesktop.org/enter_bug.cgi?product=Mesa\"" -DPACKAGE_URL=\"\" -DPACKAGE=\"mesa\" -DVERSION=\"11.1.0-devel\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DYYTEXT_POINTER=1 -DHAVE___BUILTIN_BSWAP32=1 -DHAVE___BUILTIN_BSWAP64=1 -DHAVE___BUILTIN_CLZ=1 -DHAVE___BUILTIN_CLZLL=1 -DHAVE___BUILTIN_CTZ=1 -DHAVE___BUILTIN_EXPECT=1 -DHAVE___BUILTIN_FFS=1 -DHAVE___BUILTIN_FFSLL=1 -DHAVE___BUILTIN_POPCOUNT=1 -DHAVE___BUILTIN_POPCOUNTLL=1 -DHAVE___BUILTIN_UNREACHABLE=1 -DHAVE_FUNC_ATTRIBUTE_CONST=1 -DHAVE_FUNC_ATTRIBUTE_FLATTEN=1 -DHAVE_FUNC_ATTRIBUTE_FORMAT=1 -DHAVE_FUNC_ATTRIBUTE_MALLOC=1 -DHAVE_FUNC_ATTRIBUTE_PACKED=1 -DHAVE_FUNC_ATTRIBUTE_PURE=1 -DHAVE_FUNC_ATTRIBUTE_UNUSED=1 -DHAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT=1 -DHAVE_DLADDR=1 -DHAVE_CLOCK_GETTIME=1 -DHAVE_PTHREAD_PRIO_INHERIT=1 -DHAVE_PTHREAD=1 -DHAVE_SHA1_IN_LIBC=1 -DHAVE_LIBEXPAT=1 -I. -D__STDC_LIMIT_MACROS -DUSE_SSE41 -DDEBUG -DUSE_X86_64_ASM -DHAVE_SYS_SYSCTL_H -DHAVE_STRTOF -DHAVE_MKOSTEMP -DHAVE_DLOPEN -DHAVE_POSIX_MEMALIGN -DHAVE_LIBDRM -DGLX_USE_DRM -DGLX_INDIRECT_RENDERING -DGLX_DIRECT_RENDERING -DHAVE_ALIAS -DHAVE_MINCORE -DHAVE_LLVM=0x0305 -DMESA_LLVM_VERSION_PATCH=0 -I../../include -I../../src -I../../src/glsl -I../../src/glsl -I../../src/glsl/nir -I../../src/glsl/glcpp -I../../src/mesa -I../../src/mesa -I../../src/mesa/main -I../../src/mesa/main -I../../src/mapi -I../../src/mapi -I../../src/gallium/include -I../../src/gallium/auxiliary -I./x86-64 -I./x86-64 -I/usr/local/include -I/usr/local/include/libelf -I/usr/local/include -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -fvisibility=hidden -Werror=pointer-arith -Werror=vla -msse4.1 -g -O2 -Wall -std=c99 -Werror=implicit-function-declaration -Werror=missing-prototypes -fno-strict-aliasing -fno-math-errno -fno-trapping-math -fno-builtin-memcmp -MT main/libmesa_sse41_la-streaming-load-memcpy.lo -MD -MP -MF main/.deps/libmesa_sse41_la-streaming-load-memcpy.Tpo -c main/streaming-load-memcpy.c  -fPIC -DPIC -o main/.libs/libmesa_sse41_la-streaming-load-memcpy.o
/tmp//ccVTPiZC.s: Assembler messages:
/tmp//ccVTPiZC.s:50: Error: no such instruction: `movntdqa (%rcx),%xmm3'
/tmp//ccVTPiZC.s:66: Error: no such instruction: `movntdqa -48(%rcx),%xmm2'
/tmp//ccVTPiZC.s:71: Error: no such instruction: `movntdqa -32(%rcx),%xmm1'
/tmp//ccVTPiZC.s:76: Error: no such instruction: `movntdqa -16(%rcx),%xmm0'
Makefile:2755: recipe for target 'main/libmesa_sse41_la-streaming-load-memcpy.lo' failed

from config.log:

configure:19147: /usr/local/bin/egcc -c -msse4.1 -g -O2 -Wall -std=c99 -Werror=implicit-function-declaration -Werror=missing-prototypes -fno-strict-aliasing -fno-math-errno -fno-trapping-math -fno-builtin-memcmp -I/usr/local/include -I/usr/local/include/libelf conftest.c >&5
conftest.c: In function 'main':
conftest.c:46:61: warning: variable 'c' set but not used [-Wunused-but-set-variable]
     __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
                                                             ^
configure:19147: $? = 0

$ cat t.c                                                                 
#include <smmintrin.h>
int main () {
    __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
    c = _mm_max_epu32(a, b);
    return 0;
}
$ egcc -Wall -msse4.1 t.c 
t.c: In function 'main':
t.c:3:61: warning: variable 'c' set but not used [-Wunused-but-set-variable]
     __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
                                                             ^
/tmp//ccpOR1qO.s: Assembler messages:
/tmp//ccpOR1qO.s:24: Error: no such instruction: `pinsrd $1,%eax,%xmm1'
/tmp//ccpOR1qO.s:27: Error: no such instruction: `pinsrd $1,%eax,%xmm0'
/tmp//ccpOR1qO.s:44: Error: no such instruction: `pinsrd $1,%eax,%xmm1'
/tmp//ccpOR1qO.s:47: Error: no such instruction: `pinsrd $1,%eax,%xmm0'
/tmp//ccpOR1qO.s:58: Error: no such instruction: `pmaxud %xmm1,%xmm0'
Comment 1 Emil Velikov 2015-12-04 16:53:00 UTC
In the failing case does gcc return a non zero value ?

I'm leaning that this is some sort of GCC/autotools bug as to the best of my knowledge we're doing things the "right way" (almost identical hunk is being used in pixman and other projects).

That aside if you have some ideas how we can improve things please let us know.
Comment 2 Jonathan Gray 2015-12-04 17:36:20 UTC
gcc returns 1.  I tried various changes to configure.ac but didn't get anywhere.
Comment 3 Matt Turner 2015-12-07 20:23:22 UTC
It might be as simple as changing AC_COMPILE_IFELSE -> AC_LINK_IFELSE
Comment 4 Jonathan Gray 2015-12-08 03:02:05 UTC
As mentioned in the initial report I tried that.  It seems the test somehow returns 0 not 1?

configure:19269: /usr/local/bin/egcc -o conftest -msse4.1 -g -O2 -Wall -std=c99 -Werror=implicit-function-declaration -Werror=missing-prototypes -fno
-strict-aliasing -fno-math-errno -fno-trapping-math -fno-builtin-memcmp -I/usr/local/include -I/usr/local/include/libelf -L/usr/local/lib conftest.c
 >&5
conftest.c: In function 'main':
conftest.c:46:61: warning: variable 'c' set but not used [-Wunused-but-set-variable]
     __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
                                                             ^
configure:19269: $? = 0

 19251	SSE41_CFLAGS="-msse4.1"
 19252	case "$target_cpu" in
 19253	i?86)
 19254	    SSE41_CFLAGS="$SSE41_CFLAGS -mstackrealign"
 19255	    ;;
 19256	esac
 19257	save_CFLAGS="$CFLAGS"
 19258	CFLAGS="$SSE41_CFLAGS $CFLAGS"
 19259	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 19260	/* end confdefs.h.  */
 19261	
 19262	#include <smmintrin.h>
 19263	int main () {
 19264	    __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
 19265	    c = _mm_max_epu32(a, b);
 19266	    return 0;
 19267	}
 19268	_ACEOF
 19269	if ac_fn_c_try_link "$LINENO"; then :
 19270	  SSE41_SUPPORTED=1
 19271	fi
 19272	rm -f core conftest.err conftest.$ac_objext \
 19273	    conftest$ac_exeext conftest.$ac_ext
 19274	CFLAGS="$save_CFLAGS"
 19275	if test "x$SSE41_SUPPORTED" = x1; then
 19276	    DEFINES="$DEFINES -DUSE_SSE41"
 19277	fi
 19278	 if test x$SSE41_SUPPORTED = x1; then
 19279	  SSE41_SUPPORTED_TRUE=
 19280	  SSE41_SUPPORTED_FALSE='#'
 19281	else
 19282	  SSE41_SUPPORTED_TRUE='#'
 19283	  SSE41_SUPPORTED_FALSE=
 19284	fi
 19285	
 19286	SSE41_CFLAGS=$SSE41_CFLAGS

The if ac_fn_c_try_link "$LINENO" path is taken and SSE41_SUPPORTED is set to 1.

conftest.c has

/* confdefs.h */
#define PACKAGE_NAME "Mesa"
#define PACKAGE_TARNAME "mesa"
#define PACKAGE_VERSION "11.2.0-devel"
#define PACKAGE_STRING "Mesa 11.2.0-devel"
#define PACKAGE_BUGREPORT "https://bugs.freedesktop.org/enter_bug.cgi?product=Mesa"
#define PACKAGE_URL ""
#define PACKAGE "mesa"
#define VERSION "11.2.0-devel"
#define STDC_HEADERS 1
#define HAVE_SYS_TYPES_H 1
#define HAVE_SYS_STAT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRING_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STRINGS_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_STDINT_H 1
#define HAVE_UNISTD_H 1
#define HAVE_DLFCN_H 1
#define LT_OBJDIR ".libs/"
#define YYTEXT_POINTER 1
#define HAVE___BUILTIN_BSWAP32 1
#define HAVE___BUILTIN_BSWAP64 1
#define HAVE___BUILTIN_CLZ 1
#define HAVE___BUILTIN_CLZLL 1
#define HAVE___BUILTIN_CTZ 1
#define HAVE___BUILTIN_EXPECT 1
#define HAVE___BUILTIN_FFS 1
#define HAVE___BUILTIN_FFSLL 1
#define HAVE___BUILTIN_POPCOUNT 1
#define HAVE___BUILTIN_POPCOUNTLL 1
#define HAVE___BUILTIN_UNREACHABLE 1
#define HAVE_FUNC_ATTRIBUTE_CONST 1
#define HAVE_FUNC_ATTRIBUTE_FLATTEN 1
#define HAVE_FUNC_ATTRIBUTE_FORMAT 1
#define HAVE_FUNC_ATTRIBUTE_MALLOC 1
#define HAVE_FUNC_ATTRIBUTE_PACKED 1
#define HAVE_FUNC_ATTRIBUTE_PURE 1
#define HAVE_FUNC_ATTRIBUTE_UNUSED 1
#define HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT 1
/* end confdefs.h.  */

#include <smmintrin.h>
int main () {
    __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
    c = _mm_max_epu32(a, b);
    return 0;
}

ac_fn_c_try_link seems to run

$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS

/usr/local/bin/egcc -o conftest -msse4.1 -g -O2 -Wall -std=c99 -Werror=impli\
cit-function-declaration -Werror=missing-prototypes -fno-strict-aliasing -fno-math-errno -fno\
-trapping-math -fno-builtin-memcmp -I/usr/local/include -/usr/local/include/libelf -L/usr/lo\
cal/lib conftest.c

And it returns 0 when run that way:

 29531 sh       ARGS  
        [0] = "/usr/local/bin/egcc"
        [1] = "-o"
        [2] = "conftest"
        [3] = "-msse4.1"
        [4] = "-g"
        [5] = "-O2"
        [6] = "-Wall"
        [7] = "-std=c99"
        [8] = "-Werror=implicit-function-declaration"
        [9] = "-Werror=missing-prototypes"
        [10] = "-fno-strict-aliasing"
        [11] = "-fno-math-errno"
        [12] = "-fno-trapping-math"
        [13] = "-fno-builtin-memcmp"
        [14] = "-I/usr/local/include"
        [15] = "-I/usr/local/include/libelf"
        [16] = "-L/usr/local/lib"
        [17] = "conftest.c"
 29531 egcc     NAMI  "/usr/libexec/ld.so"
 29531 egcc     RET   execve 0

It turns out gcc helpfully optimises out the sse4.1 call with -O1 or greater.

$ egcc -msse4.1 -O1 conftest.c
$ echo $?
0

$ egcc -msse4.1 -O0 conftest.c 
/tmp//cc6UU7Rt.s: Assembler messages:
/tmp//cc6UU7Rt.s:24: Error: no such instruction: `pinsrd $1,%eax,%xmm1'
/tmp//cc6UU7Rt.s:27: Error: no such instruction: `pinsrd $1,%eax,%xmm0'
/tmp//cc6UU7Rt.s:44: Error: no such instruction: `pinsrd $1,%eax,%xmm1'
/tmp//cc6UU7Rt.s:47: Error: no such instruction: `pinsrd $1,%eax,%xmm0'
/tmp//cc6UU7Rt.s:58: Error: no such instruction: `pmaxud %xmm1,%xmm0'
$ echo $?                      
1
Comment 5 Jonathan Gray 2015-12-19 04:22:16 UTC
fixed in 6e44bbe0f5496b1aea2b4a29adae7990b62fda33

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.