On Thu, Apr 25, 2013 at 12:41 PM, Joseph S. Myers
<[email protected]> 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
> [email protected]
* 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