On 2/4/19 11:10 AM, Jakub Jelinek wrote:
> On Thu, Jan 24, 2019 at 04:25:13PM +0100, Martin Liška wrote:
>> @@ -11361,6 +11365,13 @@ gfc_match_gcc_builtin (void)
>> else if (gfc_match (" ( inbranch ) ") == MATCH_YES)
>> clause = SIMD_INBRANCH;
>>
>> + if (gfc_match (" if ( '%n' ) ", target) == MATCH_YES)
>
> Not sure if it is clean enough to have the 's in there, rather than
> matching there a string literal, requiring that it is a constant and getting
> at the string in there. But if this is fine with the Fortran maintainers, I
> won't object.
>
> Given the patches for aarch64, I'd think that in addition to the target
> specific multilib strings it might be worth to handle here also the generic
> lp64, ilp32 and llp64 strings (by checking the precision of the
> corresponding C types) and perhaps also big-endian, little-endian and
> pdp-endian. This way, targets which have only those differences wouldn't
> need to come up with their hooks.
I would prefer to leave the implementation as simple as possible. I don't expect
many targets implementing the SIMD ABI in glibc. It would not require much work
on glibc side (math header file).
>
>> +! { dg-final { scan-tree-dump "sinf.simdclone" "optimized" { target ilp32 }
>> } } */
>> +! { dg-final { scan-tree-dump-not "sin.simdclone" "optimized" { target
>> ilp32 } } } */
>
> I think you need ia32 here, otherwise it will fail on x32, which is also
> ilp32 target, but not i386.
Fixed.
>
>> +! { dg-final { scan-tree-dump "sin.simdclone" "optimized" { target lp64} }
>> } */
>> +! { dg-final { scan-tree-dump-not "sinf.simdclone" "optimized" { target
>> lp64 } } } */
>> diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-7.h
>> b/gcc/testsuite/gfortran.dg/simd-builtins-7.h
>> new file mode 100644
>> index 00000000000..1c19b88f877
>> --- /dev/null
>> +++ b/gcc/testsuite/gfortran.dg/simd-builtins-7.h
>> @@ -0,0 +1,2 @@
>> +!GCC$ builtin (sin) attributes simd (notinbranch) if('x86_64')
>> +!GCC$ builtin (sinf) attributes simd (notinbranch) if('i386')
>
> That is all from me, but I think you need a buy-in from the Fortran
> maintainers (if they are ok with such an extension from Fortran language
> POV) and from Joseph (or other glibc people).
I CCed Fortran ML, I'm attaching update patch.
Martin
>
> Jakub
>
>From 74fa90f002d862582db7f613ff7aa758a0cbc5c0 Mon Sep 17 00:00:00 2001
From: marxin <[email protected]>
Date: Mon, 21 Jan 2019 08:46:06 +0100
Subject: [PATCH] Support if statement in !GCC$ builtin directive.
gcc/ChangeLog:
2019-01-24 Martin Liska <[email protected]>
* config/i386/i386.c (ix86_get_multilib_abi_name): New function.
(TARGET_GET_MULTILIB_ABI_NAME): New macro defined.
* doc/tm.texi: Document new target hook.
* doc/tm.texi.in: Likewise.
* target.def: Add new target macro.
* gcc.c (find_fortran_preinclude_file): Do not search multilib
suffixes.
gcc/fortran/ChangeLog:
2019-01-24 Martin Liska <[email protected]>
* decl.c (gfc_match_gcc_builtin): Add support for filtering
of builtin directive based on multilib ABI name.
gcc/testsuite/ChangeLog:
2019-01-24 Martin Liska <[email protected]>
* gfortran.dg/simd-builtins-7.f90: New test.
* gfortran.dg/simd-builtins-7.h: New test.
---
gcc/config/i386/i386.c | 17 +++++++++++++++
gcc/doc/tm.texi | 4 ++++
gcc/doc/tm.texi.in | 2 ++
gcc/fortran/decl.c | 21 ++++++++++++++-----
gcc/gcc.c | 10 ++++-----
gcc/target.def | 6 ++++++
gcc/testsuite/gfortran.dg/simd-builtins-7.f90 | 19 +++++++++++++++++
gcc/testsuite/gfortran.dg/simd-builtins-7.h | 2 ++
8 files changed, 71 insertions(+), 10 deletions(-)
create mode 100644 gcc/testsuite/gfortran.dg/simd-builtins-7.f90
create mode 100644 gcc/testsuite/gfortran.dg/simd-builtins-7.h
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 789a53501ee..232a14a7de7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -29583,6 +29583,19 @@ ix86_warn_parameter_passing_abi (cumulative_args_t cum_v, tree type)
cum->warn_empty = false;
}
+/* This hook returns name of multilib ABI. */
+
+static const char *
+ix86_get_multilib_abi_name (void)
+{
+ if (!(TARGET_64BIT_P (ix86_isa_flags)))
+ return "i386";
+ else if (TARGET_X32_P (ix86_isa_flags))
+ return "x32";
+ else
+ return "x86_64";
+}
+
/* Compute the alignment for a variable for Intel MCU psABI. TYPE is
the data type, and ALIGN is the alignment that the object would
ordinarily have. */
@@ -51815,6 +51828,10 @@ ix86_run_selftests (void)
#undef TARGET_WARN_PARAMETER_PASSING_ABI
#define TARGET_WARN_PARAMETER_PASSING_ABI ix86_warn_parameter_passing_abi
+#undef TARGET_GET_MULTILIB_ABI_NAME
+#define TARGET_GET_MULTILIB_ABI_NAME \
+ ix86_get_multilib_abi_name
+
#if CHECKING_P
#undef TARGET_RUN_TARGET_SELFTESTS
#define TARGET_RUN_TARGET_SELFTESTS selftest::ix86_run_selftests
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 4347f89cd2f..8c8978bb13a 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1931,6 +1931,10 @@ superset of all other ABIs. @var{call_1} must always be a call insn,
call_2 may be NULL or a call insn.
@end deftypefn
+@deftypefn {Target Hook} {const char *} TARGET_GET_MULTILIB_ABI_NAME (void)
+This hook returns name of multilib ABI name.
+@end deftypefn
+
@findex fixed_regs
@findex call_used_regs
@findex global_regs
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 41a6cb11cb0..fe1194ef91a 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -1711,6 +1711,8 @@ of @code{CALL_USED_REGISTERS}.
@hook TARGET_RETURN_CALL_WITH_MAX_CLOBBERS
+@hook TARGET_GET_MULTILIB_ABI_NAME
+
@findex fixed_regs
@findex call_used_regs
@findex global_regs
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 4393287e1f1..df7d5733ef0 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "match.h"
#include "parse.h"
#include "constructor.h"
+#include "target.h"
/* Macros to access allocate memory for gfc_data_variable,
gfc_data_value and gfc_data. */
@@ -11352,19 +11353,22 @@ gfc_match_gcc_unroll (void)
return MATCH_ERROR;
}
-/* Match a !GCC$ builtin (b) attributes simd flags form:
+/* Match a !GCC$ builtin (b) attributes simd flags if('target') form:
The parameter b is name of a middle-end built-in.
- Flags are one of:
- - (empty)
- - inbranch
- - notinbranch
+ FLAGS is optional and must be one of:
+ - (inbranch)
+ - (notinbranch)
+
+ IF('target') is optional and TARGET is a name of a multilib ABI.
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];
+ char target[GFC_MAX_SYMBOL_LEN + 1];
if (gfc_match (" ( %n ) attributes simd", builtin) != MATCH_YES)
return MATCH_ERROR;
@@ -11375,6 +11379,13 @@ gfc_match_gcc_builtin (void)
else if (gfc_match (" ( inbranch ) ") == MATCH_YES)
clause = SIMD_INBRANCH;
+ if (gfc_match (" if ( '%n' ) ", target) == MATCH_YES)
+ {
+ const char *abi = targetm.get_multilib_abi_name ();
+ if (abi == NULL || strcmp (abi, target) != 0)
+ return MATCH_YES;
+ }
+
if (gfc_vectorized_builtins == NULL)
gfc_vectorized_builtins = new hash_map<nofree_string_hash, int> ();
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 797ed36616f..481e8289ad3 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -9965,24 +9965,24 @@ find_fortran_preinclude_file (int argc, const char **argv)
/* Search first for 'finclude' folder location for a header file
installed by the compiler (similar to omp_lib.h). */
- add_prefix (&prefixes, argv[2], NULL, 0, 0, false);
+ add_prefix (&prefixes, argv[2], NULL, 0, 0, 0);
#ifdef TOOL_INCLUDE_DIR
/* Then search: <prefix>/<target>/<include>/finclude */
add_prefix (&prefixes, TOOL_INCLUDE_DIR "/finclude/",
- NULL, 0, 0, false);
+ NULL, 0, 0, 0);
#endif
#ifdef NATIVE_SYSTEM_HEADER_DIR
/* Then search: <sysroot>/usr/include/finclude/<multilib> */
add_sysrooted_hdrs_prefix (&prefixes, NATIVE_SYSTEM_HEADER_DIR "/finclude/",
- NULL, 0, 0, false);
+ NULL, 0, 0, 0);
#endif
- const char *path = find_a_file (&include_prefixes, argv[1], R_OK, true);
+ const char *path = find_a_file (&include_prefixes, argv[1], R_OK, false);
if (path != NULL)
result = concat (argv[0], path, NULL);
else
{
- path = find_a_file (&prefixes, argv[1], R_OK, true);
+ path = find_a_file (&prefixes, argv[1], R_OK, false);
if (path != NULL)
result = concat (argv[0], path, NULL);
}
diff --git a/gcc/target.def b/gcc/target.def
index 05c9cc1da28..66cee075018 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -5791,6 +5791,12 @@ call_2 may be NULL or a call insn.",
rtx_insn *, (rtx_insn *call_1, rtx_insn *call_2),
NULL)
+DEFHOOK
+(get_multilib_abi_name,
+ "This hook returns name of multilib ABI name.",
+ const char *, (void),
+ hook_constcharptr_void_null)
+
DEFHOOK
(remove_extra_call_preserved_regs,
"This hook removes registers from the set of call-clobbered registers\n\
diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-7.f90 b/gcc/testsuite/gfortran.dg/simd-builtins-7.f90
new file mode 100644
index 00000000000..75734d43c3d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/simd-builtins-7.f90
@@ -0,0 +1,19 @@
+! { dg-do compile { target { i?86-*-linux* x86_64-*-linux* } } }
+! { dg-additional-options "-msse2 -mno-avx -nostdinc -Ofast -fpre-include=simd-builtins-7.h -fdump-tree-optimized" }
+
+program test_overloaded_intrinsic
+ real(4) :: x4(3200), y4(3200)
+ real(8) :: x8(3200), y8(3200)
+
+ y4 = sin(x4)
+ print *, y4
+
+ y4 = sin(x8)
+ print *, y8
+end
+
+! { dg-final { scan-tree-dump "sinf.simdclone" "optimized" { target ia32 } } } */
+! { dg-final { scan-tree-dump-not "sin.simdclone" "optimized" { target ia32 } } } */
+
+! { dg-final { scan-tree-dump "sin.simdclone" "optimized" { target lp64} } } */
+! { dg-final { scan-tree-dump-not "sinf.simdclone" "optimized" { target lp64 } } } */
diff --git a/gcc/testsuite/gfortran.dg/simd-builtins-7.h b/gcc/testsuite/gfortran.dg/simd-builtins-7.h
new file mode 100644
index 00000000000..1c19b88f877
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/simd-builtins-7.h
@@ -0,0 +1,2 @@
+!GCC$ builtin (sin) attributes simd (notinbranch) if('x86_64')
+!GCC$ builtin (sinf) attributes simd (notinbranch) if('i386')
--
2.20.1