#include <immintrin.h> #pragma GCC target ("no-avx") __m256d a, b, c; __m128d d, e, f; void __attribute__ ((__target__ ("avx"), __noinline__)) avx_routine (void) { a = _mm256_andnot_pd (b, c); } void __attribute__ ((__target__ ("sse3"), __noinline__)) sse3_routine (void) { d = _mm_andnot_pd (d, e); } ICEs when compiled with -O2 -mavx: include/avxintrin.h: In function 'avx_routine': include/avxintrin.h:155: error: '__builtin_ia32_andnpd256' needs unknown isa option include/avxintrin.h:155: internal compiler error: in emit_move_insn, at expr.c:3405 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. One issue is the unknown ISA option which can be cured by: --- i386.c.jj22009-04-14 16:33:49.000000000 +0200 +++ i386.c2009-04-16 20:47:05.000000000 +0200 @@ -2350,6 +2350,7 @@ ix86_target_string (int isa, int flags, static struct ix86_target_opts isa_opts[] = { { "-m64",OPTION_MASK_ISA_64BIT }, + { "-mavx",OPTION_MASK_ISA_AVX }, { "-msse5",OPTION_MASK_ISA_SSE5 }, { "-msse4a",OPTION_MASK_ISA_SSE4A }, { "-msse4.2",OPTION_MASK_ISA_SSE4_2 }, @@ -2365,6 +2366,7 @@ ix86_target_string (int isa, int flags, { "-mpopcnt",OPTION_MASK_ISA_POPCNT }, { "-maes",OPTION_MASK_ISA_AES }, { "-mpclmul",OPTION_MASK_ISA_PCLMUL }, + { "-mfma",OPTION_MASK_ISA_FMA } }; /* Flag options. */ But the worse problem is that ix86_valid_target_attribute_tree when the new ix86_isa_flags is the same as def->ix86_isa_flags will just return NULL, which means ix86_isa_flags won't be restored to the state with -mavx enabled when switching to the avx_routine function. I get a different ICE with: -void __attribute__ ((__target__ ("avx"), __noinline__)) +void __attribute__ ((__target__ ("tune=core2", "avx"), __noinline__)) change on the testcase, this time without any reported error.
It also ICEs at -O0 on the trunk: Either: t.c: In function ‘avx_routine’: t.c:11: internal compiler error: in emit_move_insn, at expr.c:3386 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. OR: t.c: In function ‘avx_routine’: t.c:11: internal compiler error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions.
Here is one reduced testcase (an seg fault); typedef double __m256d __attribute__ ((__vector_size__ (32) )); static inline __m256d __attribute__((__always_inline__)) c(){} #pragma GCC target ("no-avx") __m256d a, b; void avx_routine (void) { a = c();}
Created attachment 18458 [details] another testcase Here's another testcase that I just simplified from my attempts to use, in Mozilla, some SSE2 code with runtime detection using CPUID. (See https://bugzilla.mozilla.org/show_bug.cgi?id=506430 and https://bugzilla.mozilla.org/show_bug.cgi?id=513422 .) I'd simplified this testcase before discovering the existing bug report. When I compile this testcase with: /usr/local/gcc-4.4.1/bin/gcc -mno-sse2 ice.c I get: ice.c: In function ‘Convert_ascii_run’: ice.c:11: internal compiler error: in emit_move_insn, at expr.c:3405
Hmm, does the pragma happen before or after the attribute? Because I don't get an ICE on any recent GCC but the code is all rejected.
Looks fully fixed on the trunk, in that we no longer get a warning about the return type of _mm256_andnot_pd while compiling avx_routine . and _mm_andnot_pd is rejected from being inlined from sse3_routine.