From facf0354cfdaa555f376311b9d3c8fec79747f09 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 27 Nov 2018 14:06:48 +0100 Subject: [PATCH] Support simd function declarations via a pre-include. 2018-11-27 Martin Liska * config/gnu-user.h (TARGET_F951_OPTIONS): New. * gcc.c (find_fortran_preinclude_file): New function to handle Fortran pre-include. 2018-11-27 Martin Liska * decl.c (gfc_match_gcc_builtin): New function. * gfortran.h (struct vect_builtin_tuple): New. (gfc_adjust_builtins): Likewise. * lang-specs.h (TARGET_F951_OPTIONS): New. (F951_OPTIONS): Use it. * lang.opt: Add new option -fpre-include. * match.h (gfc_match_gcc_builtin): Declare new function. * parse.c (decode_gcc_attribute): Handle builtin. (parse_progunit): Call gfc_adjust_builtins. * scanner.c (gfc_new_file): Load pre-included header file when provided. * trans-intrinsic.c (add_simd_flag_for_built_in): New. (gfc_adjust_builtins): Likewise. 2018-11-27 Martin Liska * gfortran.dg/simd-builtins-1.f90: New test. * gfortran.dg/simd-builtins-1.h: New test. * gfortran.dg/simd-builtins-2.f90: New test. * gfortran.dg/simd-builtins-3.f90: New test. * gfortran.dg/simd-builtins-3.h: New test. * gfortran.dg/simd-builtins-4.f: New test. * gfortran.dg/simd-builtins-4.h: New test. * gfortran.dg/simd-builtins-5.f: New test. * gfortran.dg/simd-builtins-6.f90: New test. From-SVN: r266509 --- gcc/ChangeLog | 6 ++ gcc/config/gnu-user.h | 4 ++ gcc/fortran/ChangeLog | 16 +++++ gcc/fortran/decl.c | 41 +++++++++++ gcc/fortran/gfortran.h | 22 ++++++ gcc/fortran/lang-specs.h | 10 ++- gcc/fortran/lang.opt | 4 ++ gcc/fortran/match.h | 1 + gcc/fortran/parse.c | 3 + gcc/fortran/scanner.c | 4 ++ gcc/fortran/trans-intrinsic.c | 70 +++++++++++++++++++ gcc/gcc.c | 19 +++++ gcc/testsuite/ChangeLog | 12 ++++ gcc/testsuite/gfortran.dg/simd-builtins-1.f90 | 19 +++++ gcc/testsuite/gfortran.dg/simd-builtins-1.h | 4 ++ gcc/testsuite/gfortran.dg/simd-builtins-2.f90 | 20 ++++++ gcc/testsuite/gfortran.dg/simd-builtins-3.f90 | 1 + gcc/testsuite/gfortran.dg/simd-builtins-3.h | 8 +++ gcc/testsuite/gfortran.dg/simd-builtins-4.f | 1 + gcc/testsuite/gfortran.dg/simd-builtins-4.h | 8 +++ gcc/testsuite/gfortran.dg/simd-builtins-5.f | 9 +++ gcc/testsuite/gfortran.dg/simd-builtins-6.f90 | 24 +++++++ 22 files changed, 304 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/simd-builtins-1.f90 create mode 100644 gcc/testsuite/gfortran.dg/simd-builtins-1.h create mode 100644 gcc/testsuite/gfortran.dg/simd-builtins-2.f90 create mode 100644 gcc/testsuite/gfortran.dg/simd-builtins-3.f90 create mode 100644 gcc/testsuite/gfortran.dg/simd-builtins-3.h create mode 100644 gcc/testsuite/gfortran.dg/simd-builtins-4.f create mode 100644 gcc/testsuite/gfortran.dg/simd-builtins-4.h create mode 100644 gcc/testsuite/gfortran.dg/simd-builtins-5.f create mode 100644 gcc/testsuite/gfortran.dg/simd-builtins-6.f90 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b539e130209..1ecc476d352 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-11-27 Martin Liska + + * config/gnu-user.h (TARGET_F951_OPTIONS): New. + * gcc.c (find_fortran_preinclude_file): New function + to handle Fortran pre-include. + 2018-11-27 Martin Liska * asan.c (asan_emit_stack_protection): Use new enum values diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h index 09170d416b8..3da0c658285 100644 --- a/gcc/config/gnu-user.h +++ b/gcc/config/gnu-user.h @@ -148,3 +148,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see LD_STATIC_OPTION " --whole-archive -llsan --no-whole-archive " \ LD_DYNAMIC_OPTION "}}%{!static-liblsan:-llsan}" #endif + +#undef TARGET_F951_OPTIONS +#define TARGET_F951_OPTIONS "%{!nostdinc:\ + %:fortran-preinclude-file(-fpre-include= math-vector-fortran.h)}" diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 7c15deff07f..06e7400eda7 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,19 @@ +2018-11-27 Martin Liska + + * decl.c (gfc_match_gcc_builtin): New function. + * gfortran.h (struct vect_builtin_tuple): New. + (gfc_adjust_builtins): Likewise. + * lang-specs.h (TARGET_F951_OPTIONS): New. + (F951_OPTIONS): Use it. + * lang.opt: Add new option -fpre-include. + * match.h (gfc_match_gcc_builtin): Declare new function. + * parse.c (decode_gcc_attribute): Handle builtin. + (parse_progunit): Call gfc_adjust_builtins. + * scanner.c (gfc_new_file): Load pre-included header file + when provided. + * trans-intrinsic.c (add_simd_flag_for_built_in): New. + (gfc_adjust_builtins): Likewise. + 2018-11-24 Paul Thomas PR fortran/88143 diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 2b77d950abb..ac8679886af 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -98,6 +98,9 @@ bool gfc_matching_function; /* Set upon parsing a !GCC$ unroll n directive for use in the next loop. */ int directive_unroll = -1; +/* Map of middle-end built-ins that should be vectorized. */ +hash_map *gfc_vectorized_builtins; + /* If a kind expression of a component of a parameterized derived type is parameterized, temporarily store the expression here. */ static gfc_expr *saved_kind_expr = NULL; @@ -11243,3 +11246,41 @@ gfc_match_gcc_unroll (void) gfc_error ("Syntax error in !GCC$ UNROLL directive at %C"); return MATCH_ERROR; } + +/* Match a !GCC$ builtin (b) attributes simd flags form: + + The parameter b is name of a middle-end built-in. + Flags are one of: + - (empty) + - inbranch + - notinbranch + + When we come here, we have already matched the !GCC$ builtin string. */ +match +gfc_match_gcc_builtin (void) +{ + char builtin[GFC_MAX_SYMBOL_LEN + 1]; + + if (gfc_match (" ( %n ) attributes simd", builtin) != MATCH_YES) + return MATCH_ERROR; + + gfc_simd_clause clause = SIMD_NONE; + if (gfc_match (" ( notinbranch ) ") == MATCH_YES) + clause = SIMD_NOTINBRANCH; + else if (gfc_match (" ( inbranch ) ") == MATCH_YES) + clause = SIMD_INBRANCH; + + if (gfc_vectorized_builtins == NULL) + gfc_vectorized_builtins = new hash_map (); + + char *r = XNEWVEC (char, strlen (builtin) + 32); + sprintf (r, "__builtin_%s", builtin); + + bool existed; + int &value = gfc_vectorized_builtins->get_or_insert (r, &existed); + value |= clause; + if (existed) + free (r); + + return MATCH_YES; +} diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 530e00794fb..4dd6298b3dd 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2764,6 +2764,27 @@ bool gfc_in_match_data (void); match gfc_match_char_spec (gfc_typespec *); extern int directive_unroll; +/* SIMD clause enum. */ +enum gfc_simd_clause +{ + SIMD_NONE = (1 << 0), + SIMD_INBRANCH = (1 << 1), + SIMD_NOTINBRANCH = (1 << 2) +}; + +/* Tuple for parsing of vectorized built-ins. */ +struct gfc_vect_builtin_tuple +{ + gfc_vect_builtin_tuple (const char *n, gfc_simd_clause t) + : name (n), simd_type (t) {} + + const char *name; + gfc_simd_clause simd_type; +}; + +/* Map of middle-end built-ins that should be vectorized. */ +extern hash_map *gfc_vectorized_builtins; + /* Handling Parameterized Derived Types */ bool gfc_insert_kind_parameter_exprs (gfc_expr *); bool gfc_insert_parameter_exprs (gfc_expr *, gfc_actual_arglist *); @@ -3502,5 +3523,6 @@ bool gfc_is_reallocatable_lhs (gfc_expr *); /* trans-decl.c */ void finish_oacc_declare (gfc_namespace *, gfc_symbol *, bool); +void gfc_adjust_builtins (void); #endif /* GCC_GFORTRAN_H */ diff --git a/gcc/fortran/lang-specs.h b/gcc/fortran/lang-specs.h index c3ab9700ea7..61a9118d531 100644 --- a/gcc/fortran/lang-specs.h +++ b/gcc/fortran/lang-specs.h @@ -32,9 +32,15 @@ #define F951_CPP_OPTIONS "%{!nocpp: -cpp=%g.f90 %{E} %(cpp_unique_options) \ %{E|M|MM:%(cpp_debug_options) " CPP_ONLY_OPTIONS \ " -fsyntax-only};: " CPP_FORWARD_OPTIONS "}" + +#ifndef TARGET_F951_OPTIONS +#define TARGET_F951_OPTIONS +#endif + #define F951_OPTIONS "%(cc1_options) %{J*} \ - %{!nostdinc:-fintrinsic-modules-path finclude%s}\ - %{!fsyntax-only:%(invoke_as)}" + %{!nostdinc:-fintrinsic-modules-path finclude%s}" \ + TARGET_F951_OPTIONS \ + "%{!fsyntax-only:%(invoke_as)}" #define F951_SOURCE_FORM "%{!ffree-form:-ffixed-form}" diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index ae4957e176c..dc9a94c829c 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -670,6 +670,10 @@ fprotect-parens Fortran Var(flag_protect_parens) Init(-1) Protect parentheses in expressions. +fpre-include= +Fortran RejectNegative Joined Var(flag_pre_include) Undocumented +Path to header file that should be pre-included before each compilation unit. + frange-check Fortran Var(flag_range_check) Init(1) Enable range checking during compilation. diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h index 418542bd5a6..f25ed860c06 100644 --- a/gcc/fortran/match.h +++ b/gcc/fortran/match.h @@ -247,6 +247,7 @@ match gfc_match_dimension (void); match gfc_match_external (void); match gfc_match_gcc_attributes (void); match gfc_match_gcc_unroll (void); +match gfc_match_gcc_builtin (void); match gfc_match_import (void); match gfc_match_intent (void); match gfc_match_intrinsic (void); diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c index 13cc6f5fccd..56d0d050bc3 100644 --- a/gcc/fortran/parse.c +++ b/gcc/fortran/parse.c @@ -1072,6 +1072,7 @@ decode_gcc_attribute (void) match ("attributes", gfc_match_gcc_attributes, ST_ATTR_DECL); match ("unroll", gfc_match_gcc_unroll, ST_NONE); + match ("builtin", gfc_match_gcc_builtin, ST_NONE); /* All else has failed, so give up. See if any of the matchers has stored an error message of some sort. */ @@ -5663,6 +5664,8 @@ parse_progunit (gfc_statement st) gfc_state_data *p; int n; + gfc_adjust_builtins (); + if (gfc_new_block && gfc_new_block->abr_modproc_decl && gfc_new_block->attr.function) diff --git a/gcc/fortran/scanner.c b/gcc/fortran/scanner.c index 2ef32b279fe..a79689a266b 100644 --- a/gcc/fortran/scanner.c +++ b/gcc/fortran/scanner.c @@ -2677,6 +2677,10 @@ gfc_new_file (void) { bool result; + if (flag_pre_include != NULL + && !load_file (flag_pre_include, NULL, false)) + exit (FATAL_EXIT_CODE); + if (gfc_cpp_enabled ()) { result = gfc_cpp_preprocess (gfc_source_file); diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 4ae2b3252b5..40a74916bb8 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -597,7 +597,77 @@ define_quad_builtin (const char *name, tree type, bool is_const) return fndecl; } +/* Add SIMD attribute for FNDECL built-in if the built-in + name is in VECTORIZED_BUILTINS. */ +static void +add_simd_flag_for_built_in (tree fndecl) +{ + if (gfc_vectorized_builtins == NULL + || fndecl == NULL_TREE) + return; + + const char *name = IDENTIFIER_POINTER (DECL_NAME (fndecl)); + int *clauses = gfc_vectorized_builtins->get (name); + if (clauses) + { + for (unsigned i = 0; i < 3; i++) + if (*clauses & (1 << i)) + { + gfc_simd_clause simd_type = (gfc_simd_clause)*clauses; + tree omp_clause = NULL_TREE; + if (simd_type == SIMD_NONE) + ; /* No SIMD clause. */ + else + { + omp_clause_code code + = (simd_type == SIMD_INBRANCH + ? OMP_CLAUSE_INBRANCH : OMP_CLAUSE_NOTINBRANCH); + omp_clause = build_omp_clause (UNKNOWN_LOCATION, code); + omp_clause = build_tree_list (NULL_TREE, omp_clause); + } + + DECL_ATTRIBUTES (fndecl) + = tree_cons (get_identifier ("omp declare simd"), omp_clause, + DECL_ATTRIBUTES (fndecl)); + } + } +} + + /* Set SIMD attribute to all built-in functions that are mentioned + in gfc_vectorized_builtins vector. */ + +void +gfc_adjust_builtins (void) +{ + gfc_intrinsic_map_t *m; + for (m = gfc_intrinsic_map; + m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++) + { + add_simd_flag_for_built_in (m->real4_decl); + add_simd_flag_for_built_in (m->complex4_decl); + add_simd_flag_for_built_in (m->real8_decl); + add_simd_flag_for_built_in (m->complex8_decl); + add_simd_flag_for_built_in (m->real10_decl); + add_simd_flag_for_built_in (m->complex10_decl); + add_simd_flag_for_built_in (m->real16_decl); + add_simd_flag_for_built_in (m->complex16_decl); + add_simd_flag_for_built_in (m->real16_decl); + add_simd_flag_for_built_in (m->complex16_decl); + } + + /* Release all strings. */ + if (gfc_vectorized_builtins != NULL) + { + for (hash_map::iterator it + = gfc_vectorized_builtins->begin (); + it != gfc_vectorized_builtins->end (); ++it) + free (CONST_CAST (char *, (*it).first)); + + delete gfc_vectorized_builtins; + gfc_vectorized_builtins = NULL; + } +} /* Initialize function decls for library functions. The external functions are created as required. Builtin functions are added here. */ diff --git a/gcc/gcc.c b/gcc/gcc.c index afc18b33a15..955a08cc8e8 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -408,6 +408,7 @@ static const char *pass_through_libs_spec_func (int, const char **); static const char *replace_extension_spec_func (int, const char **); static const char *greater_than_spec_func (int, const char **); static const char *debug_level_greater_than_spec_func (int, const char **); +static const char *find_fortran_preinclude_file (int, const char **); static char *convert_white_space (char *); /* The Specs Language @@ -1647,6 +1648,7 @@ static const struct spec_function static_spec_functions[] = { "replace-extension", replace_extension_spec_func }, { "gt", greater_than_spec_func }, { "debug-level-gt", debug_level_greater_than_spec_func }, + { "fortran-preinclude-file", find_fortran_preinclude_file}, #ifdef EXTRA_SPEC_FUNCTIONS EXTRA_SPEC_FUNCTIONS #endif @@ -9894,6 +9896,23 @@ debug_level_greater_than_spec_func (int argc, const char **argv) return NULL; } +/* The function takes 2 arguments: OPTION name and file name. + When the FILE is found by find_file, return OPTION=path_to_file. */ + +static const char * +find_fortran_preinclude_file (int argc, const char **argv) +{ + if (argc != 2) + return NULL; + + const char *path = find_a_file (&include_prefixes, argv[1], R_OK, true); + if (path != NULL) + return concat (argv[0], path, NULL); + + return NULL; +} + + /* Insert backslash before spaces in ORIG (usually a file path), to avoid being broken by spec parser. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9e1f6d05a45..e6bc1f8ce21 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2018-11-27 Martin Liska + + * gfortran.dg/simd-builtins-1.f90: New test. + * gfortran.dg/simd-builtins-1.h: New test. + * gfortran.dg/simd-builtins-2.f90: New test. + * gfortran.dg/simd-builtins-3.f90: New test. + * gfortran.dg/simd-builtins-3.h: New test. + * gfortran.dg/simd-builtins-4.f: New test. + * gfortran.dg/simd-builtins-4.h: New test. + * gfortran.dg/simd-builtins-5.f: New test. + * gfortran.dg/simd-builtins-6.f90: New test. + 2018-11-27 Jozef Lawrynowicz * lib/target-supports.exp diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-1.f90 b/gcc/testsuite/gfortran.dg/simd-builtins-1.f90 new file mode 100644 index 00000000000..e5ee380943f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/simd-builtins-1.f90 @@ -0,0 +1,19 @@ +! { dg-do compile { target { i?86-*-linux* x86_64-*-linux* } } } +! { dg-additional-options "-msse2 -nostdinc -Ofast -fpre-include=simd-builtins-1.h -fdump-tree-optimized" } + +program test_overloaded_intrinsic + real(4) :: x4(3200), y4(3200) + real(8) :: x8(3200), y8(3200) + + ! this should be using simd clone + y4 = sin(x4) + print *, y4 + + ! this should not be using simd clone + y4 = sin(x8) + print *, y8 +end + +! { dg-final { scan-tree-dump "sinf.simdclone" "optimized" } } */ +! { dg-final { scan-tree-dump "__builtin_sin" "optimized" } } */ +! { dg-final { scan-assembler "call.*_ZGVbN4v_sinf" } } diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-1.h b/gcc/testsuite/gfortran.dg/simd-builtins-1.h new file mode 100644 index 00000000000..88d555cf41a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/simd-builtins-1.h @@ -0,0 +1,4 @@ +!GCC$ builtin (sin) attributes simd (inbranch) +!GCC$ builtin (sinf) attributes simd (notinbranch) +!GCC$ builtin (cosf) attributes simd +!GCC$ builtin (cosf) attributes simd (notinbranch) diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-2.f90 b/gcc/testsuite/gfortran.dg/simd-builtins-2.f90 new file mode 100644 index 00000000000..f0e6bc13862 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/simd-builtins-2.f90 @@ -0,0 +1,20 @@ +! { dg-do compile { target { i?86-*-linux* x86_64-*-linux* } } } +! { dg-additional-options "-msse2 -nostdinc -Ofast -fdump-tree-optimized" } + +program test_overloaded_intrinsic + real(4) :: x4(3200), y4(3200) + real(8) :: x8(3200), y8(3200) + + ! this should be using simd clone + y4 = sin(x4) + print *, y4 + + ! this should not be using simd clone + y4 = sin(x8) + print *, y8 +end + +! { dg-final { scan-tree-dump "__builtin_sinf" "optimized" } } */ +! { dg-final { scan-tree-dump "__builtin_sin" "optimized" } } */ +! { dg-final { scan-tree-dump-not "simdclone" "optimized" } } */ +! { dg-final { scan-assembler-not "call.*_ZGVbN4v_sinf" } } diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-3.f90 b/gcc/testsuite/gfortran.dg/simd-builtins-3.f90 new file mode 100644 index 00000000000..949209bcf60 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/simd-builtins-3.f90 @@ -0,0 +1 @@ +! { dg-additional-options "-nostdinc -fpre-include=simd-builtins-3.h" } diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-3.h b/gcc/testsuite/gfortran.dg/simd-builtins-3.h new file mode 100644 index 00000000000..9707ef0a628 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/simd-builtins-3.h @@ -0,0 +1,8 @@ +!GCC$ builtin (sin) attributes simd (inbranch) +!GCC$ builtin ( sin) attributes simd (inbranch) +!GCC$ builtin (sin ) attributes simd (inbranch) +!GCC$ builtin (sin) attributes simd ( inbranch) +!GCC$ builtin (sin) attributes simd (inbranch ) +!GCC$ builtin(sin ) attributes simd ( inbranch ) +!GCC$ builtin ( sin ) attributes simd ( inbranch ) +!GCC$ builtin ( sin ) attributes simd diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-4.f b/gcc/testsuite/gfortran.dg/simd-builtins-4.f new file mode 100644 index 00000000000..48947b6f951 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/simd-builtins-4.f @@ -0,0 +1 @@ +! { dg-additional-options "-nostdinc -fpre-include=simd-builtins-4.h" } diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-4.h b/gcc/testsuite/gfortran.dg/simd-builtins-4.h new file mode 100644 index 00000000000..9707ef0a628 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/simd-builtins-4.h @@ -0,0 +1,8 @@ +!GCC$ builtin (sin) attributes simd (inbranch) +!GCC$ builtin ( sin) attributes simd (inbranch) +!GCC$ builtin (sin ) attributes simd (inbranch) +!GCC$ builtin (sin) attributes simd ( inbranch) +!GCC$ builtin (sin) attributes simd (inbranch ) +!GCC$ builtin(sin ) attributes simd ( inbranch ) +!GCC$ builtin ( sin ) attributes simd ( inbranch ) +!GCC$ builtin ( sin ) attributes simd diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-5.f b/gcc/testsuite/gfortran.dg/simd-builtins-5.f new file mode 100644 index 00000000000..55330a8306d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/simd-builtins-5.f @@ -0,0 +1,9 @@ +! { dg-do compile } + +!GCC$ buil tin (s in) attributes simd (inbranch) +!GCC$ builtin (sinf) at tributes simd (notinbranch) +!GCC$ builtin (cosf) att r i bu tes s imd +!GCC$ buil ti n ( cosf) attrib utes simd (noti nbranch) + + PROGRAM Z + END diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-6.f90 b/gcc/testsuite/gfortran.dg/simd-builtins-6.f90 new file mode 100644 index 00000000000..5ff99212cf1 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/simd-builtins-6.f90 @@ -0,0 +1,24 @@ +! { dg-do compile { target { i?86-*-linux* x86_64-*-linux* } } } +! { dg-additional-options "-msse2 -nostdinc -Ofast -fdump-tree-optimized" } + +!GCC$ builtin (sin) attributes simd (inbranch) +!GCC$ builtin (sinf) attributes simd (notinbranch) +!GCC$ builtin (cosf) attributes simd +!GCC$ builtin (cosf) attributes simd (notinbranch) + +program test_overloaded_intrinsic + real(4) :: x4(3200), y4(3200) + real(8) :: x8(3200), y8(3200) + + ! this should be using simd clone + y4 = sin(x4) + print *, y4 + + ! this should not be using simd clone + y4 = sin(x8) + print *, y8 +end + +! { dg-final { scan-tree-dump "sinf.simdclone" "optimized" } } */ +! { dg-final { scan-tree-dump "__builtin_sin" "optimized" } } */ +! { dg-final { scan-assembler "call.*_ZGVbN4v_sinf" } } -- 2.30.2