On Thu, Apr 25, 2013 at 12:41 PM, Joseph S. Myers <jos...@codesourcery.com> wrote: > On Tue, 16 Apr 2013, Sriraman Tallam wrote: > >> Ok, it is on by default now. There is a way to turn it off, with >> -mno-generate-builtins. > > Any new option needs documenting in invoke.texi.
Added and new patch attached. Thanks Sri > > -- > Joseph S. Myers > jos...@codesourcery.com
* config/i386/i386.c (construct_container): Do not issue SSE return error for extern gnu_inline functions. (def_builtin): Do not generate builtins when -mno-generate-builtins is used. * doc/invoke.texi: Document option -mgenerate-builtins. * config/i386/i386.opt (mgenerate-builtins): New target option. * config/i386/i386-c.c (ix86_target_macros_internal): Define macro __ALL_ISA__ when generate_target_builtins is true. * testsuite/gcc.target/i386/intrinsics_1.c: New test. * testsuite/gcc.target/i386/intrinsics_2.c: Ditto. * testsuite/gcc.target/i386/intrinsics_3.c: Ditto. * testsuite/gcc.target/i386/intrinsics_4.c: Ditto. * testsuite/gcc.target/i386/intrinsics_5.c: Ditto. * config/i386/lzcntintrin.h: Expose header when __ALL_ISA__ is defined. * config/i386/lwpintrin.h: Ditto. * config/i386/xopintrin.h: Ditto. * config/i386/fmaintrin.h: Ditto. * config/i386/bmiintrin.h: Ditto. * config/i386/fma4intrin.h: Ditto. * config/i386/nmmintrin.h: Ditto. * config/i386/tbmintrin.h: Ditto. * config/i386/smmintrin.h: Ditto. * config/i386/wmmintrin.h: Ditto. * config/i386/popcntintrin.h: Ditto. * config/i386/f16cintrin.h: Ditto. * config/i386/pmmintrin.h: Ditto. * config/i386/bmi2intrin.h: Ditto. * config/i386/tmmintrin.h: Ditto. * config/i386/xmmintrin.h: Ditto. * config/i386/mmintrin.h: Ditto. * config/i386/ammintrin.h: Ditto. * config/i386/emmintrin.h: Ditto. Index: config/i386/smmintrin.h =================================================================== --- config/i386/smmintrin.h (revision 198212) +++ config/i386/smmintrin.h (working copy) @@ -27,7 +27,7 @@ #ifndef _SMMINTRIN_H_INCLUDED #define _SMMINTRIN_H_INCLUDED -#ifndef __SSE4_1__ +#if !defined (__SSE4_1__) && !defined (__ALL_ISA__) # error "SSE4.1 instruction set not enabled" #else Index: config/i386/f16cintrin.h =================================================================== --- config/i386/f16cintrin.h (revision 198212) +++ config/i386/f16cintrin.h (working copy) @@ -25,7 +25,7 @@ # error "Never use <f16intrin.h> directly; include <x86intrin.h> or <immintrin.h> instead." #endif -#ifndef __F16C__ +#if !defined (__F16C__) && !defined (__ALL_ISA__) # error "F16C instruction set not enabled" #else Index: config/i386/wmmintrin.h =================================================================== --- config/i386/wmmintrin.h (revision 198212) +++ config/i386/wmmintrin.h (working copy) @@ -30,7 +30,7 @@ /* We need definitions from the SSE2 header file. */ #include <emmintrin.h> -#if !defined (__AES__) && !defined (__PCLMUL__) +#if !defined (__AES__) && !defined (__PCLMUL__) && !defined (__ALL_ISA__) # error "AES/PCLMUL instructions not enabled" #else Index: config/i386/bmi2intrin.h =================================================================== --- config/i386/bmi2intrin.h (revision 198212) +++ config/i386/bmi2intrin.h (working copy) @@ -25,7 +25,7 @@ # error "Never use <bmi2intrin.h> directly; include <x86intrin.h> instead." #endif -#ifndef __BMI2__ +#if !defined (__BMI2__) && !defined (__ALL_ISA__) # error "BMI2 instruction set not enabled" #endif /* __BMI2__ */ Index: config/i386/pmmintrin.h =================================================================== --- config/i386/pmmintrin.h (revision 198212) +++ config/i386/pmmintrin.h (working copy) @@ -27,7 +27,7 @@ #ifndef _PMMINTRIN_H_INCLUDED #define _PMMINTRIN_H_INCLUDED -#ifndef __SSE3__ +#if !defined (__SSE3__) && !defined (__ALL_ISA__) # error "SSE3 instruction set not enabled" #else Index: config/i386/lzcntintrin.h =================================================================== --- config/i386/lzcntintrin.h (revision 198212) +++ config/i386/lzcntintrin.h (working copy) @@ -25,7 +25,7 @@ # error "Never use <lzcntintrin.h> directly; include <x86intrin.h> instead." #endif -#ifndef __LZCNT__ +#if !defined (__LZCNT__) && !defined (__ALL_ISA__) # error "LZCNT instruction is not enabled" #endif /* __LZCNT__ */ Index: config/i386/tmmintrin.h =================================================================== --- config/i386/tmmintrin.h (revision 198212) +++ config/i386/tmmintrin.h (working copy) @@ -27,7 +27,7 @@ #ifndef _TMMINTRIN_H_INCLUDED #define _TMMINTRIN_H_INCLUDED -#ifndef __SSSE3__ +#if !defined (__SSSE3__) && !defined (__ALL_ISA__) # error "SSSE3 instruction set not enabled" #else Index: config/i386/xmmintrin.h =================================================================== --- config/i386/xmmintrin.h (revision 198212) +++ config/i386/xmmintrin.h (working copy) @@ -27,7 +27,7 @@ #ifndef _XMMINTRIN_H_INCLUDED #define _XMMINTRIN_H_INCLUDED -#ifndef __SSE__ +#if !defined (__SSE__) && !defined (__ALL_ISA__) # error "SSE instruction set not enabled" #else Index: config/i386/i386.c =================================================================== --- config/i386/i386.c (revision 198212) +++ config/i386/i386.c (working copy) @@ -6384,8 +6384,13 @@ construct_container (enum machine_mode mode, enum return NULL; /* We allowed the user to turn off SSE for kernel mode. Don't crash if - some less clueful developer tries to use floating-point anyway. */ - if (needed_sseregs && !TARGET_SSE) + some less clueful developer tries to use floating-point anyway. It is + alright if this is in a extern "gnu_inline" function, as it is the + caller that matters in this case. */ + if (needed_sseregs && !TARGET_SSE + && !(DECL_EXTERNAL (current_function_decl) + && lookup_attribute ("gnu_inline", + DECL_ATTRIBUTES (current_function_decl)) != NULL)) { if (in_return) { @@ -26823,7 +26828,8 @@ def_builtin (HOST_WIDE_INT mask, const char *name, ix86_builtins_isa[(int) code].isa = mask; mask &= ~OPTION_MASK_ISA_64BIT; - if (mask == 0 + if (generate_target_builtins + || mask == 0 || (mask & ix86_isa_flags) != 0 || (lang_hooks.builtin_function == lang_hooks.builtin_function_ext_scope)) Index: config/i386/ammintrin.h =================================================================== --- config/i386/ammintrin.h (revision 198212) +++ config/i386/ammintrin.h (working copy) @@ -27,7 +27,7 @@ #ifndef _AMMINTRIN_H_INCLUDED #define _AMMINTRIN_H_INCLUDED -#ifndef __SSE4A__ +#if !defined (__SSE4A__) && !defined (__ALL_ISA__) # error "SSE4A instruction set not enabled" #else Index: config/i386/emmintrin.h =================================================================== --- config/i386/emmintrin.h (revision 198212) +++ config/i386/emmintrin.h (working copy) @@ -27,7 +27,7 @@ #ifndef _EMMINTRIN_H_INCLUDED #define _EMMINTRIN_H_INCLUDED -#ifndef __SSE2__ +#if !defined (__SSE2__) && !defined (__ALL_ISA__) # error "SSE2 instruction set not enabled" #else Index: config/i386/lwpintrin.h =================================================================== --- config/i386/lwpintrin.h (revision 198212) +++ config/i386/lwpintrin.h (working copy) @@ -28,7 +28,7 @@ #ifndef _LWPINTRIN_H_INCLUDED #define _LWPINTRIN_H_INCLUDED -#ifndef __LWP__ +#if !defined (__LWP__) && !defined (__ALL_ISA__) # error "LWP instruction set not enabled" #else Index: config/i386/xopintrin.h =================================================================== --- config/i386/xopintrin.h (revision 198212) +++ config/i386/xopintrin.h (working copy) @@ -28,7 +28,7 @@ #ifndef _XOPMMINTRIN_H_INCLUDED #define _XOPMMINTRIN_H_INCLUDED -#ifndef __XOP__ +#if !defined (__XOP__) && !defined (__ALL_ISA__) # error "XOP instruction set not enabled" #else Index: config/i386/mmintrin.h =================================================================== --- config/i386/mmintrin.h (revision 198212) +++ config/i386/mmintrin.h (working copy) @@ -27,7 +27,7 @@ #ifndef _MMINTRIN_H_INCLUDED #define _MMINTRIN_H_INCLUDED -#ifndef __MMX__ +#if !defined (__MMX__) && !defined (__ALL_ISA__) # error "MMX instruction set not enabled" #else /* The Intel API is flexible enough that we must allow aliasing with other Index: config/i386/i386-c.c =================================================================== --- config/i386/i386-c.c (revision 198212) +++ config/i386/i386-c.c (working copy) @@ -54,6 +54,9 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_fla int last_arch_char = ix86_arch_string[arch_len - 1]; int last_tune_char = ix86_tune_string[tune_len - 1]; + if (generate_target_builtins) + def_or_undef (parse_in, "__ALL_ISA__"); + /* Built-ins based on -march=. */ switch (arch) { Index: config/i386/i386.opt =================================================================== --- config/i386/i386.opt (revision 198212) +++ config/i386/i386.opt (working copy) @@ -640,3 +640,7 @@ Enum(stack_protector_guard) String(tls) Value(SSP_ EnumValue Enum(stack_protector_guard) String(global) Value(SSP_GLOBAL) + +mgenerate-builtins +Target Report Var(generate_target_builtins) Save Init(1) +Generate all target builtins that are otherwise only generated when the appropriate ISA is turned on. Index: config/i386/fma4intrin.h =================================================================== --- config/i386/fma4intrin.h (revision 198212) +++ config/i386/fma4intrin.h (working copy) @@ -28,7 +28,7 @@ #ifndef _FMA4INTRIN_H_INCLUDED #define _FMA4INTRIN_H_INCLUDED -#ifndef __FMA4__ +#if !defined (__FMA4__) && !defined (__ALL_ISA__) # error "FMA4 instruction set not enabled" #else Index: config/i386/popcntintrin.h =================================================================== --- config/i386/popcntintrin.h (revision 198212) +++ config/i386/popcntintrin.h (working copy) @@ -21,7 +21,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef __POPCNT__ +#if !defined (__POPCNT__) && !defined (__ALL_ISA__) # error "POPCNT instruction set not enabled" #endif /* __POPCNT__ */ Index: config/i386/fmaintrin.h =================================================================== --- config/i386/fmaintrin.h (revision 198212) +++ config/i386/fmaintrin.h (working copy) @@ -28,7 +28,7 @@ #ifndef _FMAINTRIN_H_INCLUDED #define _FMAINTRIN_H_INCLUDED -#ifndef __FMA__ +#if !defined (__FMA__) && !defined (__ALL_ISA__) # error "FMA instruction set not enabled" #else Index: config/i386/bmiintrin.h =================================================================== --- config/i386/bmiintrin.h (revision 198212) +++ config/i386/bmiintrin.h (working copy) @@ -25,7 +25,7 @@ # error "Never use <bmiintrin.h> directly; include <x86intrin.h> instead." #endif -#ifndef __BMI__ +#if !defined (__BMI__) && !defined (__ALL_ISA__) # error "BMI instruction set not enabled" #endif /* __BMI__ */ Index: config/i386/nmmintrin.h =================================================================== --- config/i386/nmmintrin.h (revision 198212) +++ config/i386/nmmintrin.h (working copy) @@ -27,7 +27,7 @@ #ifndef _NMMINTRIN_H_INCLUDED #define _NMMINTRIN_H_INCLUDED -#ifndef __SSE4_2__ +#if !defined (__SSE4_2__) && !defined (__ALL_ISA__) # error "SSE4.2 instruction set not enabled" #else /* We just include SSE4.1 header file. */ Index: config/i386/tbmintrin.h =================================================================== --- config/i386/tbmintrin.h (revision 198212) +++ config/i386/tbmintrin.h (working copy) @@ -25,7 +25,7 @@ # error "Never use <tbmintrin.h> directly; include <x86intrin.h> instead." #endif -#ifndef __TBM__ +#if !defined (__TBM__) && !defined (__ALL_ISA__) # error "TBM instruction set not enabled" #endif /* __TBM__ */ Index: testsuite/gcc.target/i386/intrinsics_3.c =================================================================== --- testsuite/gcc.target/i386/intrinsics_3.c (revision 0) +++ testsuite/gcc.target/i386/intrinsics_3.c (revision 0) @@ -0,0 +1,11 @@ +/* Using vector types without SSE enabled should generate an error. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-sse" } */ + +typedef long long _m128i __attribute__((vector_size(16),__may_alias__)); + +int foo (_m128i V) /* { dg-warning "SSE vector argument without SSE enabled changes the ABI" } */ +{ + return 0; +} Index: testsuite/gcc.target/i386/intrinsics_4.c =================================================================== --- testsuite/gcc.target/i386/intrinsics_4.c (revision 0) +++ testsuite/gcc.target/i386/intrinsics_4.c (revision 0) @@ -0,0 +1,11 @@ +/* Test to check if a target specific builtin used in a function without the + appropriate ISA support generates an error. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-sse4.1" } */ + +#include <smmintrin.h> +__m128i foo(__m128i *V) +{ + return __builtin_ia32_movntdqa (V); /* { dg-error "'__builtin_ia32_movntdqa' needs isa option -m32 -msse4.1" } */ +} Index: testsuite/gcc.target/i386/intrinsics_1.c =================================================================== --- testsuite/gcc.target/i386/intrinsics_1.c (revision 0) +++ testsuite/gcc.target/i386/intrinsics_1.c (revision 0) @@ -0,0 +1,13 @@ +/* Test case to check if intrinsics and function specific target + optimizations work together. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -msse -mno-sse4.1" } */ + +#include <smmintrin.h> + +__attribute__((target("sse4.1"))) +__m128i foo(__m128i *V) +{ + return _mm_stream_load_si128(V); +} Index: testsuite/gcc.target/i386/intrinsics_5.c =================================================================== --- testsuite/gcc.target/i386/intrinsics_5.c (revision 0) +++ testsuite/gcc.target/i386/intrinsics_5.c (revision 0) @@ -0,0 +1,13 @@ +/* Test case to check if -mno-generate-builtins will break use of intrinsics + when the appropriate ISA is not specified. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-generate-builtins -mno-sse4.1" } */ + +#include <smmintrin.h> +__m128i foo(__m128i *V) /* { dg-error "unknown type name" } */ +{ + return V; +} + +/* { dg-excess-errors "\"SSE4.1 instruction set not enabled\"" } */ Index: testsuite/gcc.target/i386/intrinsics_2.c =================================================================== --- testsuite/gcc.target/i386/intrinsics_2.c (revision 0) +++ testsuite/gcc.target/i386/intrinsics_2.c (revision 0) @@ -0,0 +1,19 @@ +/* Ok, to have SSE4.1 code in non-SSE4.1 functions marked as + extern, "gnu_inline". */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -msse -mno-sse4.1" } */ + +#include <smmintrin.h> + +extern __inline __attribute__ ((__gnu_inline__)) +__m128i bar (__m128i *V) +{ + return _mm_stream_load_si128(V); +} + +__attribute__((target("sse4.1"))) +__m128i foo(__m128i *V) +{ + return bar (V); +} Index: doc/invoke.texi =================================================================== --- doc/invoke.texi (revision 198212) +++ doc/invoke.texi (working copy) @@ -658,7 +658,8 @@ Objective-C and Objective-C++ Dialects}. -m32 -m64 -mx32 -mlarge-data-threshold=@var{num} @gol -msse2avx -mfentry -m8bit-idiv @gol -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol --mstack-protector-guard=@var{guard}} +-mstack-protector-guard=@var{guard}} @gol +-mgenerate-builtins @emph{i386 and x86-64 Windows Options} @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol @@ -14604,6 +14605,13 @@ locations are @samp{global} for global canary or @ canary in the TLS block (the default). This option has effect only when @option{-fstack-protector} or @option{-fstack-protector-all} is specified. +@item -mgenerate-builtins +@itemx -mno-generate-builtins. +@opindex generate-builtins +Generate all target builtins that are otherwise only generated when the +appropriate ISA is turned on. This is turned on by default. Use +@option{-mno-generate-builtins} to turn this off. + @end table These @samp{-m} switches are supported in addition to the above