Re: [PATCH] [RFC] vect: Fix infinite loop while determining peeling amount

2020-07-27 Thread Richard Biener via Gcc-patches
On Wed, Jul 22, 2020 at 5:18 PM Stefan Schulze Frielinghaus via
Gcc-patches  wrote:
>
> This is a follow up to commit 5c9669a0e6c respectively discussion
> https://gcc.gnu.org/pipermail/gcc-patches/2020-June/549132.html
>
> In case that an alignment constraint is less than the size of a
> corresponding scalar type, ensure that we advance at least by one
> iteration.  For example, on s390x we have for a long double an alignment
> constraint of 8 bytes whereas the size is 16 bytes.  Therefore,
> TARGET_ALIGN / DR_SIZE equals zero resulting in an infinite loop which
> can be reproduced by the following MWE:

But we guard this case with vector_alignment_reachable_p, so we shouldn't
have ended up here and the patch looks bogus.

Richard.

> extern long double *a;
> extern double *b;
> void fun(void) {
>   for (int i = 0; i < 42; i++)
> a[i] = b[i];
> }
>
> Increasing the number of peelings in each iteration at least by one
> fixes the issue for me.  Any comments?
>
> Bootstrapped and regtested on s390x.
>
> gcc/ChangeLog:
>
> * tree-vect-data-refs.c (vect_enhance_data_refs_alignment):
> Ensure that loop variable npeel_tmp advances in each iteration.
> ---
>  gcc/tree-vect-data-refs.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
> index e35a215e042..a78ae61d1b0 100644
> --- a/gcc/tree-vect-data-refs.c
> +++ b/gcc/tree-vect-data-refs.c
> @@ -1779,7 +1779,7 @@ vect_enhance_data_refs_alignment (loop_vec_info 
> loop_vinfo)
>  {
>vect_peeling_hash_insert (&peeling_htab, loop_vinfo,
> dr_info, npeel_tmp);
> - npeel_tmp += target_align / dr_size;
> + npeel_tmp += MAX (1, target_align / dr_size);
>  }
>
>   one_misalignment_known = true;
> --
> 2.25.3
>


Re: [PATCH] LTO: Add -fcf-protection=check

2020-07-27 Thread Richard Biener via Gcc-patches
On Fri, Jul 24, 2020 at 11:15 PM H.J. Lu via Gcc-patches
 wrote:
>
> Mixing -fcf-protection and -fcf-protection=none objects are allowed.
> Linker just merges -fcf-protection values from all input objects.
>
> Add -fcf-protection=check for the final link with LTO.  An error is
> issued if LTO object files are compiled with different -fcf-protection
> values.  Otherwise, -fcf-protection=check is ignored at the compile
> time.  Without explicit -fcf-protection at link time, -fcf-protection
> values from LTO object files are merged at the final link.

OK.

Thanks,
Richard.

> gcc/
>
> PR bootstrap/96203
> * common.opt: Add -fcf-protection=check.
> * flag-types.h (cf_protection_level): Add CF_CHECK.
> * lto-wrapper.c (merge_and_complain): Issue an error for
> mismatching -fcf-protection values with -fcf-protection=check.
> Otherwise, merge -fcf-protection values.
> * doc/invoke.texi: Document -fcf-protection=check.
>
> gcc/testsuite/
>
> PR bootstrap/96203
> * gcc.target/i386/pr96203-1.c: New test.
> * gcc.target/i386/pr96203-2.c: Likewise.
> ---
>  gcc/common.opt|  5 ++-
>  gcc/doc/invoke.texi   |  9 --
>  gcc/flag-types.h  |  3 +-
>  gcc/lto-wrapper.c | 39 +++
>  gcc/testsuite/gcc.target/i386/pr96203-1.c | 18 +++
>  gcc/testsuite/gcc.target/i386/pr96203-2.c | 11 +++
>  6 files changed, 74 insertions(+), 11 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr96203-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr96203-2.c
>
> diff --git a/gcc/common.opt b/gcc/common.opt
> index a3893a4725e..47f42615bfa 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -1776,7 +1776,7 @@ Common RejectNegative Alias(fcf-protection=,full)
>
>  fcf-protection=
>  Common Report Joined RejectNegative Enum(cf_protection_level) 
> Var(flag_cf_protection) Init(CF_NONE)
> --fcf-protection=[full|branch|return|none]  Instrument functions with 
> checks to verify jump/call/return control-flow transfer
> +-fcf-protection=[full|branch|return|none|check]Instrument functions 
> with checks to verify jump/call/return control-flow transfer
>  instructions have valid targets.
>
>  Enum
> @@ -1791,6 +1791,9 @@ Enum(cf_protection_level) String(branch) 
> Value(CF_BRANCH)
>  EnumValue
>  Enum(cf_protection_level) String(return) Value(CF_RETURN)
>
> +EnumValue
> +Enum(cf_protection_level) String(check) Value(CF_CHECK)
> +
>  EnumValue
>  Enum(cf_protection_level) String(none) Value(CF_NONE)
>
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index ba18e05fb1a..df84bce3a56 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -559,7 +559,7 @@ Objective-C and Objective-C++ Dialects}.
>  -fsanitize=@var{style}  -fsanitize-recover  -fsanitize-recover=@var{style} 
> @gol
>  -fasan-shadow-offset=@var{number}  -fsanitize-sections=@var{s1},@var{s2},... 
> @gol
>  -fsanitize-undefined-trap-on-error  -fbounds-check @gol
> --fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{]} @gol
> +-fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{|}check@r{]} @gol
>  -fstack-protector  -fstack-protector-all  -fstack-protector-strong @gol
>  -fstack-protector-explicit  -fstack-check @gol
>  -fstack-limit-register=@var{reg}  -fstack-limit-symbol=@var{sym} @gol
> @@ -14210,7 +14210,7 @@ operand constant, @code{__sanitizer_cov_trace_cmpf} or
>  @code{__sanitizer_cov_trace_cmpd} for float or double comparisons and
>  @code{__sanitizer_cov_trace_switch} for switch statements.
>
> -@item -fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{]}
> +@item -fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{|}check@r{]}
>  @opindex fcf-protection
>  Enable code instrumentation of control-flow transfers to increase
>  program security by checking that target addresses of control-flow
> @@ -14228,6 +14228,11 @@ function.  The value @code{full} is an alias for 
> specifying both
>  @code{branch} and @code{return}. The value @code{none} turns off
>  instrumentation.
>
> +The value @code{check} is used for the final link with link-time
> +optimization (LTO).  An error is issued if LTO object files are
> +compiled with different @option{-fcf-protection} values.  The
> +value @code{check} is ignored at the compile time.
> +
>  The macro @code{__CET__} is defined when @option{-fcf-protection} is
>  used.  The first bit of @code{__CET__} is set to 1 for the value
>  @code{branch} and the second bit of @code{__CET__} is set to 1 for
> diff --git a/gcc/flag-types.h b/gcc/flag-types.h
> index b092c563f3d..852ea76eaa2 100644
> --- a/gcc/flag-types.h
> +++ b/gcc/flag-types.h
> @@ -368,7 +368,8 @@ enum cf_protection_level
>CF_BRANCH = 1 << 0,
>CF_RETURN = 1 << 1,
>CF_FULL = CF_BRANCH | CF_RETURN,
> -  CF_SET = 1 << 2
> +  CF_SET = 1 << 2,
> +  CF_CHECK = 1 << 3
>  };
>
>  /* Parloops 

Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Richard Biener via Gcc-patches
On Sat, Jul 25, 2020 at 2:23 PM Martin Liška  wrote:
>
> Hello.
>
> When inserting into fast_call_summary (or fast_function_summary), we grow
> a vector to a _exact_ size based on cgraph_max_summary_id or 
> edges_max_summary_id.
> Problem is that it causes very many reallocation and we should rather use 
> ::reserve
> function that selects a reasonable size of a new vector.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> Fixes chromium WPA build time:
> https://gist.githubusercontent.com/marxin/223890df4d8d8e490b6b2918b77dacad/raw/f766f6546739e739a273639dde90ac6179aa3077/chromium-gcc10-fixed-summary-crash.svg
>
> Ready to be installed?

OK.  I guess the previous code tried to use less memory.

Thanks,
Richard.

> Thanks,
> Martin
>
> gcc/ChangeLog:
>
> * symbol-summary.h: Call vec_safe_reserve before grow is called
> in order to grow to a reasonable size.
> * vec.h (vec_safe_reserve): Add missing function for vl_ptr
> type.
> ---
>   gcc/symbol-summary.h | 13 ++---
>   gcc/vec.h| 11 +++
>   2 files changed, 21 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
> index a38eb1db778..fa1df5c8015 100644
> --- a/gcc/symbol-summary.h
> +++ b/gcc/symbol-summary.h
> @@ -354,8 +354,11 @@ public:
> id = this->m_symtab->assign_summary_id (node);
>
>   if ((unsigned int)id >= m_vector->length ())
> -  vec_safe_grow_cleared (m_vector,
> -this->m_symtab->cgraph_max_summary_id);
> +  {
> +   int newlen = this->m_symtab->cgraph_max_summary_id;
> +   vec_safe_reserve (m_vector, newlen - m_vector->length ());
> +   m_vector->quick_grow_cleared (newlen);
> +  }
>
>   if ((*m_vector)[id] == NULL)
> (*m_vector)[id] = this->allocate_new ();
> @@ -812,7 +815,11 @@ public:
> id = this->m_symtab->assign_summary_id (edge);
>
>   if ((unsigned)id >= m_vector->length ())
> -  vec_safe_grow_cleared (m_vector, this->m_symtab->edges_max_summary_id);
> +  {
> +   int newlen = this->m_symtab->edges_max_summary_id;
> +   m_vector->reserve (newlen - m_vector->length ());
> +   m_vector->quick_grow_cleared (newlen);
> +  }
>
>   if ((*m_vector)[id] == NULL)
> (*m_vector)[id] = this->allocate_new ();
> diff --git a/gcc/vec.h b/gcc/vec.h
> index bd7c7351dcd..3ad99b83690 100644
> --- a/gcc/vec.h
> +++ b/gcc/vec.h
> @@ -753,6 +753,17 @@ vec_safe_grow_cleared (vec *&v,
> v->safe_grow_cleared (len PASS_MEM_STAT);
>   }
>
> +/* If V does not have space for NELEMS elements, call
> +   V->reserve(NELEMS, EXACT).  */
> +
> +template
> +inline bool
> +vec_safe_reserve (vec *&v, unsigned nelems, bool exact = 
> false
> + CXX_MEM_STAT_INFO)
> +{
> +  return v->reserve (nelems, exact);
> +}
> +
>
>   /* If V is NULL return false, otherwise return V->iterate(IX, PTR).  */
>   template
> --
> 2.27.0
>


Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Martin Liška

On 7/27/20 9:11 AM, Richard Biener wrote:

OK.  I guess the previous code tried to use less memory.


It did. But I didn't realize that such exact growth would lead
to a massive reallocation for huge apps like chromium.

I'm going to backport the patch older releases as well.

Martin


Re: [PATCH] ipa/96291: don't crash on unoptimized lto functions

2020-07-27 Thread Richard Biener via Gcc-patches
On Sat, Jul 25, 2020 at 8:35 PM Sergei Trofimovich via Gcc-patches
 wrote:
>
> From: Sergei Trofimovich 
>
> In PR ipa/96291 the test contained an SCC with one
> unoptimized function. This tricked ipa-cp into NULL dereference.
>
> has_undead_caller_from_outside_scc_p() did not take into account
> that unoptimized funtions don't have IPA summary analysis. and
> dereferenced NULL pointer causing an ICE.

Can you create a single-unit testcase with a SCC with one function
having the no_ipa attribute?

> PR ipa/96291
> * ipa-cp.c (has_undead_caller_from_outside_scc_p): Consider
> unoptimized callers as undead.
> ---
>  gcc/ipa-cp.c | 12 +---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
> index b0c8f405260..d5082576962 100644
> --- a/gcc/ipa-cp.c
> +++ b/gcc/ipa-cp.c
> @@ -5666,9 +5666,15 @@ has_undead_caller_from_outside_scc_p (struct 
> cgraph_node *node,
> && cs->caller->call_for_symbol_thunks_and_aliases
>   (has_undead_caller_from_outside_scc_p, NULL, true))
>return true;
> -else if (!ipa_edge_within_scc (cs)
> -&& !IPA_NODE_REF (cs->caller)->node_dead)
> -  return true;
> +else if (!ipa_edge_within_scc (cs))
> +  {
> +   /* Unoptimized callers don't have IPA information.
> +  Conservatively assume callers are undead.  */
> +   if (!IPA_NODE_REF (cs->caller))
> + return true;
> +   if (!IPA_NODE_REF (cs->caller)->node_dead)
> + return true;
> +  }
>return false;
>  }
>
> --
> 2.27.0
>


[patch, committed] fortran/openmp.c - silence static analyzer warning (was: [Patch] OpenMP: Fixes for omp critical + hint)

2020-07-27 Thread Tobias Burnus

As complained by Coverity, which was pointed out to my
by Fredering (thanks!), that patch lead to an inconsistency:

+  if (code->ext.omp_clauses)
+   resolve_omp_clauses (code, code->ext.omp_clauses, NULL);
+  if (!code->ext.omp_clauses->critical_name

Before, we had:
  !$omp critical [(name) [hint()]]
but as for hint == 0 '(name)' is not required, we now have:
  !$omp critical [(name)] [hint()]
Result: gfc_match_omp_clauses is now called unconditionally
and (unless MATCH_ERROR) it always allocates 'ext.omp_clauses'.

Thus, we can now remove first condition – which caused that
Coverity's scanner assumed that the second condition
could dereference a NULL pointer in the 'false' case.

Committed as obvious.

Tobias


-
Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander 
Walter
commit 20d0d6527c36005a9664f7ac9eb50f1071d5670c
Author: Tobias Burnus 
Date:   Mon Jul 27 09:12:15 2020 +0200

fortran/openmp.c - silence static analyzer warning

gcc/fortran/ChangeLog:

* openmp.c (gfc_resolve_omp_directive): Remove NULL check
for clauses in EXEC_OMP_CRITICAL as it no longer can be NULL.

diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index f8f2439b6e4..4a0466f968d 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -6560,8 +6560,7 @@ gfc_resolve_omp_directive (gfc_code *code, gfc_namespace *ns ATTRIBUTE_UNUSED)
   resolve_omp_atomic (code);
   break;
 case EXEC_OMP_CRITICAL:
-  if (code->ext.omp_clauses)
-	resolve_omp_clauses (code, code->ext.omp_clauses, NULL);
+  resolve_omp_clauses (code, code->ext.omp_clauses, NULL);
   if (!code->ext.omp_clauses->critical_name
 	  && code->ext.omp_clauses->hint
 	  && code->ext.omp_clauses->hint->ts.type == BT_INTEGER


RE: [PATCH v2] driver: fix a problem with implementation of -falign-foo=0 [PR96247]

2020-07-27 Thread Hu, Jiangping
> In addition to Segher's comments, I wonder if it would be better
> to pass &opts->x_flag_align_foo and &opts->x_str_align_jumps to
> check_alignment_argument and do the check there instead.
> The condition for whether to do this would then be:
> 
>   align_result.length () == 1 && align_result[0] == 0
> 
> The reason for suggesting that is that it makes the parsing code
> more self-consistent, rather than using atoi for this case only.
> 
Thanks, Segher and Richard!

I'll make a new patch to do the check in check_alignment_argument,
and change the condition of the if statement as follows:

align_result.length () >= 1 && align_result[0] == 0

for the input -falign-foo=n:m:n2:m2, according to documentation,
if n is zero, use the machine-dependent value. I think the implict
meaning is that even if m or n2 or m2 is specified, it should be
ignored. Any comments are appreciated!

> Looks good otherwise, thanks.
> 
> Richard
> 





[PATCH v3] driver: fix a problem with implementation of -falign-foo=0 [PR96247]

2020-07-27 Thread Hu Jiangping
Hi!

This patch makes the -falign-foo=0 work as described in the
documentation. Thanks for all the suggestions, Richard and Segher!

v3: make change more readable and self-consistent
v2: at a high level handles -falign-foo=0 like -falign-foo

Regards!
Hujp

---
 gcc/opts.c | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/gcc/opts.c b/gcc/opts.c
index 499eb900643..dec5ba6d2be 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2007,10 +2007,20 @@ parse_and_check_align_values (const char *flag,
location LOC.  */
 
 static void
-check_alignment_argument (location_t loc, const char *flag, const char *name)
+check_alignment_argument (location_t loc,
+const char *flag,
+const char *name,
+int *opt_flag,
+const char **opt_str)
 {
   auto_vec align_result;
   parse_and_check_align_values (flag, name, align_result, true, loc);
+
+  if (align_result.length() >= 1 && align_result[0] == 0)
+  {
+*opt_flag = 1;
+*opt_str = NULL;
+  }
 }
 
 /* Print help when OPT__help_ is set.  */
@@ -2785,19 +2795,23 @@ common_handle_option (struct gcc_options *opts,
   break;
 
 case OPT_falign_loops_:
-  check_alignment_argument (loc, arg, "loops");
+  check_alignment_argument (loc, arg, "loops",
+  &opts->x_flag_align_loops, &opts->x_str_align_loops);
   break;
 
 case OPT_falign_jumps_:
-  check_alignment_argument (loc, arg, "jumps");
+  check_alignment_argument (loc, arg, "jumps",
+  &opts->x_flag_align_jumps, &opts->x_str_align_jumps);
   break;
 
 case OPT_falign_labels_:
-  check_alignment_argument (loc, arg, "labels");
+  check_alignment_argument (loc, arg, "labels",
+  &opts->x_flag_align_labels, &opts->x_str_align_labels);
   break;
 
 case OPT_falign_functions_:
-  check_alignment_argument (loc, arg, "functions");
+  check_alignment_argument (loc, arg, "functions",
+  &opts->x_flag_align_functions, &opts->x_str_align_functions);
   break;
 
 case OPT_ftabstop_:
-- 
2.17.1





RE: [PATCH v3] driver: fix a problem with implementation of -falign-foo=0 [PR96247]

2020-07-27 Thread Hu, Jiangping
Tested on x86_64.

> -Original Message-
> From: Gcc-patches  On Behalf Of Hu
> Jiangping
> Sent: Monday, July 27, 2020 3:46 PM
> To: gcc-patches@gcc.gnu.org; richard.sandif...@arm.com;
> seg...@kernel.crashing.org
> Subject: [PATCH v3] driver: fix a problem with implementation of -falign-foo=0
> [PR96247]
> 
> Hi!
> 
> This patch makes the -falign-foo=0 work as described in the
> documentation. Thanks for all the suggestions, Richard and Segher!
> 
> v3: make change more readable and self-consistent
> v2: at a high level handles -falign-foo=0 like -falign-foo
> 
> Regards!
> Hujp
> 
> ---
>  gcc/opts.c | 24 +++-
>  1 file changed, 19 insertions(+), 5 deletions(-)
> 
> diff --git a/gcc/opts.c b/gcc/opts.c
> index 499eb900643..dec5ba6d2be 100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -2007,10 +2007,20 @@ parse_and_check_align_values (const char *flag,
> location LOC.  */
> 
>  static void
> -check_alignment_argument (location_t loc, const char *flag, const char
> *name)
> +check_alignment_argument (location_t loc,
> +const char *flag,
> +const char *name,
> +int *opt_flag,
> +const char **opt_str)
>  {
>auto_vec align_result;
>parse_and_check_align_values (flag, name, align_result, true, loc);
> +
> +  if (align_result.length() >= 1 && align_result[0] == 0)
> +  {
> +*opt_flag = 1;
> +*opt_str = NULL;
> +  }
>  }
> 
>  /* Print help when OPT__help_ is set.  */
> @@ -2785,19 +2795,23 @@ common_handle_option (struct gcc_options
> *opts,
>break;
> 
>  case OPT_falign_loops_:
> -  check_alignment_argument (loc, arg, "loops");
> +  check_alignment_argument (loc, arg, "loops",
> +  &opts->x_flag_align_loops, &opts->x_str_align_loops);
>break;
> 
>  case OPT_falign_jumps_:
> -  check_alignment_argument (loc, arg, "jumps");
> +  check_alignment_argument (loc, arg, "jumps",
> +  &opts->x_flag_align_jumps, &opts->x_str_align_jumps);
>break;
> 
>  case OPT_falign_labels_:
> -  check_alignment_argument (loc, arg, "labels");
> +  check_alignment_argument (loc, arg, "labels",
> +  &opts->x_flag_align_labels, &opts->x_str_align_labels);
>break;
> 
>  case OPT_falign_functions_:
> -  check_alignment_argument (loc, arg, "functions");
> +  check_alignment_argument (loc, arg, "functions",
> +  &opts->x_flag_align_functions, &opts->x_str_align_functions);
>break;
> 
>  case OPT_ftabstop_:
> --
> 2.17.1
> 
> 





[Ada] x86-lynx178elf: use a-numaux.ads instead of a-numaux__libc-x86.ads

2020-07-27 Thread Pierre-Marie de Rodat
a-numaux__libc-x86.ads wraps around long double trig functions that
Lynx178 does not have, so use the default a-numaux.ads instead to match
what is offered on Lynx178.

This is done by removing X86_TARGET_PAIRS from the x86-lynx178elf
configuration as it is now redundant: the default a-numaux pacakge is
used, plus this target also can use the default s-atocou pacakge (since
atomic builtins are supported on the i586 compiler).

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* Makefile.rtl: Remove X86_TARGET_PAIRS for x86-lynx178elf.diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -1911,7 +1911,6 @@ ifeq ($(strip $(filter-out lynxos178%,$(target_os))),)
   endif
   ifeq ($(strip $(filter-out %86, $(target_cpu))),)
 LIBGNAT_TARGET_PAIRS +=  system.ads

[Ada] AI12-0382: Loosen type-invariant overriding requirement of AI12-0042

2020-07-27 Thread Pierre-Marie de Rodat
The requirement for overriding an inherited visible private operation
when extending from an ancestor that specifies Type_Invariant'Class as
specified in RM 7.3.2(6.1/4) (AI12-0042) was unintentionally
overrestrictive.  The rule is loosened by AI12-0382 so that it only
applies to type extensions that are declared in the visible part of a
package.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch3.adb (Check_Abstract_Overriding): Remove Scope
comparison test from test related to initial implementation of
AI12-0042, plus remove the related ??? comment.
(Derive_Subprogram): Add test requiring that the type extension
appear in the visible part of its enclosing package when
checking the overriding requirement of 7.3.2(6.1/4), as
clarified by AI12-0382.diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -10763,12 +10763,7 @@ package body Sem_Ch3 is
  --  AI12-0042: Test for rule in 7.3.2(6.1/4), that requires overriding
  --  of a visible private primitive inherited from an ancestor with
  --  the aspect Type_Invariant'Class, unless the inherited primitive
- --  is abstract. (The test for the extension occurring in a different
- --  scope than the ancestor is to avoid requiring overriding when
- --  extending in the same scope, because the inherited primitive will
- --  also be private in that case, which looks like an unhelpful
- --  restriction that may break reasonable code, though the rule
- --  appears to apply in the same-scope case as well???)
+ --  is abstract.
 
  elsif not Is_Abstract_Subprogram (Subp)
and then not Comes_From_Source (Subp) -- An inherited subprogram
@@ -10778,7 +10773,6 @@ package body Sem_Ch3 is
and then Present (Get_Pragma (Etype (T), Pragma_Invariant))
and then Class_Present (Get_Pragma (Etype (T), Pragma_Invariant))
and then Is_Private_Primitive (Alias_Subp)
-   and then Scope (Subp) /= Scope (Alias_Subp)
  then
 Error_Msg_NE
   ("inherited private primitive & must be overridden", T, Subp);
@@ -15732,7 +15726,9 @@ package body Sem_Ch3 is
--  AI12-0042: Set Requires_Overriding when a type extension
--  inherits a private operation that is visible at the
--  point of extension (Has_Private_Ancestor is False) from
-   --  an ancestor that has Type_Invariant'Class.
+   --  an ancestor that has Type_Invariant'Class, and when the
+   --  type extension is in a visible part (the latter as
+   --  clarified by AI12-0382).
 
or else
  (not Has_Private_Ancestor (Derived_Type)
@@ -15742,7 +15738,8 @@ package body Sem_Ch3 is
and then
  Class_Present
(Get_Pragma (Parent_Type, Pragma_Invariant))
-   and then Is_Private_Primitive (Parent_Subp)))
+   and then Is_Private_Primitive (Parent_Subp)
+   and then In_Visible_Part (Scope (Derived_Type
 
 and then No (Actual_Subp)
   then




[Ada] Warnings on overloays involving generic In_Parameters

2020-07-27 Thread Pierre-Marie de Rodat
Warnings aare emitted when a declaration for a constant C has an address
aspect or an address_specification clause of the form O'Address, where
O is a previously declared entity that is not a constant, The warning
must br supppressed if O is a generic formal In_Parameter, which is a
constant within the generic unit.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch13.adb (Analyze_Address_Specification_Clause): Do not
emit a warning when a constant declaration in a generic unit
overlays a generic In_Parameter.diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -6190,9 +6190,13 @@ package body Sem_Ch13 is
   --  Issue an unconditional warning for a constant overlaying
   --  a variable. For the reverse case, we will issue it only
   --  if the variable is modified.
+  --  Within a generic unit an In_Parameter is a constant.
+  --  It can be instantiated with a variable, in which case
+  --  there will be a warning on the instance.
 
   if Ekind (U_Ent) = E_Constant
 and then Present (O_Ent)
+and then Ekind (O_Ent) /= E_Generic_In_Parameter
 and then not Overlays_Constant (U_Ent)
 and then Address_Clause_Overlay_Warnings
   then




[Ada] Add range check for GNATprove on 'Pos to Long_Integer conversion

2020-07-27 Thread Pierre-Marie de Rodat
In GNAT mode attribute Pos is typically expanded into either a type
conversion (unless applied to enumeration types with custom
representation values) and analysis of this type conversion adds check
flags as required.

In GNATprove mode we expand the attribute with
Apply_Universal_Integer_Attribute_Checks, which adds a type conversion,
but its analysis only adds check flags if the size of the target type is
smaller than the size of universal integer. This should be fixed in the
compiler itself, but we already had a workaround for 'Length and
'Range_Length.

This patch extends the existing workaround to 'Pos, which is enough to
solve the problem in GNATprove; the compiler is not affected by this
patch.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_spark.adb (Expand_SPARK_N_Attribute_Reference) Extend
existing workaround to 'Pos.diff --git a/gcc/ada/exp_spark.adb b/gcc/ada/exp_spark.adb
--- a/gcc/ada/exp_spark.adb
+++ b/gcc/ada/exp_spark.adb
@@ -400,13 +400,16 @@ package body Exp_SPARK is
  --  flag as the compiler assumes attributes always fit in this type.
  --  Since in SPARK_Mode we do not take Storage_Error into account, we
  --  cannot make this assumption and need to produce a check.
- --  ??? It should be enough to add this check for attributes 'Length
- --  and 'Range_Length when the type is as big as Long_Long_Integer.
+ --  ??? It should be enough to add this check for attributes
+ --  'Length, 'Range_Length and 'Pos when the type is as big
+ --  as Long_Long_Integer.
 
  declare
 Typ : Entity_Id;
  begin
-if Attr_Id = Attribute_Range_Length then
+if Attr_Id = Attribute_Range_Length
+  or else Attr_Id = Attribute_Pos
+then
Typ := Etype (Prefix (N));
 
 elsif Attr_Id = Attribute_Length then
@@ -421,6 +424,9 @@ package body Exp_SPARK is
 if Present (Typ)
   and then RM_Size (Typ) = RM_Size (Standard_Long_Long_Integer)
 then
+   --  ??? This should rather be a range check, but this would
+   --  crash GNATprove which somehow recovers the proper kind
+   --  of check anyway.
Set_Do_Overflow_Check (N);
 end if;
  end;




[Ada] AI12-0194: Language-defined aspects and entry bodies

2020-07-27 Thread Pierre-Marie de Rodat
AI12-0194 specifies that language-defined aspects aren't permitted
on entry bodies, which is already effectively enforced by GNAT,
however the error message given when Max_Entry_Queue_Length is applied
to an entry body is potentially confusing, because it says that the
aspect "must apply to a protected entry", and we improve that by
revising it to say "must apply to a protected entry declaration".

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_prag.adb (Analyze_Pragma, Pragma_Max_Entry_Queue_Length):
Refine error message to indicate that the pragma must apply to
an entry declaration, not just an entry.diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -19452,7 +19452,8 @@ package body Sem_Prag is
 --  Otherwise the pragma is associated with an illegal construct
 
 else
-   Error_Pragma ("pragma % must apply to a protected entry");
+   Error_Pragma
+ ("pragma % must apply to a protected entry declaration");
return;
 end if;
 




[Ada] Unbounded string overriding control

2020-07-27 Thread Pierre-Marie de Rodat
Unbounded string operation has to raise Constraint_Error if resulting
string going to be over Integer'Last length.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* libgnat/a-strunb.adb (Sum, Mul, Saturated_Sum, Saturated_Mul):
New routines.  Use them when resulting string size more that
length of the strings in parameters.
(Unbounded_Slice): Use "- 1" instead of "+ 1" in opposite side
of condition to avoid overflow.
* libgnat/a-strunb__shared.adb (Sum, Mul): New routines.
(Allocate): New routine with 2 parameters.  Use routine above
when resulting string size more that length of the strings in
parameters.
(Aligned_Max_Length): Do not try to align to more than Natural'Last.
(Unbounded_Slice): Use "- 1" instead of "+ 1" in opposite side
of condition to avoid overflow.diff --git a/gcc/ada/libgnat/a-strunb.adb b/gcc/ada/libgnat/a-strunb.adb
--- a/gcc/ada/libgnat/a-strunb.adb
+++ b/gcc/ada/libgnat/a-strunb.adb
@@ -35,6 +35,19 @@ with Ada.Unchecked_Deallocation;
 
 package body Ada.Strings.Unbounded is
 
+   function Sum (Left : Natural; Right : Integer) return Natural with Inline;
+   --  Returns summary of Left and Right, raise Constraint_Error on overflow
+
+   function Mul (Left, Right : Natural) return Natural with Inline;
+   --  Returns multiplication of Left and Right, raise Constraint_Error on
+   --  overflow.
+
+   function Saturated_Sum (Left : Natural; Right : Integer) return Natural;
+   --  Returns summary of Left and Right or Natural'Last on overflow
+
+   function Saturated_Mul (Left, Right : Natural) return Natural;
+   --  Returns multiplication of Left and Right or Natural'Last on overflow
+
-
-- "&" --
-
@@ -48,7 +61,7 @@ package body Ada.Strings.Unbounded is
   Result   : Unbounded_String;
 
begin
-  Result.Last := L_Length + R_Length;
+  Result.Last := Sum (L_Length, R_Length);
 
   Result.Reference := new String (1 .. Result.Last);
 
@@ -68,7 +81,7 @@ package body Ada.Strings.Unbounded is
   Result   : Unbounded_String;
 
begin
-  Result.Last := L_Length + Right'Length;
+  Result.Last := Sum (L_Length, Right'Length);
 
   Result.Reference := new String (1 .. Result.Last);
 
@@ -86,7 +99,7 @@ package body Ada.Strings.Unbounded is
   Result   : Unbounded_String;
 
begin
-  Result.Last := Left'Length + R_Length;
+  Result.Last := Sum (Left'Length, R_Length);
 
   Result.Reference := new String (1 .. Result.Last);
 
@@ -104,7 +117,7 @@ package body Ada.Strings.Unbounded is
   Result : Unbounded_String;
 
begin
-  Result.Last := Left.Last + 1;
+  Result.Last := Sum (Left.Last, 1);
 
   Result.Reference := new String (1 .. Result.Last);
 
@@ -122,7 +135,7 @@ package body Ada.Strings.Unbounded is
   Result : Unbounded_String;
 
begin
-  Result.Last := Right.Last + 1;
+  Result.Last := Sum (Right.Last, 1);
 
   Result.Reference := new String (1 .. Result.Last);
   Result.Reference (1) := Left;
@@ -142,7 +155,7 @@ package body Ada.Strings.Unbounded is
   Result : Unbounded_String;
 
begin
-  Result.Last   := Left;
+  Result.Last := Left;
 
   Result.Reference := new String (1 .. Left);
   for J in Result.Reference'Range loop
@@ -161,7 +174,7 @@ package body Ada.Strings.Unbounded is
   Result : Unbounded_String;
 
begin
-  Result.Last := Left * Len;
+  Result.Last := Mul (Left, Len);
 
   Result.Reference := new String (1 .. Result.Last);
 
@@ -183,7 +196,7 @@ package body Ada.Strings.Unbounded is
   Result : Unbounded_String;
 
begin
-  Result.Last := Left * Len;
+  Result.Last := Mul (Left, Len);
 
   Result.Reference := new String (1 .. Result.Last);
 
@@ -718,6 +731,16 @@ package body Ada.Strings.Unbounded is
   return Source.Last;
end Length;
 
+   -
+   -- Mul --
+   -
+
+   function Mul (Left, Right : Natural) return Natural is
+  pragma Unsuppress (Overflow_Check);
+   begin
+  return Left * Right;
+   end Mul;
+
---
-- Overwrite --
---
@@ -783,10 +806,12 @@ package body Ada.Strings.Unbounded is
   if Chunk_Size > S_Length - Source.Last then
  declare
 New_Size : constant Positive :=
-  S_Length + Chunk_Size + (S_Length / Growth_Factor);
+  Saturated_Sum
+(Sum (S_Length, Chunk_Size), S_Length / Growth_Factor);
 
 New_Rounded_Up_Size : constant Positive :=
-  ((New_Size - 1) / Min_Mul_Alloc + 1) * Min_Mul_Alloc;
+  Saturated_Mul
+((New_Size - 1) / Min_Mul_Alloc + 1, Min_Mul_Alloc);
 
 Tmp : constant String_Access :=
   new String (1 .. New_Rounded_Up_Size);
@@ -847,6 +872,30 @@ package body Ada.Strings.Unbounded is
   Free (Old);
end Replace_Slice;
 
+   ---
+   

[Ada] Ada2020: wording of 'Image messages

2020-07-27 Thread Pierre-Marie de Rodat
Change the wording of error messages about 'Image to indicate that newer
versions of the language allow more cases.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* errout.ads, errout.adb (Error_Msg_Ada_2020_Feature): New
procedure analogous to Error_Msg_Ada_2012_Feature.
* sem_attr.adb (Analyze_Image_Attribute): Use
Error_Msg_Ada_2012_Feature and Error_Msg_Ada_2020_Feature to
indicate that Object'Image is allowed in Ada 2012, and that
'Image is allowed for any type in Ada 2020.diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -630,6 +630,24 @@ package body Errout is
   end if;
end Error_Msg_Ada_2012_Feature;
 
+   
+   -- Error_Msg_Ada_2020_Feature --
+   
+
+   procedure Error_Msg_Ada_2020_Feature (Feature : String; Loc : Source_Ptr) is
+   begin
+  if Ada_Version < Ada_2020 then
+ Error_Msg (Feature & " is an Ada 2020 feature", Loc);
+
+ if No (Ada_Version_Pragma) then
+Error_Msg ("\unit must be compiled with -gnat2020 switch", Loc);
+ else
+Error_Msg_Sloc := Sloc (Ada_Version_Pragma);
+Error_Msg ("\incompatible with Ada version set#", Loc);
+ end if;
+  end if;
+   end Error_Msg_Ada_2020_Feature;
+
--
-- Error_Msg_AP --
--


diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads
--- a/gcc/ada/errout.ads
+++ b/gcc/ada/errout.ads
@@ -895,12 +895,15 @@ package Errout is
--  first formal (RM 9.4(11.9/3)).
 
procedure Error_Msg_Ada_2012_Feature (Feature : String; Loc : Source_Ptr);
-   --  If not operating in Ada 2012 mode, posts errors complaining that Feature
-   --  is only supported in Ada 2012, with appropriate suggestions to fix this.
-   --  Loc is the location at which the flag is to be posted. Feature, which
-   --  appears at the start of the first generated message, may contain error
-   --  message insertion characters in the normal manner, and in particular
-   --  may start with | to flag a non-serious error.
+   --  If not operating in Ada 2012 mode or higher, posts errors complaining
+   --  that Feature is only supported in Ada 2012, with appropriate suggestions
+   --  to fix this. Loc is the location at which the flag is to be posted.
+   --  Feature, which appears at the start of the first generated message, may
+   --  contain error message insertion characters in the normal manner, and in
+   --  particular may start with | to flag a non-serious error.
+
+   procedure Error_Msg_Ada_2020_Feature (Feature : String; Loc : Source_Ptr);
+   --  Analogous to Error_Msg_Ada_2012_Feature
 
procedure dmsg (Id : Error_Msg_Id) renames Erroutc.dmsg;
--  Debugging routine to dump an error message


diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -1457,16 +1457,11 @@ package body Sem_Attr is
 
  procedure Check_Image_Type (Image_Type : Entity_Id) is
  begin
-if Ada_Version >= Ada_2020 then
-   null; -- all types are OK
-elsif not Is_Scalar_Type (Image_Type) then
-   if Ada_Version >= Ada_2012 then
-  Error_Attr_P
-("prefix of % attribute must be a scalar type or a scalar "
-   & "object name");
-   else
-  Error_Attr_P ("prefix of % attribute must be a scalar type");
-   end if;
+if Ada_Version < Ada_2020
+  and then not Is_Scalar_Type (Image_Type)
+then
+   Error_Msg_Ada_2020_Feature ("|nonscalar ''Image", Sloc (P));
+   Error_Attr;
 end if;
  end Check_Image_Type;
 
@@ -1483,7 +1478,7 @@ package body Sem_Attr is
 Check_Image_Type (Etype (P));
 
 if Attr_Id /= Attribute_Img and then Ada_Version < Ada_2012 then
-   Error_Attr_P ("prefix of % attribute must be a scalar type");
+   Error_Msg_Ada_2012_Feature ("|Object''Image", Sloc (P));
 end if;
  else
 Check_E1;




[Ada] Remove disabled code

2020-07-27 Thread Pierre-Marie de Rodat
This old code is likely made obsolete by recent changes related to the
handling of the universal access "=" operator.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_attr.adb (Resolve_Attribute): Remove dead code.diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -10783,19 +10783,6 @@ package body Sem_Attr is
end;
 end if;
 
---  The following comes from a query concerning improper use of
---  universal_access in equality tests involving anonymous access
---  types. Another good reason for 'Ref, but for now disable the
---  test, which breaks several filed tests???
-
-if Ekind (Typ) = E_Anonymous_Access_Type
-  and then Nkind (Parent (N)) in N_Op_Eq | N_Op_Ne
-  and then False
-then
-   Error_Msg_N ("need unique type to resolve 'Access", N);
-   Error_Msg_N ("\qualify attribute with some access type", N);
-end if;
-
 --  Case where prefix is an entity name
 
 if Is_Entity_Name (P) then




[Ada] Remove obsolete special case in Switch_View

2020-07-27 Thread Pierre-Marie de Rodat
This removes obsolete code that would prevent a subtype dependent on a
private type from having its views switched when those of the private
type are switched by Switch_View.

Not switching the views in this case is problematic because this is not
in keeping with what the mechanism based on Install_Private_Declarations
& Uninstall_Declarations does for them, and this discrepancy runs afoul
of a nesting issue in Instantiate_Package_Body.

The issue is essentially only visible with inlining across units.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch12.adb (Instantiate_Package_Body): Add commentary for a
nesting issue with parent handling and private view switching.
(Switch_View): Do not skip specific private-dependent subtypes.diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -12029,6 +12029,19 @@ package body Sem_Ch12 is
  end if;
 
  Restore_Hidden_Primitives (Vis_Prims_List);
+
+ --  Restore the private views that were made visible when the body of
+ --  the instantiation was created. Note that, in the case where one of
+ --  these private views is declared in the parent, there is a nesting
+ --  issue with the calls to Install_Parent and Remove_Parent made in
+ --  between above with In_Body set to True, because these calls also
+ --  want to swap and restore this private view respectively. In this
+ --  case, the call to Install_Parent does nothing, but the call to
+ --  Remove_Parent does restore the private view, thus undercutting the
+ --  call to Restore_Private_Views. That's OK under the condition that
+ --  the two mechanisms swap exactly the same entities, in particular
+ --  the private entities dependent on the primary private entities.
+
  Restore_Private_Views (Act_Decl_Id);
 
  --  Remove the current unit from visibility if this is an instance
@@ -16680,19 +16693,9 @@ package body Sem_Ch12 is
   end if;
 
   while Present (Priv_Elmt) loop
- Priv_Sub := (Node (Priv_Elmt));
-
- --  We avoid flipping the subtype if the Etype of its full view is
- --  private because this would result in a malformed subtype. This
- --  occurs when the Etype of the subtype full view is the full view of
- --  the base type (and since the base types were just switched, the
- --  subtype is pointing to the wrong view). This is currently the case
- --  for tagged record types, access types (maybe more?) and needs to
- --  be resolved. ???
-
- if Present (Full_View (Priv_Sub))
-   and then not Is_Private_Type (Etype (Full_View (Priv_Sub)))
- then
+ Priv_Sub := Node (Priv_Elmt);
+
+ if Present (Full_View (Priv_Sub)) then
 Prepend_Elmt (Full_View (Priv_Sub), Exchanged_Views);
 Exchange_Declarations (Priv_Sub);
  end if;




[Ada] Ada2020: AI12-0304 Put_Image attrs of lang-def types

2020-07-27 Thread Pierre-Marie de Rodat
Implement Put_Image for the random number packages and for
Ada.Containers.Vectors. More to come.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* libgnat/s-rannum.ads, libgnat/s-rannum.adb: Add Put_Image.
This will be inherited by the language-defined packages
Ada.Numerics.Discrete_Random and Ada.Numerics.Float_Random.
* libgnat/a-convec.ads, libgnat/a-convec.adb: Add Put_Image.
* libgnat/s-putima.ads: Add pragma Preelaborate, so this can be
imported into containers packages.
* libgnat/s-putima.adb: Move Digit to private part; otherwise
reference to Base is illegal in Preelaborate generic.
* exp_put_image.adb (Build_Record_Put_Image_Procedure): Use the
base type.diff --git a/gcc/ada/exp_put_image.adb b/gcc/ada/exp_put_image.adb
--- a/gcc/ada/exp_put_image.adb
+++ b/gcc/ada/exp_put_image.adb
@@ -520,8 +520,8 @@ package body Exp_Put_Image is
   Decl : out Node_Id;
   Pnam : out Entity_Id)
is
-  pragma Assert (Typ = Base_Type (Typ));
-  pragma Assert (not Is_Unchecked_Union (Typ));
+  Btyp : constant Entity_Id := Base_Type (Typ);
+  pragma Assert (not Is_Unchecked_Union (Btyp));
 
   First_Time : Boolean := True;
 
@@ -694,7 +694,7 @@ package body Exp_Put_Image is
   Stms : constant List_Id := New_List;
   Rdef : Node_Id;
   Type_Decl : constant Node_Id :=
-Declaration_Node (Base_Type (Underlying_Type (Typ)));
+Declaration_Node (Base_Type (Underlying_Type (Btyp)));
 
--  Start of processing for Build_Record_Put_Image_Procedure
 
@@ -732,8 +732,8 @@ package body Exp_Put_Image is
   Parameter_Associations => New_List
 (Make_Identifier (Loc, Name_S;
 
-  Pnam := Make_Put_Image_Name (Loc, Typ);
-  Build_Put_Image_Proc (Loc, Typ, Decl, Pnam, Stms);
+  Pnam := Make_Put_Image_Name (Loc, Btyp);
+  Build_Put_Image_Proc (Loc, Btyp, Decl, Pnam, Stms);
end Build_Record_Put_Image_Procedure;
 
---


diff --git a/gcc/ada/libgnat/a-convec.adb b/gcc/ada/libgnat/a-convec.adb
--- a/gcc/ada/libgnat/a-convec.adb
+++ b/gcc/ada/libgnat/a-convec.adb
@@ -31,6 +31,7 @@ with Ada.Containers.Generic_Array_Sort;
 with Ada.Unchecked_Deallocation;
 
 with System; use type System.Address;
+with System.Put_Images;
 
 package body Ada.Containers.Vectors with
   SPARK_Mode => Off
@@ -2299,6 +2300,31 @@ is
   end return;
end Pseudo_Reference;
 
+   ---
+   -- Put_Image --
+   ---
+
+   procedure Put_Image
+ (S : in out Ada.Strings.Text_Output.Sink'Class; V : Vector)
+   is
+  First_Time : Boolean := True;
+  use System.Put_Images;
+   begin
+  Array_Before (S);
+
+  for X of V loop
+ if First_Time then
+First_Time := False;
+ else
+Simple_Array_Between (S);
+ end if;
+
+ Element_Type'Put_Image (S, X);
+  end loop;
+
+  Array_After (S);
+   end Put_Image;
+
---
-- Query_Element --
---


diff --git a/gcc/ada/libgnat/a-convec.ads b/gcc/ada/libgnat/a-convec.ads
--- a/gcc/ada/libgnat/a-convec.ads
+++ b/gcc/ada/libgnat/a-convec.ads
@@ -36,6 +36,7 @@ with Ada.Iterator_Interfaces;
 with Ada.Containers.Helpers;
 private with Ada.Finalization;
 private with Ada.Streams;
+private with Ada.Strings.Text_Output;
 
 --  The language-defined generic package Containers.Vectors provides private
 --  types Vector and Cursor, and a set of operations for each type. A vector
@@ -696,7 +697,10 @@ private
   Elements : Elements_Access := null;
   Last : Extended_Index := No_Index;
   TC   : aliased Tamper_Counts;
-   end record;
+   end record with Put_Image => Put_Image;
+
+   procedure Put_Image
+ (S : in out Ada.Strings.Text_Output.Sink'Class; V : Vector);
 
overriding procedure Adjust (Container : in out Vector);
overriding procedure Finalize (Container : in out Vector);


diff --git a/gcc/ada/libgnat/s-putima.adb b/gcc/ada/libgnat/s-putima.adb
--- a/gcc/ada/libgnat/s-putima.adb
+++ b/gcc/ada/libgnat/s-putima.adb
@@ -46,13 +46,14 @@ package body System.Put_Images is
   pragma Assert (Base in 2 .. 36);
   procedure Put_Image (S : in out Sink'Class; X : Integer_Type);
   procedure Put_Image (S : in out Sink'Class; X : Unsigned_Type);
+   private
+  subtype Digit is Unsigned_Type range 0 .. Base - 1;
end Generic_Integer_Images;
 
package body Generic_Integer_Images is
 
   A : constant := Character'Pos ('a');
   Z : constant := Character'Pos ('0');
-  subtype Digit is Unsigned_Type range 0 .. Base - 1;
   function Digit_To_Character (X : Digit) return Character is
 (Character'Val (if X < 10 then X + Z else X + A - 10));
 


diff --git a/gcc/ada/libgnat/s-putima.ads b/gcc/ada/libgnat/s-putima.ads
--- a/gcc/ada/libgnat/s-putima.ads
+++ b/gcc/ada/libgnat/s-putima.ads
@@ -47,6 +47,8 @@ package System.Put_I

[Ada] Bug in Enum_Subtype'Image in Ada 2020 mode

2020-07-27 Thread Pierre-Marie de Rodat
This patch fixes a bug in which Enum_Subtype'Image, where Enum_Subtype
is a non-first subtype of an enumeration type, would return the image of
the 'Pos -- that is, an integer instead of the text of the enumeration
literal.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_imgv.adb (Expand_Image_Attribute): Add Root_Type, so
constrained subtypes work.diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb
--- a/gcc/ada/exp_imgv.adb
+++ b/gcc/ada/exp_imgv.adb
@@ -483,7 +483,7 @@ package body Exp_Imgv is
   --  underlying type.
 
   if Ada_Version >= Ada_2020 then
- Rtyp := Underlying_Type (Ptyp);
+ Rtyp := Underlying_Type (Root_Type (Ptyp));
   else
  Rtyp := Root_Type (Ptyp);
   end if;




[Ada] AI12-0383 Renaming values

2020-07-27 Thread Pierre-Marie de Rodat
This AI allows names that denote values rather than objects to
nevertheless be renamed using an object renaming.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_ch8.adb (Analyze_Object_Renaming): Allow values in Ada
2020 mode.diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -918,7 +918,8 @@ package body Sem_Ch8 is
if No (Etype (Nam))
  or else Etype (Nam) = Standard_Void_Type
then
-  Error_Msg_N ("object name expected in renaming", Nam);
+  Error_Msg_N
+("object name or value expected in renaming", Nam);
 
   Set_Ekind (Id, E_Variable);
   Set_Etype (Id, Any_Type);
@@ -965,7 +966,8 @@ package body Sem_Ch8 is
   --  as overloaded procedures named in the object renaming).
 
   if No (It.Typ) then
- Error_Msg_N ("object name expected in renaming", Nam);
+ Error_Msg_N
+   ("object name or value expected in renaming", Nam);
 
  Set_Ekind (Id, E_Variable);
  Set_Etype (Id, Any_Type);
@@ -996,6 +998,12 @@ package body Sem_Ch8 is
   T := It1.Typ;
end;
 end if;
+
+if Etype (Nam) = Standard_Exception_Type then
+   Error_Msg_N
+ ("exception requires a subtype mark in renaming", Nam);
+   return;
+end if;
  end if;
 
  --  The object renaming declaration may become Ghost if it renames a
@@ -1396,8 +1404,19 @@ package body Sem_Ch8 is
 and then Nkind (Original_Node (Nam)) /= N_Attribute_Reference
   then
  null;
-  else
- Error_Msg_N ("expect object name in renaming", Nam);
+
+  --  A named number can only be renamed without a subtype mark
+
+  elsif Nkind (Nam) in N_Real_Literal | N_Integer_Literal
+and then Present (Subtype_Mark (N))
+and then Present (Original_Entity (Nam))
+  then
+ Error_Msg_N ("incompatible types in renaming", Nam);
+
+  --  AI12-0383: Names that denote values can be renamed
+
+  elsif Ada_Version < Ada_2020 then
+ Error_Msg_N ("value in renaming requires -gnat2020", Nam);
   end if;
 
   Set_Etype (Id, T2);




[Ada] AI12-0377 View conversions and out parameters revisited

2020-07-27 Thread Pierre-Marie de Rodat
This AI refines AI12-0074 to disallow cases of potential de-initializing
of out parameters.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* sem_res.adb (Resolve_Actuals): Refine 6.4.1 rules as per
AI12-0377.diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -4175,27 +4175,34 @@ package body Sem_Res is
 end if;
  end if;
 
-  --  AI12-0074
+  --  AI12-0074 & AI12-0377
   --  Check 6.4.1: If the mode is out, the actual parameter is
   --  a view conversion, and the type of the formal parameter
-  --  is a scalar type that has the Default_Value aspect
-  --  specified, then
-  --- there shall exist a type (other than a root numeric
-  --  type) that is an ancestor of both the target type and
-  --  the operand type; and
-  --- the type of the operand of the conversion shall have
-  --  the Default_Value aspect specified.
+  --  is a scalar type, then either:
+  --- the target and operand type both do not have the
+  --  Default_Value aspect specified; or
+  --- the target and operand type both have the
+  --  Default_Value aspect specified, and there shall exist
+  --  a type (other than a root numeric type) that is an
+  --  ancestor of both the target type and the operand
+  --  type.
 
   elsif Ekind (F) = E_Out_Parameter
 and then Is_Scalar_Type (Etype (F))
-and then Present (Default_Aspect_Value (Etype (F)))
-and then
-  (not Same_Ancestor (Etype (F), Expr_Typ)
- or else No (Default_Aspect_Value (Expr_Typ)))
   then
- Error_Msg_N
-   ("view conversion between unrelated types with "
-& "Default_Value not allowed (RM 6.4.1)", A);
+ if Has_Default_Aspect (Etype (F)) /=
+Has_Default_Aspect (Expr_Typ)
+ then
+Error_Msg_N
+  ("view conversion requires Default_Value on both " &
+   "types (RM 6.4.1)", A);
+ elsif Has_Default_Aspect (Expr_Typ)
+   and then not Same_Ancestor (Etype (F), Expr_Typ)
+ then
+Error_Msg_N
+  ("view conversion between unrelated types with "
+   & "Default_Value not allowed (RM 6.4.1)", A);
+ end if;
   end if;
end;
 




[Ada] Wrong accessibility on 'Access of formal in call

2020-07-27 Thread Pierre-Marie de Rodat
This patch fixes a bug in the compiler whereby taking 'Access on a
component of an anonymous access formal parameter and using such an
expression as an actual in a call where the corresponding formal is also
an anonymous access type will cause dynamic accessibility checks within
the callee function to not be performed.

This is also an iterative patch for overall accessibility work.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_ch6.adb (Expand_Call_Helper): Modify addition of the extra
accessibility parameter to take into account the extra
accessibility of formals within the calling subprogram.diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -3264,7 +3264,7 @@ package body Exp_Ch6 is
   Param_Count   : Natural := 0;
   Parent_Formal : Entity_Id;
   Parent_Subp   : Entity_Id;
-  Pref_Entity   : Entity_Id;
+  Prev_Ult  : Node_Id;
   Scop  : Entity_Id;
   Subp  : Entity_Id;
 
@@ -3824,60 +3824,30 @@ package body Exp_Ch6 is
 Expression (Original_Node (Prev_Orig));
end if;
 
-   --  If this is an Access attribute applied to the
-   --  the current instance object passed to a type
-   --  initialization procedure, then use the level
-   --  of the type itself. This is not really correct,
-   --  as there should be an extra level parameter
-   --  passed in with _init formals (only in the case
-   --  where the type is immutably limited), but we
-   --  don't have an easy way currently to create such
-   --  an extra formal (init procs aren't ever frozen).
-   --  For now we just use the level of the type,
-   --  which may be too shallow, but that works better
-   --  than passing Object_Access_Level of the type,
-   --  which can be one level too deep in some cases.
-   --  ???
-
-   --  A further case that requires special handling
-   --  is the common idiom E.all'access. If E is a
-   --  formal of the enclosing subprogram, the
-   --  accessibility of the expression is that of E.
-
-   if Is_Entity_Name (Prev_Orig) then
-  Pref_Entity := Entity (Prev_Orig);
-
-   elsif Nkind (Prev_Orig) = N_Explicit_Dereference
- and then Is_Entity_Name (Prefix (Prev_Orig))
-   then
-  Pref_Entity := Entity (Prefix ((Prev_Orig)));
+   --  Obtain the ultimate prefix so we can check for
+   --  the case where we are taking 'Access of a
+   --  component of an anonymous access formal - which
+   --  would mean we need to pass said formal's
+   --  corresponding extra accessibility formal.
 
-   else
-  Pref_Entity := Empty;
-   end if;
+   Prev_Ult := Ultimate_Prefix (Prev_Orig);
 
-   if Is_Entity_Name (Prev_Orig)
- and then Is_Type (Entity (Prev_Orig))
-   then
-  Add_Extra_Actual
-(Expr =>
-   Make_Integer_Literal (Loc,
- Intval =>
-   Type_Access_Level (Pref_Entity)),
- EF   => Get_Accessibility (Formal));
-
-   elsif Nkind (Prev_Orig) = N_Explicit_Dereference
- and then Present (Pref_Entity)
- and then Is_Formal (Pref_Entity)
+   if Is_Entity_Name (Prev_Ult)
+ and then not Is_Type (Entity (Prev_Ult))
  and then Present
-(Get_Accessibility (Pref_Entity))
+(Get_Accessibility
+  (Entity (Prev_Ult)))
then
   Add_Extra_Actual
 (Expr =>
New_Occurrence_Of
- (Get_Accessibility (Pref_Entity), Loc),
+ (Get_Accessibility
+(Entity (Prev_Ult)), Loc),

[Ada] Revert "Revamp dump and aux output names"

2020-07-27 Thread Pierre-Marie de Rodat
This reverts commit 593627b4562814d2206e53e9ad6ce2e85295aa58.

That commit was installed in GCC by mistake, bringing it in sync with an
earlier, internal transitory state that had just been resolved in a
separate patch.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* switch.adb (Is_Internal_GCC_Switch): Revert accidental
reintroduction of auxbase and auxbase-strip.diff --git a/gcc/ada/switch.adb b/gcc/ada/switch.adb
--- a/gcc/ada/switch.adb
+++ b/gcc/ada/switch.adb
@@ -165,10 +165,7 @@ package body Switch is
   (Switch_Chars (First .. Last) = "-param"or else
Switch_Chars (First .. Last) = "dumpdir"   or else
Switch_Chars (First .. Last) = "dumpbase"  or else
-   Switch_Chars (First .. Last) = "dumpbase-ext"  or else
-   -- Can we remove auxbase-strip and auxbase already?
-   Switch_Chars (First .. Last) = "auxbase-strip" or else
-   Switch_Chars (First .. Last) = "auxbase");
+   Switch_Chars (First .. Last) = "dumpbase-ext");
end Is_Internal_GCC_Switch;
 
---




[Ada] Switch Ada_Version_Runtime to Ada 2020

2020-07-27 Thread Pierre-Marie de Rodat
Now that we're adding more and more Ada 2020 specific aspects in runtime
units, this is the convenient thing to do. Note that this doesn't impact
the Ada version used by user code.

Also fix a latent bug in sem_ch3 along the way, showing up when
System.Atomic_Primitives generic children are compiled in Ada 2020 mode.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* opt.ads (Ada_Version_Runtime): Set to Ada_2020.
* sem_ch3.adb (Analyze_Subtype_Declaration): Propagate
Is_Independent flag to subtypes.
* libgnarl/s-taprop__linux.adb: Adapt to Ada 2020 warning.
* libgnat/a-nbnbin.adb, libgnat/a-nbnbin.ads,
libgnat/a-nbnbin__gmp.adb, libgnat/a-nbnbre.adb,
libgnat/a-nbnbre.ads, libgnat/a-stobbu.adb,
libgnat/a-stobbu.ads, libgnat/a-stobfi.adb,
libgnat/a-stobfi.ads, libgnat/a-stoubu.adb,
libgnat/a-stoubu.ads, libgnat/a-stoufi.adb,
libgnat/a-stoufi.ads, libgnat/a-stoufo.adb,
libgnat/a-stoufo.ads, libgnat/a-stouut.adb,
libgnat/a-stouut.ads, libgnat/a-strsto.ads,
libgnat/a-ststbo.adb, libgnat/a-ststbo.ads,
libgnat/a-ststun.adb, libgnat/a-ststun.ads,
libgnat/a-stteou.ads, libgnat/s-aoinar.ads,
libgnat/s-aomoar.ads, libgnat/s-atopex.ads,
libgnat/s-putaim.adb, libgnat/s-putaim.ads,
libgnat/s-putima.adb, libgnat/s-putima.ads: Remove pragma
Ada_2020, now redundant.diff --git a/gcc/ada/libgnarl/s-taprop__linux.adb b/gcc/ada/libgnarl/s-taprop__linux.adb
--- a/gcc/ada/libgnarl/s-taprop__linux.adb
+++ b/gcc/ada/libgnarl/s-taprop__linux.adb
@@ -243,9 +243,9 @@ package body System.Task_Primitives.Operations is
   return Ceiling_Support;
end Get_Ceiling_Support;
 
-   pragma Warnings (Off, "non-static call not allowed in preelaborated unit");
+   pragma Warnings (Off, "non-preelaborable call not allowed*");
Ceiling_Support : constant Boolean := Get_Ceiling_Support;
-   pragma Warnings (On, "non-static call not allowed in preelaborated unit");
+   pragma Warnings (On, "non-preelaborable call not allowed*");
--  True if the locking policy is Ceiling_Locking, and the current process
--  has permission to use this policy. The process has permission if it is
--  running as 'root', or if the capability was set by the setcap command,


diff --git a/gcc/ada/libgnat/a-nbnbin.adb b/gcc/ada/libgnat/a-nbnbin.adb
--- a/gcc/ada/libgnat/a-nbnbin.adb
+++ b/gcc/ada/libgnat/a-nbnbin.adb
@@ -29,8 +29,6 @@
 --  --
 --
 
-pragma Ada_2020;
-
 with Ada.Unchecked_Deallocation;
 with Ada.Strings.Text_Output.Utils;
 


diff --git a/gcc/ada/libgnat/a-nbnbin.ads b/gcc/ada/libgnat/a-nbnbin.ads
--- a/gcc/ada/libgnat/a-nbnbin.ads
+++ b/gcc/ada/libgnat/a-nbnbin.ads
@@ -13,8 +13,6 @@
 --  --
 --
 
-pragma Ada_2020;
-
 with Ada.Strings.Text_Output; use Ada.Strings.Text_Output;
 
 private with Ada.Finalization;


diff --git a/gcc/ada/libgnat/a-nbnbin__gmp.adb b/gcc/ada/libgnat/a-nbnbin__gmp.adb
--- a/gcc/ada/libgnat/a-nbnbin__gmp.adb
+++ b/gcc/ada/libgnat/a-nbnbin__gmp.adb
@@ -31,8 +31,6 @@
 
 --  This is the GMP version of this package
 
-pragma Ada_2020;
-
 with Ada.Unchecked_Conversion;
 with Ada.Unchecked_Deallocation;
 with Interfaces.C;   use Interfaces.C;


diff --git a/gcc/ada/libgnat/a-nbnbre.adb b/gcc/ada/libgnat/a-nbnbre.adb
--- a/gcc/ada/libgnat/a-nbnbre.adb
+++ b/gcc/ada/libgnat/a-nbnbre.adb
@@ -31,8 +31,6 @@
 
 --  This is the default version of this package, based on Big_Integers only.
 
-pragma Ada_2020;
-
 with Ada.Strings.Text_Output.Utils;
 
 package body Ada.Numerics.Big_Numbers.Big_Reals is


diff --git a/gcc/ada/libgnat/a-nbnbre.ads b/gcc/ada/libgnat/a-nbnbre.ads
--- a/gcc/ada/libgnat/a-nbnbre.ads
+++ b/gcc/ada/libgnat/a-nbnbre.ads
@@ -13,8 +13,6 @@
 --  --
 --
 
-pragma Ada_2020;
-
 with Ada.Numerics.Big_Numbers.Big_Integers;
 
 with Ada.Strings.Text_Output; use Ada.Strings.Text_Output;


diff --git a/gcc/ada/libgnat/a-stobbu.adb b/gcc/ada/libgnat/a-stobbu.adb
--- a/gcc/ada/libgnat/a-stobbu.adb
+++ b/gcc/ada/libgnat/a-stobbu.adb
@@ -29,8 +29,6 @@
 --  --
 --
 
-pragma Ada_2020;
-
 package body Ada.Strings.Text_Output.Bit_Buckets is
 
type Bit_Bucket_Type is new Sink with null record;


diff --git a/gcc/ada/libgnat/a-stobbu.ads b/gcc/ada/libgnat/a-stobbu.ads
--- a/gcc/ada/libgnat/a-stobbu.ads
+++ b/gcc/ada/libgnat/a-stobbu.ads
@@ -29,8 +29,6 @@
 --   

[Ada] Refactor pragma argument getters

2020-07-27 Thread Pierre-Marie de Rodat
This refactoring replaces exp_prag.adb's Arg1, Arg2 and Arg3 functions
with a new function Arg_N which enables fetching any pragma arguments.

Tested on x86_64-pc-linux-gnu, committed on trunk

gcc/ada/

* exp_prag.adb (Arg1, Arg2, Arg3): Removed.
(Arg_N): New function.diff --git a/gcc/ada/exp_prag.adb b/gcc/ada/exp_prag.adb
--- a/gcc/ada/exp_prag.adb
+++ b/gcc/ada/exp_prag.adb
@@ -61,9 +61,7 @@ package body Exp_Prag is
-- Local Subprograms --
---
 
-   function Arg1 (N : Node_Id) return Node_Id;
-   function Arg2 (N : Node_Id) return Node_Id;
-   function Arg3 (N : Node_Id) return Node_Id;
+   function Arg_N (N : Node_Id; Arg_Number : Positive) return Node_Id;
--  Obtain specified pragma argument expression
 
procedure Expand_Pragma_Abort_Defer (N : Node_Id);
@@ -84,13 +82,24 @@ package body Exp_Prag is
--  these cases we want no initialization to occur, but we have already done
--  the initialization by the time we see the pragma, so we have to undo it.
 
-   --
-   -- Arg1 --
-   --
+   ---
+   -- Arg_N --
+   ---
 
-   function Arg1 (N : Node_Id) return Node_Id is
-  Arg : constant Node_Id := First (Pragma_Argument_Associations (N));
+   function Arg_N (N : Node_Id; Arg_Number : Positive) return Node_Id is
+  Arg : Node_Id := First (Pragma_Argument_Associations (N));
begin
+  if No (Arg) then
+ return Empty;
+  end if;
+
+  for J in 2 .. Arg_Number loop
+ Next (Arg);
+ if No (Arg) then
+return Empty;
+ end if;
+  end loop;
+
   if Present (Arg)
 and then Nkind (Arg) = N_Pragma_Argument_Association
   then
@@ -98,66 +107,7 @@ package body Exp_Prag is
   else
  return Arg;
   end if;
-   end Arg1;
-
-   --
-   -- Arg2 --
-   --
-
-   function Arg2 (N : Node_Id) return Node_Id is
-  Arg1 : constant Node_Id := First (Pragma_Argument_Associations (N));
-
-   begin
-  if No (Arg1) then
- return Empty;
-
-  else
- declare
-Arg : constant Node_Id := Next (Arg1);
- begin
-if Present (Arg)
-  and then Nkind (Arg) = N_Pragma_Argument_Association
-then
-   return Expression (Arg);
-else
-   return Arg;
-end if;
- end;
-  end if;
-   end Arg2;
-
-   --
-   -- Arg3 --
-   --
-
-   function Arg3 (N : Node_Id) return Node_Id is
-  Arg1 : constant Node_Id := First (Pragma_Argument_Associations (N));
-
-   begin
-  if No (Arg1) then
- return Empty;
-
-  else
- declare
-Arg : Node_Id := Next (Arg1);
- begin
-if No (Arg) then
-   return Empty;
-
-else
-   Next (Arg);
-
-   if Present (Arg)
- and then Nkind (Arg) = N_Pragma_Argument_Association
-   then
-  return Expression (Arg);
-   else
-  return Arg;
-   end if;
-end if;
- end;
-  end if;
-   end Arg3;
+   end Arg_N;
 
-
-- Expand_N_Pragma --
@@ -317,8 +267,8 @@ package body Exp_Prag is
--
 
procedure Expand_Pragma_Check (N : Node_Id) is
-  Cond : constant Node_Id := Arg2 (N);
-  Nam  : constant Name_Id := Chars (Arg1 (N));
+  Cond : constant Node_Id := Arg_N (N, 2);
+  Nam  : constant Name_Id := Chars (Arg_N (N, 1));
   Msg  : Node_Id;
 
   Loc : constant Source_Ptr := Sloc (First_Node (Cond));
@@ -477,7 +427,7 @@ package body Exp_Prag is
   if ((Debug_Flag_Dot_G
 or else Restriction_Active (No_Exception_Propagation))
and then Present (Find_Local_Handler (RTE (RE_Assert_Failure), N)))
-or else (Opt.Exception_Locations_Suppressed and then No (Arg3 (N)))
+or else (Opt.Exception_Locations_Suppressed and then No (Arg_N (N, 3)))
   then
  Rewrite (N,
Make_If_Statement (Loc,
@@ -491,8 +441,8 @@ package body Exp_Prag is
   else
  --  If we have a message given, use it
 
- if Present (Arg3 (N)) then
-Msg := Get_Pragma_Arg (Arg3 (N));
+ if Present (Arg_N (N, 3)) then
+Msg := Get_Pragma_Arg (Arg_N (N, 3));
 
  --  Here we have no string, so prepare one
 
@@ -615,8 +565,8 @@ package body Exp_Prag is
procedure Expand_Pragma_Common_Object (N : Node_Id) is
   Loc : constant Source_Ptr := Sloc (N);
 
-  Internal : constant Node_Id := Arg1 (N);
-  External : constant Node_Id := Arg2 (N);
+  Internal : constant Node_Id := Arg_N (N, 1);
+  External : constant Node_Id := Arg_N (N, 2);
 
   Psect : Node_Id;
   --  Psect value upper cased as string literal
@@ -1380,11 +1330,11 @@ package body Exp_Prag is
   if Relaxed_RM_Semantics
 and then List_Len

Re: [PATCH] [RFC] vect: Fix infinite loop while determining peeling amount

2020-07-27 Thread Richard Sandiford
Richard Biener via Gcc-patches  writes:
> On Wed, Jul 22, 2020 at 5:18 PM Stefan Schulze Frielinghaus via
> Gcc-patches  wrote:
>>
>> This is a follow up to commit 5c9669a0e6c respectively discussion
>> https://gcc.gnu.org/pipermail/gcc-patches/2020-June/549132.html
>>
>> In case that an alignment constraint is less than the size of a
>> corresponding scalar type, ensure that we advance at least by one
>> iteration.  For example, on s390x we have for a long double an alignment
>> constraint of 8 bytes whereas the size is 16 bytes.  Therefore,
>> TARGET_ALIGN / DR_SIZE equals zero resulting in an infinite loop which
>> can be reproduced by the following MWE:
>
> But we guard this case with vector_alignment_reachable_p, so we shouldn't
> have ended up here and the patch looks bogus.

The above sounds like it ought to count as reachable alignment though.
If a type requires a lower alignment than its size, then that's even
more easily reachable than a type that requires the same alignment as
the size.  I guess at one extreme, a target alignment of 1 is always
reachable.

Thanks,
Richard


Re: [PATCH v3] driver: fix a problem with implementation of -falign-foo=0 [PR96247]

2020-07-27 Thread Richard Sandiford
Hu Jiangping  writes:
> Hi!
>
> This patch makes the -falign-foo=0 work as described in the
> documentation. Thanks for all the suggestions, Richard and Segher!
>
> v3: make change more readable and self-consistent
> v2: at a high level handles -falign-foo=0 like -falign-foo

Thanks, this is OK with some minor nits for coding conventions.
Could you add a GNU changelog too?  See:

http://www.gnu.org/prep/standards/html_node/Change-Logs.html

for the conventions.

> Regards!
> Hujp
>
> ---
>  gcc/opts.c | 24 +++-
>  1 file changed, 19 insertions(+), 5 deletions(-)
>
> diff --git a/gcc/opts.c b/gcc/opts.c
> index 499eb900643..dec5ba6d2be 100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -2007,10 +2007,20 @@ parse_and_check_align_values (const char *flag,
> location LOC.  */
>  
>  static void
> -check_alignment_argument (location_t loc, const char *flag, const char *name)
> +check_alignment_argument (location_t loc,
> +const char *flag,
> +const char *name,
> +int *opt_flag,
> +const char **opt_str)

The function comment needs to mention the new parameters.  Maybe just add:

  OPT_STR points to the stored -falign-NAME= argument and
   OPT_FLAG points to the associated -falign-NAME on/off flag.  */

It's more usual in GCC to put as many arguments on one line as possible,
so maybe:

check_alignment_argument (location_t loc, const char *flag, const char *name,
  int *opt_flag, const char **opt_str)

>  {
>auto_vec align_result;
>parse_and_check_align_values (flag, name, align_result, true, loc);
> +
> +  if (align_result.length() >= 1 && align_result[0] == 0)
> +  {
> +*opt_flag = 1;
> +*opt_str = NULL;
> +  }

The GCC style is to indent the braced “if” body by 2 more spaces:

  if (align_result.length() >= 1 && align_result[0] == 0)
{
  *opt_flag = 1;
  *opt_str = NULL;
}

>  }
>  
>  /* Print help when OPT__help_ is set.  */
> @@ -2785,19 +2795,23 @@ common_handle_option (struct gcc_options *opts,
>break;
>  
>  case OPT_falign_loops_:
> -  check_alignment_argument (loc, arg, "loops");
> +  check_alignment_argument (loc, arg, "loops",
> +  &opts->x_flag_align_loops, &opts->x_str_align_loops);

For multi-line argument lists, the second and subsequent lines should
be indented under the first argument.  So maybe something like:

  check_alignment_argument (loc, arg, "loops",
&opts->x_flag_align_loops,
&opts->x_str_align_loops);

Thanks,
Richard


Re: [PATCH] [RFC] vect: Fix infinite loop while determining peeling amount

2020-07-27 Thread Richard Biener via Gcc-patches
On Mon, Jul 27, 2020 at 11:09 AM Richard Sandiford
 wrote:
>
> Richard Biener via Gcc-patches  writes:
> > On Wed, Jul 22, 2020 at 5:18 PM Stefan Schulze Frielinghaus via
> > Gcc-patches  wrote:
> >>
> >> This is a follow up to commit 5c9669a0e6c respectively discussion
> >> https://gcc.gnu.org/pipermail/gcc-patches/2020-June/549132.html
> >>
> >> In case that an alignment constraint is less than the size of a
> >> corresponding scalar type, ensure that we advance at least by one
> >> iteration.  For example, on s390x we have for a long double an alignment
> >> constraint of 8 bytes whereas the size is 16 bytes.  Therefore,
> >> TARGET_ALIGN / DR_SIZE equals zero resulting in an infinite loop which
> >> can be reproduced by the following MWE:
> >
> > But we guard this case with vector_alignment_reachable_p, so we shouldn't
> > have ended up here and the patch looks bogus.
>
> The above sounds like it ought to count as reachable alignment though.
> If a type requires a lower alignment than its size, then that's even
> more easily reachable than a type that requires the same alignment as
> the size.  I guess at one extreme, a target alignment of 1 is always
> reachable.

Well, if the element alignment is 8 but its size is 16 then when presumably
the desired vector alignment is a multiple of 16 we can never reach it.
Isn't this the case here?

Richard.

> Thanks,
> Richard


Re: [PATCH] Using gen_int_mode instead of GEN_INT to avoid ICE caused by type promotion.

2020-07-27 Thread Hongtao Liu via Gcc-patches
ping

On Wed, Jul 22, 2020 at 3:57 PM Hongtao Liu  wrote:
>
>   Bootstrap is ok, regression test is ok for i386 backend.
>
> gcc/
> PR target/96262
> * config/i386/i386-expand.c
> (ix86_expand_vec_shift_qihi_constant): Refine.
>
> gcc/testsuite/
> * gcc.target/i386/pr96262-1.c: New test.
>
> ---
>  gcc/config/i386/i386-expand.c |  6 +++---
>  gcc/testsuite/gcc.target/i386/pr96262-1.c | 11 +++
>  2 files changed, 14 insertions(+), 3 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr96262-1.c
>
> diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
> index e194214804b..d57d043106a 100644
> --- a/gcc/config/i386/i386-expand.c
> +++ b/gcc/config/i386/i386-expand.c
> @@ -19537,7 +19537,7 @@ bool
>  ix86_expand_vec_shift_qihi_constant (enum rtx_code code, rtx dest,
> rtx op1, rtx op2)
>  {
>machine_mode qimode, himode;
> -  unsigned int and_constant, xor_constant;
> +  HOST_WIDE_INT and_constant, xor_constant;
>HOST_WIDE_INT shift_amount;
>rtx vec_const_and, vec_const_xor;
>rtx tmp, op1_subreg;
> @@ -19612,7 +19612,7 @@ ix86_expand_vec_shift_qihi_constant (enum
> rtx_code code, rtx dest, rtx op1, rtx
>emit_move_insn (dest, simplify_gen_subreg (qimode, tmp, himode, 0));
>emit_move_insn (vec_const_and,
>   ix86_build_const_vector (qimode, true,
> -  GEN_INT (and_constant)));
> +  gen_int_mode (and_constant,
> QImode)));
>emit_insn (gen_and (dest, dest, vec_const_and));
>
>/* For ASHIFTRT, perform extra operation like
> @@ -19623,7 +19623,7 @@ ix86_expand_vec_shift_qihi_constant (enum
> rtx_code code, rtx dest, rtx op1, rtx
>vec_const_xor = gen_reg_rtx (qimode);
>emit_move_insn (vec_const_xor,
>   ix86_build_const_vector (qimode, true,
> -  GEN_INT (xor_constant)));
> +  gen_int_mode
> (xor_constant, QImode)));
>emit_insn (gen_xor (dest, dest, vec_const_xor));
>emit_insn (gen_sub (dest, dest, vec_const_xor));
>  }
> diff --git a/gcc/testsuite/gcc.target/i386/pr96262-1.c
> b/gcc/testsuite/gcc.target/i386/pr96262-1.c
> new file mode 100644
> index 000..1825388072e
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr96262-1.c
> @@ -0,0 +1,11 @@
> +/* PR target/96262 */
> +/* { dg-do compile } */
> +/* { dg-options "-mavx512bw -O" } */
> +
> +typedef char __attribute__ ((__vector_size__ (64))) V;
> +
> +V
> +foo (V v)
> +{
> +  return ~(v << 1);
> +}
> --
>
> --
> BR,
> Hongtao



-- 
BR,
Hongtao


Re: [PATCH] [AVX512]For vector compare to mask register, UNSPEC is needed instead of comparison operator [PR96243]

2020-07-27 Thread Hongtao Liu via Gcc-patches
ping

On Mon, Jul 20, 2020 at 4:40 PM Hongtao Liu  wrote:
>
> Correct PR number in ChangeLog
> it's pr96243.
>
> On Mon, Jul 20, 2020 at 1:46 PM Hongtao Liu  wrote:
> >
> > Hi:
> >   For rtx like (eq:HI (V8SI 90) (V8SI 91)), cse will take it as a
> > boolean value and try to do some optimization. But it is not true for
> > vector compare, also other places in rtl passes hold the same
> > assumption.
> >
> > Bootstrap is ok, regression test is ok for i386 backend.
> >
> > 2020-07-20  Hongtao Liu  
> >
> > gcc/
> > PR target/96243
> > * config/i386/i386-expand.c (ix86_expand_sse_cmp): Refine for
> > maskcmp.
> > (ix86_expand_mask_vec_cmp): Change prototype.
> > * config/i386/i386-protos.h (ix86_expand_mask_vec_cmp): Change
> > prototype.
> > * config/i386/i386.c (ix86_print_operand): Remove operand
> > modifier 'I'.
> > * config/i386/sse.md
> > (*_cmp3,
> > *_cmp3,
> > *_ucmp3,
> > *_ucmp3,
> > avx512f_maskcmp3): Deleted.
> >
> > gcc/testsuite
> > * gcc.target/i386/pr92865-1.c: Adjust testcase.
> >
> >
> > --
> > BR,
> > Hongtao
>
>
>
> --
> BR,
> Hongtao



-- 
BR,
Hongtao


Re: [PATCH][AVX512][PR96246] Merge two define_insn: _blendm, _load_mask.

2020-07-27 Thread Hongtao Liu via Gcc-patches
ping

On Wed, Jul 22, 2020 at 12:59 PM Hongtao Liu  wrote:
>
>   Those two define_insns have same pattern, and
> _load_mask would always be matched since it show up
> earlier in the md file, and it may lose some opportunity in
> pass_reload since _load_mask only have constraint "0C"
> for operand2, and "v" constraint in _vblendm would never
> be matched.
>
> 2020-07-21  Hongtao Liu  
>
> gcc/
>PR target/96246
> * config/i386/sse.md (_load_mask,
> _load_mask): Extend to generate blendm
> instructions.
> (_blendm, _blendm): Change
> define_insn to define_expand.
>
> gcc/testsuite/
> * gcc.target/i386/avx512bw-pr96246-1.c: New test.
> * gcc.target/i386/avx512bw-pr96246-2.c: New test.
> * gcc.target/i386/avx512vl-pr96246-1.c: New test.
> * gcc.target/i386/avx512vl-pr96246-2.c: New test.
> * gcc.target/i386/avx512bw-vmovdqu16-1.c: New test.
> * gcc.target/i386/avx512bw-vmovdqu8-1.c: New test.
> * gcc.target/i386/avx512f-vmovapd-1.c: New test.
> * gcc.target/i386/avx512f-vmovaps-1.c: New test.
> * gcc.target/i386/avx512f-vmovdqa32-1.c: New test.
> * gcc.target/i386/avx512f-vmovdqa64-1.c: New test.
> * gcc.target/i386/avx512vl-pr92686-movcc-1.c: New test.
> * gcc.target/i386/avx512vl-pr96246-1.c: New test.
> * gcc.target/i386/avx512vl-pr96246-2.c: New test.
> * gcc.target/i386/avx512vl-vmovapd-1.c: New test.
> * gcc.target/i386/avx512vl-vmovaps-1.c: New test.
> * gcc.target/i386/avx512vl-vmovdqa32-1.c: New test.
> * gcc.target/i386/avx512vl-vmovdqa64-1.c: New test.
>
>
> --
> BR,
> Hongtao



-- 
BR,
Hongtao


Re: [PATCH] Remove dead vector comparisons

2020-07-27 Thread Martin Liška

On 7/10/20 10:24 AM, Richard Biener wrote:

On Fri, Jul 10, 2020 at 9:50 AM Martin Liška  wrote:


As mentioned in the PR, we need to clean up orphan vector comparisons
that tend to happen be gimplification of VEC_COND_EXPR.

I've done that easily in expand_vector_comparison where I add these
to a bitmap used in simple DCE.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?


I don't like this much - the reason for the dead code is that the gimplifier,
while it manages to DCE the VEC_COND_EXPR because the value is not
needed, does not apply the same for the operands where only side-effects
would need to be kept.

But then if the vector comparisons would not be dead, the testcase
would still ICE even with your patch.


Hello.

Question here is if one can write such a test-case? I would the target
would lower a vector comparison directly to a non-vector code?


 And the reason for the ICE is
that vector lowering checks

   if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)
   && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))
 {

while RTL expansion has

   /* For vector typed comparisons emit code to generate the desired
  all-ones or all-zeros mask.  */
   if (TREE_CODE (ops->type) == VECTOR_TYPE)
 {
   tree ifexp = build2 (ops->code, ops->type, arg0, arg1);
   if (VECTOR_BOOLEAN_TYPE_P (ops->type)
   && expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, ops->code))
 return expand_vec_cmp_expr (ops->type, ifexp, target);
   else
 gcc_unreachable ();

so vector lowering doesn't lower vector comparisons when we can expand
via a VEC_COND_EXPR but the RTL expansion code asserts this will not
be needed.


Ah, ok, now I understand that.



Thus this should either be fixed by re-instantiating the RTL expansion code


Could you please explain what re-instantiating the RTL means?


or handling vector comparisons in gimple-isel.cc at least when they need
to be expanded as VEC_COND_EXPR.


That's doable but by something like:

  _1 = v_5(D) > { 0, 0, 0, 0, 0, 0, 0, 0 };
  _10 = VEC_COND_EXPR <_1, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 1, 1, 1, 1, 1 
}>;

which will be immediately expanded to in ISEL to:

  _10 = .VCOND (v_5(D), { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }, 
{ 1, 1, 1, 1, 1, 1, 1, 1 }, 109);

But I would need to redirect all uses of _1 to _10, right? Do we prefer to do 
this?

Thanks,
Martin



Richard.


Thanks,
Martin

gcc/ChangeLog:

 PR tree-optimization/96128
 * tree-vect-generic.c (expand_vector_comparison): Remove vector
 comparisons that don't have a usage.

gcc/testsuite/ChangeLog:

 PR tree-optimization/96128
 * gcc.target/s390/vector/pr96128.c: New test.
---
   .../gcc.target/s390/vector/pr96128.c  | 35 +++
   gcc/tree-vect-generic.c   |  4 ++-
   2 files changed, 38 insertions(+), 1 deletion(-)
   create mode 100644 gcc/testsuite/gcc.target/s390/vector/pr96128.c

diff --git a/gcc/testsuite/gcc.target/s390/vector/pr96128.c 
b/gcc/testsuite/gcc.target/s390/vector/pr96128.c
new file mode 100644
index 000..20abe5e515c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/vector/pr96128.c
@@ -0,0 +1,35 @@
+/* PR tree-optimization/96128 */
+/* { dg-options "-march=z13" } */
+
+#define B_TEST(TYPE) { TYPE v __attribute__((vector_size(16))); (void)((v < v) 
< v); }
+#ifdef __cplusplus
+#define T_TEST(TYPE) { TYPE s; TYPE v __attribute__((vector_size(16))); 
__typeof((v



Re: [PATCH v3] driver: fix a problem with implementation of -falign-foo=0 [PR96247]

2020-07-27 Thread Martin Liška

On 7/27/20 9:46 AM, Hu Jiangping wrote:

Hi!

This patch makes the -falign-foo=0 work as described in the
documentation. Thanks for all the suggestions, Richard and Segher!


Hello.

I'm the author of the original code.



v3: make change more readable and self-consistent
v2: at a high level handles -falign-foo=0 like -falign-foo

Regards!
Hujp

---
  gcc/opts.c | 24 +++-
  1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/gcc/opts.c b/gcc/opts.c
index 499eb900643..dec5ba6d2be 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2007,10 +2007,20 @@ parse_and_check_align_values (const char *flag,
 location LOC.  */
  
  static void

-check_alignment_argument (location_t loc, const char *flag, const char *name)
+check_alignment_argument (location_t loc,
+const char *flag,
+const char *name,
+int *opt_flag,
+const char **opt_str)
  {
auto_vec align_result;
parse_and_check_align_values (flag, name, align_result, true, loc);
+
+  if (align_result.length() >= 1 && align_result[0] == 0)
+  {
+*opt_flag = 1;
+*opt_str = NULL;
+  }


Hm, shouldn't the code be placed in parse_and_check_align_values? Note that 
there's
one another call gcc/toplev.c (parse_N_M).

I bet you likely want to modify result_values in case -falign-foo=0.
About the -falign-foo=0:m:n2:m3, you can report an error in 
parse_and_check_align_values?

Thanks for working on that?
Btw. what's your use-case that you use the extended syntax of -falign-foo?
Martin


  }
  
  /* Print help when OPT__help_ is set.  */

@@ -2785,19 +2795,23 @@ common_handle_option (struct gcc_options *opts,
break;
  
  case OPT_falign_loops_:

-  check_alignment_argument (loc, arg, "loops");
+  check_alignment_argument (loc, arg, "loops",
+  &opts->x_flag_align_loops, &opts->x_str_align_loops);
break;
  
  case OPT_falign_jumps_:

-  check_alignment_argument (loc, arg, "jumps");
+  check_alignment_argument (loc, arg, "jumps",
+  &opts->x_flag_align_jumps, &opts->x_str_align_jumps);
break;
  
  case OPT_falign_labels_:

-  check_alignment_argument (loc, arg, "labels");
+  check_alignment_argument (loc, arg, "labels",
+  &opts->x_flag_align_labels, &opts->x_str_align_labels);
break;
  
  case OPT_falign_functions_:

-  check_alignment_argument (loc, arg, "functions");
+  check_alignment_argument (loc, arg, "functions",
+  &opts->x_flag_align_functions, &opts->x_str_align_functions);
break;
  
  case OPT_ftabstop_:






Re: [committed] libstdc++: Add std::from_chars for floating-point types

2020-07-27 Thread Rainer Orth
Hi Jonathan,

> This adds the missing std::from_chars overloads for floating-point
> types, as required for C++17 conformance.
>
> The implementation is a hack and not intended to be used in the long
> term. Rather than parsing the string directly, this determines the
> initial portion of the string that matches the pattern determined by the
> chars_format parameter, then creates a NTBS to be parsed by strtod (or
> strtold or strtof).
>
> Because creating a NTBS requires allocating memory, but std::from_chars
> is noexcept, we need to be careful to minimise allocation. Even after
> being careful, allocation failure is still possible, and so a
> non-conforming std::no_more_memory error code might be returned.
>
> Because strtod et al depend on the current locale, but std::from_chars
> does not, we change the current thread's locale to "C" using newlocale
> and uselocale before calling strtod, and restore it afterwards.
>
> Because strtod doesn't have the equivalent of a std::chars_format
> parameter, it has to examine the input to determine the format in use,
> even though the std::from_chars code has already parsed it once (or
> twice for large input strings!)
>
> By replacing the use of strtod we could avoid allocation, avoid changing
> locale, and use optimised code paths specific to each std::chars_format
> case. We would also get more portable behaviour, rather than depending
> on the presence of uselocale, and on any bugs or quirks of the target
> libc's strtod. Replacing strtod is a project for a later date.

two of the new tests FAIL on Solaris 11.3 only:

+FAIL: 20_util/from_chars/4.cc (test for excess errors)
+UNRESOLVED: 20_util/from_chars/4.cc compilation failed to produce executable
+FAIL: 20_util/from_chars/5.cc (test for excess errors)
+UNRESOLVED: 20_util/from_chars/5.cc compilation failed to produce executable

Excess errors:
/vol/gcc/src/hg/master/local/libstdc++-v3/testsuite/20_util/from_chars/4.cc:41: 
error: no matching function for call to 'from_chars(char*, char*, double&, 
std::chars_format&)'
[...]

AFAICT that's due to the fact that Solaris 11.3 (unlike 11.4) lacks
uselocale.

Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


Re: [PATCH] [RFC] vect: Fix infinite loop while determining peeling amount

2020-07-27 Thread Richard Sandiford
Richard Biener  writes:
> On Mon, Jul 27, 2020 at 11:09 AM Richard Sandiford
>  wrote:
>>
>> Richard Biener via Gcc-patches  writes:
>> > On Wed, Jul 22, 2020 at 5:18 PM Stefan Schulze Frielinghaus via
>> > Gcc-patches  wrote:
>> >>
>> >> This is a follow up to commit 5c9669a0e6c respectively discussion
>> >> https://gcc.gnu.org/pipermail/gcc-patches/2020-June/549132.html
>> >>
>> >> In case that an alignment constraint is less than the size of a
>> >> corresponding scalar type, ensure that we advance at least by one
>> >> iteration.  For example, on s390x we have for a long double an alignment
>> >> constraint of 8 bytes whereas the size is 16 bytes.  Therefore,
>> >> TARGET_ALIGN / DR_SIZE equals zero resulting in an infinite loop which
>> >> can be reproduced by the following MWE:
>> >
>> > But we guard this case with vector_alignment_reachable_p, so we shouldn't
>> > have ended up here and the patch looks bogus.
>>
>> The above sounds like it ought to count as reachable alignment though.
>> If a type requires a lower alignment than its size, then that's even
>> more easily reachable than a type that requires the same alignment as
>> the size.  I guess at one extreme, a target alignment of 1 is always
>> reachable.
>
> Well, if the element alignment is 8 but its size is 16 then when presumably
> the desired vector alignment is a multiple of 16 we can never reach it.
> Isn't this the case here?

If the desired vector alignment (TARGET_ALIGN) is a multiple of 16 then
TARGET_ALIGN / DR_SIZE will be nonzero and the problem the patch is
fixing wouldn't occur.  I agree that we might never be able to reach
that alignment if the pointer starts out misaligned by 8 bytes.

But I think that's why it makes sense for the target to only ask
for 8-byte alignment for vectors too, if it can cope with it.  8-byte
alignment should always be achievable if the scalars are ABI-aligned.
And if the target does ask for only 8-byte alignment, TARGET_ALIGN /
DR_SIZE would be zero and the loop would never progress, which is the
problem that the patch is fixing.

It would even make sense for the target to ask for 1-byte alignment,
if the target doesn't care about alignment at all.

Thanks,
Richard


Re: [committed] libstdc++: Add std::from_chars for floating-point types

2020-07-27 Thread Jonathan Wakely via Gcc-patches

On 27/07/20 11:41 +0200, Rainer Orth wrote:

Hi Jonathan,


This adds the missing std::from_chars overloads for floating-point
types, as required for C++17 conformance.

The implementation is a hack and not intended to be used in the long
term. Rather than parsing the string directly, this determines the
initial portion of the string that matches the pattern determined by the
chars_format parameter, then creates a NTBS to be parsed by strtod (or
strtold or strtof).

Because creating a NTBS requires allocating memory, but std::from_chars
is noexcept, we need to be careful to minimise allocation. Even after
being careful, allocation failure is still possible, and so a
non-conforming std::no_more_memory error code might be returned.

Because strtod et al depend on the current locale, but std::from_chars
does not, we change the current thread's locale to "C" using newlocale
and uselocale before calling strtod, and restore it afterwards.

Because strtod doesn't have the equivalent of a std::chars_format
parameter, it has to examine the input to determine the format in use,
even though the std::from_chars code has already parsed it once (or
twice for large input strings!)

By replacing the use of strtod we could avoid allocation, avoid changing
locale, and use optimised code paths specific to each std::chars_format
case. We would also get more portable behaviour, rather than depending
on the presence of uselocale, and on any bugs or quirks of the target
libc's strtod. Replacing strtod is a project for a later date.


two of the new tests FAIL on Solaris 11.3 only:

+FAIL: 20_util/from_chars/4.cc (test for excess errors)
+UNRESOLVED: 20_util/from_chars/4.cc compilation failed to produce executable
+FAIL: 20_util/from_chars/5.cc (test for excess errors)
+UNRESOLVED: 20_util/from_chars/5.cc compilation failed to produce executable

Excess errors:
/vol/gcc/src/hg/master/local/libstdc++-v3/testsuite/20_util/from_chars/4.cc:41: error: 
no matching function for call to 'from_chars(char*, char*, double&, 
std::chars_format&)'
[...]

AFAICT that's due to the fact that Solaris 11.3 (unlike 11.4) lacks
uselocale.


Ah yes, the tests should not run unconditionally. I'll fix that today,
thanks.




Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Jan Hubicka
> On 7/27/20 9:11 AM, Richard Biener wrote:
> > OK.  I guess the previous code tried to use less memory.
> 
> It did. But I didn't realize that such exact growth would lead
> to a massive reallocation for huge apps like chromium.
> 
> I'm going to backport the patch older releases as well.

Thank you!  Did it solved the the Chromium problem?  I guess I can try
to do some profiling since this problem did not show on Firefox (that i
find odd given that Firefox is just about half of the size).
Perhaps glibc has some stupid limit in realloc that makes it to behave
in a silly way for very large arrays?

Honza
> 
> Martin


Re: [PATCH v3] driver: fix a problem with implementation of -falign-foo=0 [PR96247]

2020-07-27 Thread Richard Sandiford
Martin Liška  writes:
> On 7/27/20 9:46 AM, Hu Jiangping wrote:
>> Hi!
>> 
>> This patch makes the -falign-foo=0 work as described in the
>> documentation. Thanks for all the suggestions, Richard and Segher!
>
> Hello.
>
> I'm the author of the original code.
>
>> 
>> v3: make change more readable and self-consistent
>> v2: at a high level handles -falign-foo=0 like -falign-foo
>> 
>> Regards!
>> Hujp
>> 
>> ---
>>   gcc/opts.c | 24 +++-
>>   1 file changed, 19 insertions(+), 5 deletions(-)
>> 
>> diff --git a/gcc/opts.c b/gcc/opts.c
>> index 499eb900643..dec5ba6d2be 100644
>> --- a/gcc/opts.c
>> +++ b/gcc/opts.c
>> @@ -2007,10 +2007,20 @@ parse_and_check_align_values (const char *flag,
>>  location LOC.  */
>>   
>>   static void
>> -check_alignment_argument (location_t loc, const char *flag, const char 
>> *name)
>> +check_alignment_argument (location_t loc,
>> +const char *flag,
>> +const char *name,
>> +int *opt_flag,
>> +const char **opt_str)
>>   {
>> auto_vec align_result;
>> parse_and_check_align_values (flag, name, align_result, true, loc);
>> +
>> +  if (align_result.length() >= 1 && align_result[0] == 0)
>> +  {
>> +*opt_flag = 1;
>> +*opt_str = NULL;
>> +  }
>
> Hm, shouldn't the code be placed in parse_and_check_align_values? Note that 
> there's
> one another call gcc/toplev.c (parse_N_M).

I think that's why check_alignment_argument is the right place.
The idea is that we're making -falign-foo=0 do two things:

- imply -falign-foo
- invalidate any previous -falign-foo=… option

It's therefore something that we should only do while iterating
through the command-line in order.

> I bet you likely want to modify result_values in case -falign-foo=0.
> About the -falign-foo=0:m:n2:m3, you can report an error in 
> parse_and_check_align_values?

The problem is that we don't know in general what the target's default is.
It depends on whether this is aligning for functions, loops, labels, etc.
It also depends on the target core, which we might not know yet, and which
might change during compilation based on attributes and pragmas.

So I don't think there's a different value that parse_and_check_align_values
could sensibly insert instead of zero.

Thanks,
Richard


Re: [PATCH] [RFC] vect: Fix infinite loop while determining peeling amount

2020-07-27 Thread Richard Biener via Gcc-patches
On Mon, Jul 27, 2020 at 11:45 AM Richard Sandiford
 wrote:
>
> Richard Biener  writes:
> > On Mon, Jul 27, 2020 at 11:09 AM Richard Sandiford
> >  wrote:
> >>
> >> Richard Biener via Gcc-patches  writes:
> >> > On Wed, Jul 22, 2020 at 5:18 PM Stefan Schulze Frielinghaus via
> >> > Gcc-patches  wrote:
> >> >>
> >> >> This is a follow up to commit 5c9669a0e6c respectively discussion
> >> >> https://gcc.gnu.org/pipermail/gcc-patches/2020-June/549132.html
> >> >>
> >> >> In case that an alignment constraint is less than the size of a
> >> >> corresponding scalar type, ensure that we advance at least by one
> >> >> iteration.  For example, on s390x we have for a long double an alignment
> >> >> constraint of 8 bytes whereas the size is 16 bytes.  Therefore,
> >> >> TARGET_ALIGN / DR_SIZE equals zero resulting in an infinite loop which
> >> >> can be reproduced by the following MWE:
> >> >
> >> > But we guard this case with vector_alignment_reachable_p, so we shouldn't
> >> > have ended up here and the patch looks bogus.
> >>
> >> The above sounds like it ought to count as reachable alignment though.
> >> If a type requires a lower alignment than its size, then that's even
> >> more easily reachable than a type that requires the same alignment as
> >> the size.  I guess at one extreme, a target alignment of 1 is always
> >> reachable.
> >
> > Well, if the element alignment is 8 but its size is 16 then when presumably
> > the desired vector alignment is a multiple of 16 we can never reach it.
> > Isn't this the case here?
>
> If the desired vector alignment (TARGET_ALIGN) is a multiple of 16 then
> TARGET_ALIGN / DR_SIZE will be nonzero and the problem the patch is
> fixing wouldn't occur.  I agree that we might never be able to reach
> that alignment if the pointer starts out misaligned by 8 bytes.
>
> But I think that's why it makes sense for the target to only ask
> for 8-byte alignment for vectors too, if it can cope with it.  8-byte
> alignment should always be achievable if the scalars are ABI-aligned.
> And if the target does ask for only 8-byte alignment, TARGET_ALIGN /
> DR_SIZE would be zero and the loop would never progress, which is the
> problem that the patch is fixing.
>
> It would even make sense for the target to ask for 1-byte alignment,
> if the target doesn't care about alignment at all.

Hmm, OK.  Guess I still think we should detect this somewhere upward
and avoid this peeling compute at all.  Somehow.

Richard.

> Thanks,
> Richard


Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Martin Liška

On 7/27/20 11:51 AM, Jan Hubicka wrote:

On 7/27/20 9:11 AM, Richard Biener wrote:

OK.  I guess the previous code tried to use less memory.


It did. But I didn't realize that such exact growth would lead
to a massive reallocation for huge apps like chromium.

I'm going to backport the patch older releases as well.


Thank you!  Did it solved the the Chromium problem?


Yes, I verified that.


I guess I can try
to do some profiling since this problem did not show on Firefox (that i
find odd given that Firefox is just about half of the size).


Yep, I'm also surprised about it.


Perhaps glibc has some stupid limit in realloc that makes it to behave
in a silly way for very large arrays?


Dunno :P

Martin



Honza


Martin




RE: [PATCH v3] driver: fix a problem with implementation of -falign-foo=0 [PR96247]

2020-07-27 Thread Hu, Jiangping
> > This patch makes the -falign-foo=0 work as described in the
> > documentation. Thanks for all the suggestions, Richard and Segher!
> 
> Hello.
> 
> I'm the author of the original code.
> 
> >
> > v3: make change more readable and self-consistent
> > v2: at a high level handles -falign-foo=0 like -falign-foo
> >
> > Regards!
> > Hujp
> >
> > ---
> >   gcc/opts.c | 24 +++-
> >   1 file changed, 19 insertions(+), 5 deletions(-)
> >
> > diff --git a/gcc/opts.c b/gcc/opts.c
> > index 499eb900643..dec5ba6d2be 100644
> > --- a/gcc/opts.c
> > +++ b/gcc/opts.c
> > @@ -2007,10 +2007,20 @@ parse_and_check_align_values (const char
> *flag,
> >  location LOC.  */
> >
> >   static void
> > -check_alignment_argument (location_t loc, const char *flag, const char
> *name)
> > +check_alignment_argument (location_t loc,
> > +const char *flag,
> > +const char *name,
> > +int *opt_flag,
> > +const char **opt_str)
> >   {
> > auto_vec align_result;
> > parse_and_check_align_values (flag, name, align_result, true, loc);
> > +
> > +  if (align_result.length() >= 1 && align_result[0] == 0)
> > +  {
> > +*opt_flag = 1;
> > +*opt_str = NULL;
> > +  }
> 
> Hm, shouldn't the code be placed in parse_and_check_align_values? Note that
> there's
> one another call gcc/toplev.c (parse_N_M).
>
> I bet you likely want to modify result_values in case -falign-foo=0.
> About the -falign-foo=0:m:n2:m3, you can report an error in
> parse_and_check_align_values?
> 
Thanks Martin!

Reporting errors may break exist Makefiles and is not as good as handling
-falign-foo=0 like -falign-foo. We have discussed earlier.

And when parse_N_M is called, the values may have been overided by
target code, I think it is inappropriate to report errors at that time.

> Thanks for working on that?
> Btw. what's your use-case that you use the extended syntax of -falign-foo?
> Martin
> 
In fact, I was understanding the cpu tuning structure of gcc, and then
when I read the documentation of -falign-foo, I found this problem.

Thanks,
Hujp

> >   }
> >
> >   /* Print help when OPT__help_ is set.  */
> > @@ -2785,19 +2795,23 @@ common_handle_option (struct gcc_options
> *opts,
> > break;
> >
> >   case OPT_falign_loops_:
> > -  check_alignment_argument (loc, arg, "loops");
> > +  check_alignment_argument (loc, arg, "loops",
> > +  &opts->x_flag_align_loops, &opts->x_str_align_loops);
> > break;
> >
> >   case OPT_falign_jumps_:
> > -  check_alignment_argument (loc, arg, "jumps");
> > +  check_alignment_argument (loc, arg, "jumps",
> > +  &opts->x_flag_align_jumps, &opts->x_str_align_jumps);
> > break;
> >
> >   case OPT_falign_labels_:
> > -  check_alignment_argument (loc, arg, "labels");
> > +  check_alignment_argument (loc, arg, "labels",
> > +  &opts->x_flag_align_labels, &opts->x_str_align_labels);
> > break;
> >
> >   case OPT_falign_functions_:
> > -  check_alignment_argument (loc, arg, "functions");
> > +  check_alignment_argument (loc, arg, "functions",
> > +  &opts->x_flag_align_functions, &opts->x_str_align_functions);
> > break;
> >
> >   case OPT_ftabstop_:
> >
> 
> 





Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Jan Hubicka
> Yes, I verified that.
> 
> > I guess I can try
> > to do some profiling since this problem did not show on Firefox (that i
> > find odd given that Firefox is just about half of the size).
> 
> Yep, I'm also surprised about it.
> 
> > Perhaps glibc has some stupid limit in realloc that makes it to behave
> > in a silly way for very large arrays?
> 
> Dunno :P
Seems like glibc issue. On my debian testing box:

hubicka@lomikamen-jh:~$ cat t.c
#include 
main(int argc, char **argv)
{
  char *a = malloc (1);
  int i,n=atoi(argv[1]);
  for (i=2;i time ./a.out 10

real0m59.808s
user0m58.703s
sys 0m1.080s

GDB stops at:
(gdb) bt
#0  0x77e70bfe in realloc () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x50bf in main ()
on debian while:
(gdb) bt
#0  0x77e7d6d0 in mem2mem_check () from /lib64/libc.so.6
#1  0x77e81c7d in realloc_check () from /lib64/libc.so.6
#2  0x50bf in main ()
on kunlun.

Perhaps someone enabled some cool security harnessing feature without
much of benchmarking :) (but even debian numbers seems like they can be
improved)

Honza
> 
> Martin
> 
> > 
> > Honza
> > > 
> > > Martin
> 


Re: [PATCH v3] driver: fix a problem with implementation of -falign-foo=0 [PR96247]

2020-07-27 Thread Martin Liška

On 7/27/20 12:25 PM, Richard Sandiford wrote:

So I don't think there's a different value that parse_and_check_align_values
could sensibly insert instead of zero.


All right, works for me.

Martin


Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Martin Liška

On 7/27/20 12:48 PM, Jan Hubicka wrote:

Yes, I verified that.


I guess I can try
to do some profiling since this problem did not show on Firefox (that i
find odd given that Firefox is just about half of the size).


Yep, I'm also surprised about it.


Perhaps glibc has some stupid limit in realloc that makes it to behave
in a silly way for very large arrays?


Dunno :P

Seems like glibc issue. On my debian testing box:

hubicka@lomikamen-jh:~$ cat t.c
#include 
main(int argc, char **argv)
{
   char *a = malloc (1);
   int i,n=atoi(argv[1]);
   for (i=2;i time ./a.out 10

real0m59.808s
user0m58.703s
sys 0m1.080s


It runs for me in:

$ time ./a.out 10

real0m10.048s
user0m9.742s
sys 0m0.305s

Note that there may be an interleaving load on the machine.
Perf says:

55.40%  a.outlibc-2.26.so  [.] realloc
36.01%  a.outa.out [.] realloc@plt
 4.98%  a.outlibc-2.26.so  [.] mremap_chunk
 3.60%  a.outa.out [.] main

while on my machine I see:

real0m4.998s
user0m4.947s
sys 0m0.050s

54.49%  a.outlibc-2.31.so  [.] realloc
37.63%  a.outlibc-2.31.so  [.] mremap_chunk
 3.72%  a.outa.out [.] realloc@plt

Martin



GDB stops at:
(gdb) bt
#0  0x77e70bfe in realloc () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x50bf in main ()
on debian while:
(gdb) bt
#0  0x77e7d6d0 in mem2mem_check () from /lib64/libc.so.6
#1  0x77e81c7d in realloc_check () from /lib64/libc.so.6
#2  0x50bf in main ()
on kunlun.

Perhaps someone enabled some cool security harnessing feature without
much of benchmarking :) (but even debian numbers seems like they can be
improved)

Honza


Martin



Honza


Martin






Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Jan Hubicka
> It runs for me in:
> 
> $ time ./a.out 10
> 
> real  0m10.048s
> user  0m9.742s
> sys   0m0.305s

Did you do chroot to the chromium build?
> 
> Note that there may be an interleaving load on the machine.
> Perf says:
> 
> 55.40%  a.outlibc-2.26.so  [.] realloc
> 36.01%  a.outa.out [.] realloc@plt
>  4.98%  a.outlibc-2.26.so  [.] mremap_chunk
>  3.60%  a.outa.out [.] main

How one can do perfing on kunlun?
> 
> while on my machine I see:
> 
> real  0m4.998s
> user  0m4.947s
> sys   0m0.050s
> 
> 54.49%  a.outlibc-2.31.so  [.] realloc
> 37.63%  a.outlibc-2.31.so  [.] mremap_chunk
>  3.72%  a.outa.out [.] realloc@plt

Honza
> 
> Martin
> 
> > 
> > GDB stops at:
> > (gdb) bt
> > #0  0x77e70bfe in realloc () from /lib/x86_64-linux-gnu/libc.so.6
> > #1  0x50bf in main ()
> > on debian while:
> > (gdb) bt
> > #0  0x77e7d6d0 in mem2mem_check () from /lib64/libc.so.6
> > #1  0x77e81c7d in realloc_check () from /lib64/libc.so.6
> > #2  0x50bf in main ()
> > on kunlun.
> > 
> > Perhaps someone enabled some cool security harnessing feature without
> > much of benchmarking :) (but even debian numbers seems like they can be
> > improved)
> > 
> > Honza
> > > 
> > > Martin
> > > 
> > > > 
> > > > Honza
> > > > > 
> > > > > Martin
> > > 
> 


Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Richard Biener via Gcc-patches
On Mon, Jul 27, 2020 at 12:48 PM Jan Hubicka  wrote:
>
> > Yes, I verified that.
> >
> > > I guess I can try
> > > to do some profiling since this problem did not show on Firefox (that i
> > > find odd given that Firefox is just about half of the size).
> >
> > Yep, I'm also surprised about it.
> >
> > > Perhaps glibc has some stupid limit in realloc that makes it to behave
> > > in a silly way for very large arrays?
> >
> > Dunno :P
> Seems like glibc issue. On my debian testing box:

I'm sure in your actual testcase you run into fragmentation and
eventually fall out of cache which should make things worse by
an order of magnitude.

> hubicka@lomikamen-jh:~$ cat t.c
> #include 
> main(int argc, char **argv)
> {
>   char *a = malloc (1);
>   int i,n=atoi(argv[1]);
>   for (i=2;i a = realloc (a,i);
> }
>
> hubicka@lomikamen-jh:~$ time ./a.out 10
>
> real0m10.057s
> user0m9.696s
> sys 0m0.356s
>
> And kunlun (which is a lot faster than my 2013 buldozer):
>
>
> abuild@kunlun:~> time ./a.out 10
>
> real0m59.808s
> user0m58.703s
> sys 0m1.080s
>
> GDB stops at:
> (gdb) bt
> #0  0x77e70bfe in realloc () from /lib/x86_64-linux-gnu/libc.so.6
> #1  0x50bf in main ()
> on debian while:
> (gdb) bt
> #0  0x77e7d6d0 in mem2mem_check () from /lib64/libc.so.6
> #1  0x77e81c7d in realloc_check () from /lib64/libc.so.6
> #2  0x50bf in main ()
> on kunlun.
>
> Perhaps someone enabled some cool security harnessing feature without
> much of benchmarking :) (but even debian numbers seems like they can be
> improved)
>
> Honza
> >
> > Martin
> >
> > >
> > > Honza
> > > >
> > > > Martin
> >


Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Jan Hubicka
> On 7/27/20 9:11 AM, Richard Biener wrote:
> > OK.  I guess the previous code tried to use less memory.
> 
> It did. But I didn't realize that such exact growth would lead
> to a massive reallocation for huge apps like chromium.

I would consider it an API issue - it is not really at all that obvious
when vec API does auto reserve and when it does not. 

Grepping for vec_safe_grow, rtl_create_basic_block, gimple_set_bb,
extend_h_i_d, stack_regs_mentioned, init_deps_data_vector
extend_insn_data, create_bb, move_block_to_fn logic has similar logic
but implemented by hand.  Perhaps we can switch it to the new API.  

combine_split_insns, combine_instructions, update_row_reg_save,
grow_label_align, update_uses, final_warning_record::grow_type_warnings,
sem_function::bb_dict_test, ::add_single_to_queue,
symtab_node::create_reference, mark_phi_for_rewrite, addr_for_mem_ref,
multiplier_allowed_in_address_p, get_address_cost_ainc,
make_ssa_name_fn, add_to_value, phi_translate_1,
optimize_range_tests_cmp_bitwise, set_strinfo,
ssa_name_values.safe_grow_cleared, vect_record_loop_mask has similarly
suspicious logic in it.  

Honza
> 
> I'm going to backport the patch older releases as well.
> 
> Martin


Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Martin Liška

On 7/27/20 1:03 PM, Jan Hubicka wrote:

Did you do chroot to the chromium build?


Oh, you are right!

It really takes move than 60 seconds with:

35.43%  a.outlibc-2.31.so  [.] mem2chunk_check
26.54%  a.outlibc-2.31.so  [.] mem2mem_check
21.50%  a.outlibc-2.31.so  [.] realloc_check
 8.38%  a.outlibc-2.31.so  [.] mremap_chunk
 5.03%  a.outlibc-2.31.so  [.] realloc
 1.87%  a.outa.out [.] main

So there's really a hardening enabled in openSUSE:Factory chroot.
@Andreas: Is it a known issue?


Note that there may be an interleaving load on the machine.
Perf says:

 55.40%  a.outlibc-2.26.so  [.] realloc
 36.01%  a.outa.out [.] realloc@plt
  4.98%  a.outlibc-2.26.so  [.] mremap_chunk
  3.60%  a.outa.out [.] main

How one can do perfing on kunlun?


You can install perf with:
osc build -x perf -x kernel-default

and then you can run it in a chroot env.

Martin




Re: [PATCH] Remove dead vector comparisons

2020-07-27 Thread Richard Biener via Gcc-patches
On Mon, Jul 27, 2020 at 11:32 AM Martin Liška  wrote:
>
> On 7/10/20 10:24 AM, Richard Biener wrote:
> > On Fri, Jul 10, 2020 at 9:50 AM Martin Liška  wrote:
> >>
> >> As mentioned in the PR, we need to clean up orphan vector comparisons
> >> that tend to happen be gimplification of VEC_COND_EXPR.
> >>
> >> I've done that easily in expand_vector_comparison where I add these
> >> to a bitmap used in simple DCE.
> >>
> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
> >>
> >> Ready to be installed?
> >
> > I don't like this much - the reason for the dead code is that the 
> > gimplifier,
> > while it manages to DCE the VEC_COND_EXPR because the value is not
> > needed, does not apply the same for the operands where only side-effects
> > would need to be kept.
> >
> > But then if the vector comparisons would not be dead, the testcase
> > would still ICE even with your patch.
>
> Hello.
>
> Question here is if one can write such a test-case? I would the target
> would lower a vector comparison directly to a non-vector code?

Possibly you can't (looks like you need boolean vectors for this).  The
GIMPLE FE also does not support this yet (because it relies on the C
frontends type capabilities).

> >  And the reason for the ICE is
> > that vector lowering checks
> >
> >if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)
> >&& !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))
> >  {
> >
> > while RTL expansion has
> >
> >/* For vector typed comparisons emit code to generate the desired
> >   all-ones or all-zeros mask.  */
> >if (TREE_CODE (ops->type) == VECTOR_TYPE)
> >  {
> >tree ifexp = build2 (ops->code, ops->type, arg0, arg1);
> >if (VECTOR_BOOLEAN_TYPE_P (ops->type)
> >&& expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, 
> > ops->code))
> >  return expand_vec_cmp_expr (ops->type, ifexp, target);
> >else
> >  gcc_unreachable ();
> >
> > so vector lowering doesn't lower vector comparisons when we can expand
> > via a VEC_COND_EXPR but the RTL expansion code asserts this will not
> > be needed.
>
> Ah, ok, now I understand that.
>
> >
> > Thus this should either be fixed by re-instantiating the RTL expansion code
>
> Could you please explain what re-instantiating the RTL means?

Put the code back that predates the gcc_unreachable ().

> > or handling vector comparisons in gimple-isel.cc at least when they need
> > to be expanded as VEC_COND_EXPR.
>
> That's doable but by something like:
>
>_1 = v_5(D) > { 0, 0, 0, 0, 0, 0, 0, 0 };
>_10 = VEC_COND_EXPR <_1, { 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 1, 1, 1, 
> 1, 1 }>;
>
> which will be immediately expanded to in ISEL to:
>
>_10 = .VCOND (v_5(D), { 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 
> }, { 1, 1, 1, 1, 1, 1, 1, 1 }, 109);
>
> But I would need to redirect all uses of _1 to _10, right? Do we prefer to do 
> this?

not sure - it might be that _1 is always unused at least in the for it
appears in the testcase
(with the boolean vector).  Note that the boolean vector case is not
representable by
the .VCOND because of the different result type.  So the separate
comparison looks
like an artifact of the split from the VEC_COND_EXPR after all ...

The gimplifier has

static bool
verify_gimple_comparison (tree type, tree op0, tree op1, enum tree_code code)
{
...
  /* Or a boolean vector type with the same element count
 as the comparison operand types.  */
  else if (TREE_CODE (type) == VECTOR_TYPE
   && TREE_CODE (TREE_TYPE (type)) == BOOLEAN_TYPE)
{

so it requires a BOOLEAN_TYPE vector.

I wonder what happens if we make vector lowering not allow the compare
expanded via expand_vec_cond_expr_p?

Richard.

> Thanks,
> Martin
>
> >
> > Richard.
> >
> >> Thanks,
> >> Martin
> >>
> >> gcc/ChangeLog:
> >>
> >>  PR tree-optimization/96128
> >>  * tree-vect-generic.c (expand_vector_comparison): Remove vector
> >>  comparisons that don't have a usage.
> >>
> >> gcc/testsuite/ChangeLog:
> >>
> >>  PR tree-optimization/96128
> >>  * gcc.target/s390/vector/pr96128.c: New test.
> >> ---
> >>.../gcc.target/s390/vector/pr96128.c  | 35 +++
> >>gcc/tree-vect-generic.c   |  4 ++-
> >>2 files changed, 38 insertions(+), 1 deletion(-)
> >>create mode 100644 gcc/testsuite/gcc.target/s390/vector/pr96128.c
> >>
> >> diff --git a/gcc/testsuite/gcc.target/s390/vector/pr96128.c 
> >> b/gcc/testsuite/gcc.target/s390/vector/pr96128.c
> >> new file mode 100644
> >> index 000..20abe5e515c
> >> --- /dev/null
> >> +++ b/gcc/testsuite/gcc.target/s390/vector/pr96128.c
> >> @@ -0,0 +1,35 @@
> >> +/* PR tree-optimization/96128 */
> >> +/* { dg-options "-march=z13" } */
> >> +
> >> +#define B_TEST(TYPE) { TYPE v __attribute__((vector_size(16))); (void)((v 
> >> < v) < v); }
> >> +#ifdef __cplusplus
> >> +#define T_TEST(TYPE) { TYPE s; TYPE 

Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Martin Liška

On 7/27/20 1:11 PM, Jan Hubicka wrote:

On 7/27/20 9:11 AM, Richard Biener wrote:

OK.  I guess the previous code tried to use less memory.


It did. But I didn't realize that such exact growth would lead
to a massive reallocation for huge apps like chromium.


I would consider it an API issue - it is not really at all that obvious
when vec API does auto reserve and when it does not.


Fully agree here, it's super-confusing.



Grepping for vec_safe_grow, rtl_create_basic_block, gimple_set_bb,
extend_h_i_d, stack_regs_mentioned, init_deps_data_vector
extend_insn_data, create_bb, move_block_to_fn logic has similar logic
but implemented by hand.  Perhaps we can switch it to the new API.

combine_split_insns, combine_instructions, update_row_reg_save,
grow_label_align, update_uses, final_warning_record::grow_type_warnings,
sem_function::bb_dict_test, ::add_single_to_queue,
symtab_node::create_reference, mark_phi_for_rewrite, addr_for_mem_ref,
multiplier_allowed_in_address_p, get_address_cost_ainc,
make_ssa_name_fn, add_to_value, phi_translate_1,
optimize_range_tests_cmp_bitwise, set_strinfo,
ssa_name_values.safe_grow_cleared, vect_record_loop_mask has similarly
suspicious logic in it.


Are you talking about changing all '*gros*' calls to use exact=false, right?
I can experiment with that.

Martin



Honza


I'm going to backport the patch older releases as well.

Martin




Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Richard Biener via Gcc-patches
On Mon, Jul 27, 2020 at 1:24 PM Martin Liška  wrote:
>
> On 7/27/20 1:11 PM, Jan Hubicka wrote:
> >> On 7/27/20 9:11 AM, Richard Biener wrote:
> >>> OK.  I guess the previous code tried to use less memory.
> >>
> >> It did. But I didn't realize that such exact growth would lead
> >> to a massive reallocation for huge apps like chromium.
> >
> > I would consider it an API issue - it is not really at all that obvious
> > when vec API does auto reserve and when it does not.
>
> Fully agree here, it's super-confusing.
>
> >
> > Grepping for vec_safe_grow, rtl_create_basic_block, gimple_set_bb,
> > extend_h_i_d, stack_regs_mentioned, init_deps_data_vector
> > extend_insn_data, create_bb, move_block_to_fn logic has similar logic
> > but implemented by hand.  Perhaps we can switch it to the new API.
> >
> > combine_split_insns, combine_instructions, update_row_reg_save,
> > grow_label_align, update_uses, final_warning_record::grow_type_warnings,
> > sem_function::bb_dict_test, ::add_single_to_queue,
> > symtab_node::create_reference, mark_phi_for_rewrite, addr_for_mem_ref,
> > multiplier_allowed_in_address_p, get_address_cost_ainc,
> > make_ssa_name_fn, add_to_value, phi_translate_1,
> > optimize_range_tests_cmp_bitwise, set_strinfo,
> > ssa_name_values.safe_grow_cleared, vect_record_loop_mask has similarly
> > suspicious logic in it.
>
> Are you talking about changing all '*gros*' calls to use exact=false, right?
> I can experiment with that.

No, add gro*_exact variants and replace existing ones with this, then switch
to exact = false for the non-_exact variants.  Or add a exact=false argument
to all of them and make all existing calls explicitly passing true.

Only later, on a case by case basis, swap one for the other when obvious.

Richard.

> Martin
>
> >
> > Honza
> >>
> >> I'm going to backport the patch older releases as well.
> >>
> >> Martin
>


[PATCH v4] driver: fix a problem with implementation of -falign-foo=0 [PR96247]

2020-07-27 Thread Hu Jiangping
Hi!

This patch makes the -falign-foo=0 work as described in the
documentation. Thanks for all the suggestions.

v4: do changes for coding conventions
v3: make change more readable and self-consistent

Changelog:
2020-07-27  Hu Jiangping  

PR driver/96247
* opts.c (check_alignment_argument): Set the -falign-Name
on/off flag on and set the -falign-Name string value null,
when the command-line specified argument is zero.

Tested on x86_64.

Regards!
Hujp

---
 gcc/opts.c | 28 ++--
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/gcc/opts.c b/gcc/opts.c
index 499eb900643..574b28416fb 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -2004,13 +2004,21 @@ parse_and_check_align_values (const char *flag,
 }
 
 /* Check that alignment value FLAG for -falign-NAME is valid at a given
-   location LOC.  */
+   location LOC. OPT_STR points to the stored -falign-NAME=argument and
+   OPT_FLAG points to the associated -falign-NAME on/off flag.  */
 
 static void
-check_alignment_argument (location_t loc, const char *flag, const char *name)
+check_alignment_argument (location_t loc, const char *flag, const char *name,
+int *opt_flag, const char **opt_str)
 {
   auto_vec align_result;
   parse_and_check_align_values (flag, name, align_result, true, loc);
+
+  if (align_result.length() >= 1 && align_result[0] == 0)
+{
+  *opt_flag = 1;
+  *opt_str = NULL;
+}
 }
 
 /* Print help when OPT__help_ is set.  */
@@ -2785,19 +2793,27 @@ common_handle_option (struct gcc_options *opts,
   break;
 
 case OPT_falign_loops_:
-  check_alignment_argument (loc, arg, "loops");
+  check_alignment_argument (loc, arg, "loops",
+&opts->x_flag_align_loops,
+&opts->x_str_align_loops);
   break;
 
 case OPT_falign_jumps_:
-  check_alignment_argument (loc, arg, "jumps");
+  check_alignment_argument (loc, arg, "jumps",
+&opts->x_flag_align_jumps,
+&opts->x_str_align_jumps);
   break;
 
 case OPT_falign_labels_:
-  check_alignment_argument (loc, arg, "labels");
+  check_alignment_argument (loc, arg, "labels",
+&opts->x_flag_align_labels,
+&opts->x_str_align_labels);
   break;
 
 case OPT_falign_functions_:
-  check_alignment_argument (loc, arg, "functions");
+  check_alignment_argument (loc, arg, "functions",
+&opts->x_flag_align_functions,
+&opts->x_str_align_functions);
   break;
 
 case OPT_ftabstop_:
-- 
2.17.1





[PATCH] expr: build string_constant only for a char type

2020-07-27 Thread Martin Liška

Hey.

As mentioned in the PR, we should not create a string constant for a type
that is different from char_type_node. Looking at expr.c, I was inspired
and used 'TYPE_MAIN_VARIANT (chartype) == char_type_node' to verify that 
underlying
type is a character type.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests. And it 
fixes chromium
build with gcc-10 branch with the patch applied.

Ready to be installed?
Thanks,
Martin

gcc/ChangeLog:

PR tree-optimization/96058
* expr.c (string_constant): Build string_constant only
for a type that is main variant of char_type_node.
---
 gcc/expr.c | 22 +-
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/gcc/expr.c b/gcc/expr.c
index 5db0a7a8565..c3fdd82b319 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11828,17 +11828,21 @@ string_constant (tree arg, tree *ptr_offset, tree 
*mem_size, tree *decl)
chartype = TREE_TYPE (chartype);
   while (TREE_CODE (chartype) == ARRAY_TYPE)
chartype = TREE_TYPE (chartype);
-  /* Convert a char array to an empty STRING_CST having an array
-of the expected type and size.  */
-  if (!initsize)
- initsize = integer_zero_node;
 
-  unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize);

-  init = build_string_literal (size, NULL, chartype, size);
-  init = TREE_OPERAND (init, 0);
-  init = TREE_OPERAND (init, 0);
+  if (TYPE_MAIN_VARIANT (chartype) == char_type_node)
+   {
+ /* Convert a char array to an empty STRING_CST having an array
+of the expected type and size.  */
+ if (!initsize)
+   initsize = integer_zero_node;
+
+ unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize);
+ init = build_string_literal (size, NULL, chartype, size);
+ init = TREE_OPERAND (init, 0);
+ init = TREE_OPERAND (init, 0);
 
-  *ptr_offset = integer_zero_node;

+ *ptr_offset = integer_zero_node;
+   }
 }
 
   if (decl)

--
2.27.0



Re: [PATCH] ipa/96291: don't crash on unoptimized lto functions

2020-07-27 Thread Martin Jambor
Hi,

On Sat, Jul 25 2020, Sergei Trofimovich wrote:
> From: Sergei Trofimovich 
>
> In PR ipa/96291 the test contained an SCC with one
> unoptimized function. This tricked ipa-cp into NULL dereference.
>
> has_undead_caller_from_outside_scc_p() did not take into account
> that unoptimized funtions don't have IPA summary analysis. and
> dereferenced NULL pointer causing an ICE.
>
>   PR ipa/96291
>   * ipa-cp.c (has_undead_caller_from_outside_scc_p): Consider
>   unoptimized callers as undead.
> ---
>  gcc/ipa-cp.c | 12 +---
>  1 file changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
> index b0c8f405260..d5082576962 100644
> --- a/gcc/ipa-cp.c
> +++ b/gcc/ipa-cp.c
> @@ -5666,9 +5666,15 @@ has_undead_caller_from_outside_scc_p (struct 
> cgraph_node *node,
>   && cs->caller->call_for_symbol_thunks_and_aliases
> (has_undead_caller_from_outside_scc_p, NULL, true))
>return true;
> -else if (!ipa_edge_within_scc (cs)
> -  && !IPA_NODE_REF (cs->caller)->node_dead)
> -  return true;
> +else if (!ipa_edge_within_scc (cs))
> +  {
> + /* Unoptimized callers don't have IPA information.
> +Conservatively assume callers are undead.  */
> + if (!IPA_NODE_REF (cs->caller))
> +   return true;
> + if (!IPA_NODE_REF (cs->caller)->node_dead)
> +   return true;

I'd prefer a single condition, i.e.:

else if (!ipa_edge_within_scc (cs)
 && (!IPA_NODE_REF (cs->caller)
 || !IPA_NODE_REF (cs->caller)->node_dead))
  return true;


so OK with that change.

Thanks a lot for looking into this.

Martin


Re: [PATCH] ipa/96291: don't crash on unoptimized lto functions

2020-07-27 Thread Martin Jambor
Hi,

On Mon, Jul 27 2020, Richard Biener via Gcc-patches wrote:
> On Sat, Jul 25, 2020 at 8:35 PM Sergei Trofimovich via Gcc-patches
>  wrote:
>>
>> From: Sergei Trofimovich 
>>
>> In PR ipa/96291 the test contained an SCC with one
>> unoptimized function. This tricked ipa-cp into NULL dereference.
>>
>> has_undead_caller_from_outside_scc_p() did not take into account
>> that unoptimized funtions don't have IPA summary analysis. and
>> dereferenced NULL pointer causing an ICE.
>
> Can you create a single-unit testcase with a SCC with one function
> having the no_ipa attribute?

This bug is LTO specific because otherwise a summary (although marked as
quite useless) will be left over from the summary building stage.

So Sergei, if you can afford to spend an extra while providing a
testcase, you'll need to add three files into gcc/testsuite/gcc.dg/lto,
with either the second or third (numbered _1 or _2)) having

/* { dg-lto-options { { -flto -O0 } } } */

in them.

Thanks,

Martin



>
>> PR ipa/96291
>> * ipa-cp.c (has_undead_caller_from_outside_scc_p): Consider
>> unoptimized callers as undead.
>> ---
>>  gcc/ipa-cp.c | 12 +---
>>  1 file changed, 9 insertions(+), 3 deletions(-)
>>
>> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
>> index b0c8f405260..d5082576962 100644
>> --- a/gcc/ipa-cp.c
>> +++ b/gcc/ipa-cp.c
>> @@ -5666,9 +5666,15 @@ has_undead_caller_from_outside_scc_p (struct 
>> cgraph_node *node,
>> && cs->caller->call_for_symbol_thunks_and_aliases
>>   (has_undead_caller_from_outside_scc_p, NULL, true))
>>return true;
>> -else if (!ipa_edge_within_scc (cs)
>> -&& !IPA_NODE_REF (cs->caller)->node_dead)
>> -  return true;
>> +else if (!ipa_edge_within_scc (cs))
>> +  {
>> +   /* Unoptimized callers don't have IPA information.
>> +  Conservatively assume callers are undead.  */
>> +   if (!IPA_NODE_REF (cs->caller))
>> + return true;
>> +   if (!IPA_NODE_REF (cs->caller)->node_dead)
>> + return true;
>> +  }
>>return false;
>>  }
>>
>> --
>> 2.27.0
>>


Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Andreas Schwab
On Jul 27 2020, Martin Liška wrote:

> @Andreas: Is it a known issue?

Which issue?

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."


Re: [PATCH] Remove dead vector comparisons

2020-07-27 Thread Martin Liška

On 7/27/20 1:22 PM, Richard Biener wrote:

I wonder what happens if we make vector lowering not allow the compare
expanded via expand_vec_cond_expr_p?


So the following patch survives bootstrap and tests on x86_64-linux-gnu:

diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index f8bd26f2156..fe6477c8592 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -419,8 +419,7 @@ expand_vector_comparison (gimple_stmt_iterator *gsi, tree 
type, tree op0,
 return NULL_TREE;
 
   tree t;

-  if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)
-  && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))
+  if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code))
 {
   if (VECTOR_BOOLEAN_TYPE_P (type)
  && SCALAR_INT_MODE_P (TYPE_MODE (type))

and provides a reasonable BIT_FIELD_REF expansion on the problematic s390x 
test-case.
Is it a way to go?

Martin


Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Richard Biener via Gcc-patches
On Mon, Jul 27, 2020 at 2:50 PM Andreas Schwab  wrote:
>
> On Jul 27 2020, Martin Liška wrote:
>
> > @Andreas: Is it a known issue?
>
> Which issue?

I guess Martin means the checking glibc done looks excessive
(for the specific case of realloc). But yes, it's enabled in the build roots
so we just get what we ask for.

Richard.

> Andreas.
>
> --
> Andreas Schwab, sch...@linux-m68k.org
> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> "And now for something completely different."


Re: [PATCH] Remove dead vector comparisons

2020-07-27 Thread Richard Biener via Gcc-patches
On Mon, Jul 27, 2020 at 2:50 PM Martin Liška  wrote:
>
> On 7/27/20 1:22 PM, Richard Biener wrote:
> > I wonder what happens if we make vector lowering not allow the compare
> > expanded via expand_vec_cond_expr_p?
>
> So the following patch survives bootstrap and tests on x86_64-linux-gnu:
>
> diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
> index f8bd26f2156..fe6477c8592 100644
> --- a/gcc/tree-vect-generic.c
> +++ b/gcc/tree-vect-generic.c
> @@ -419,8 +419,7 @@ expand_vector_comparison (gimple_stmt_iterator *gsi, tree 
> type, tree op0,
>   return NULL_TREE;
>
> tree t;
> -  if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)
> -  && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))
> +  if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code))
>   {
> if (VECTOR_BOOLEAN_TYPE_P (type)
>&& SCALAR_INT_MODE_P (TYPE_MODE (type))
>
> and provides a reasonable BIT_FIELD_REF expansion on the problematic s390x 
> test-case.
> Is it a way to go?

If it avoids to do this expansion if the compare feeds supported
VEC_COND_EXPRs then
I think yes.

Richard.

>
> Martin


Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Martin Liška

On 7/27/20 2:51 PM, Richard Biener wrote:

On Mon, Jul 27, 2020 at 2:50 PM Andreas Schwab  wrote:


On Jul 27 2020, Martin Liška wrote:


@Andreas: Is it a known issue?


Which issue?


I guess Martin means the checking glibc done looks excessive
(for the specific case of realloc). But yes, it's enabled in the build roots
so we just get what we ask for.


Yes. I'm basically curious who is this enabled/disabled for glibc.
I speak e.g. about:

#0  0x77e886f0 in mem2chunk_check () from /lib64/libc.so.6
#1  0x77e8cb8a in realloc_check () from /lib64/libc.so.6
#2  0x50bf in main (argc=, argv=) at 
bench.c:7

Martin



Richard.


Andreas.

--
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."




Re: [PATCH] Use vec::reserve before vec_safe_grow_cleared is called

2020-07-27 Thread Richard Biener via Gcc-patches
On Mon, Jul 27, 2020 at 2:54 PM Martin Liška  wrote:
>
> On 7/27/20 2:51 PM, Richard Biener wrote:
> > On Mon, Jul 27, 2020 at 2:50 PM Andreas Schwab  
> > wrote:
> >>
> >> On Jul 27 2020, Martin Liška wrote:
> >>
> >>> @Andreas: Is it a known issue?
> >>
> >> Which issue?
> >
> > I guess Martin means the checking glibc done looks excessive
> > (for the specific case of realloc). But yes, it's enabled in the build roots
> > so we just get what we ask for.
>
> Yes. I'm basically curious who is this enabled/disabled for glibc.
> I speak e.g. about:
>
> #0  0x77e886f0 in mem2chunk_check () from /lib64/libc.so.6
> #1  0x77e8cb8a in realloc_check () from /lib64/libc.so.6
> #2  0x50bf in main (argc=, argv=) 
> at bench.c:7

It's /etc/profile.d/malloc-debug.sh

> Martin
>
> >
> > Richard.
> >
> >> Andreas.
> >>
> >> --
> >> Andreas Schwab, sch...@linux-m68k.org
> >> GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
> >> "And now for something completely different."
>


RE: [PATCH PR96053] Add "#pragma GCC no_reduc_chain"

2020-07-27 Thread zhoukaipeng (A)
Sorry for the late reply!

-Original Message-
From: Richard Biener [mailto:rguent...@suse.de]
Sent: Wednesday, July 22, 2020 3:02 PM

> First of all I think giving users more control over vectorization is 
> good.  Now as for "#pragma GCC no_reduc_chain" I'd like to avoid 
> negatives and terms internal to GCC.  I also would like to see 
> vectorization pragmas to be grouped somehow, also to avoid bit 
> explosion in struct loop.  There's already annot_expr_no_vector_kind 
> and annot_expr_vector_kind both only used by the fortran FE at the 
> moment.  Note ANNOATE_EXPR already allows an extra argument thus only 
> annot_expr_vector_kind should prevail with its argument specifying a 
> bitmask of vectorizer hints.  We'd have an extra enum for those like
> 
> enum annot_vector_subkind {
>   annot_vector_never = 0,
>   annot_vector_auto = 1, // this is the default
>   annot_vector_always = 3,
>   your new flag
> };
> 
> and the user would specify it via
> 
> #pragma GCC vect [(never|always|auto)] [your new flag]

I'll add the code to complete the above modifications.
 
> now, I honestly have a difficulty in suggesting a better name than 
> no_reduc_chain.  Quoting the testcase:
> 
> +double f(double *a, double *b)
> +{
> +  double res1 = 0;
> +  double res0 = 0;
> +#pragma GCC no_reduc_chain
> +  for (int i = 0 ; i < 1000; i+=4) {
> +res0 += a[i] * b[i];
> +res1 += a[i+1] * b[i*1];
> +res0 += a[i+2] * b[i+2];
> +res1 += a[i+3] * b[i+3];
> +  }
> +  return res0 + res1;
> +}
> 
> for your case with IIRC V2DF vectors using reduction chains will 
> result in a vectorization factor of two while with a SLP reduction the 
> vectorization factor is one.

I reconfirmed the situation.  Using reduction chains also result in a 
vectorization factor of one as the same as using reductions.
Related logs are followed:

1.using reduction chains
pr96053.c:6:3: note:   Final SLP tree for instance:
pr96053.c:6:3: note:   node 0x1a4f4ba0 (max_nunits=2, refcnt=2)
pr96053.c:6:3: note:stmt 0 res1_37 = _14 + res1_48;
pr96053.c:6:3: note:stmt 1 res1_39 = _28 + res1_37;
...
pr96053.c:6:3: note:   === vect_make_slp_decision ===
pr96053.c:6:3: note:   Decided to SLP 2 instances. Unrolling factor 1
pr96053.c:6:3: note:   === vect_detect_hybrid_slp ===
pr96053.c:6:3: note:   === vect_update_vf_for_slp ===
pr96053.c:6:3: note:   Loop contains only SLP stmts
pr96053.c:6:3: note:   Updating vectorization factor to 1.
pr96053.c:6:3: note:  vectorization_factor = 1, niters = 250

2.using reductions
pr96053.c:6:3: note:   Final SLP tree for instance:
pr96053.c:6:3: note:   node 0x3a7f2cb0 (max_nunits=2, refcnt=2)
pr96053.c:6:3: note:stmt 0 res0_38 = _21 + res0_36;
pr96053.c:6:3: note:stmt 1 res1_39 = _28 + res1_37;
...
pr96053.c:6:3: note:   === vect_make_slp_decision ===
pr96053.c:6:3: note:   Decided to SLP 1 instances. Unrolling factor 1
pr96053.c:6:3: note:   === vect_detect_hybrid_slp ===
pr96053.c:6:3: note:   === vect_update_vf_for_slp ===
pr96053.c:6:3: note:   Loop contains only SLP stmts
pr96053.c:6:3: note:   Updating vectorization factor to 1.
pr96053.c:6:3: note:  vectorization_factor = 1, niters = 250

> So maybe it is better to give the user control over the vectorization factor?
> That's desirable in other cases where the user wants to force a larger 
> VF to get extra unrolling for example.  For the testcase above you'd 
> use
> 
> #pragma GCC vect vf(1)
> 
> or so (syntax to be discussed).  The side-effect would be that with a 
> reduction chain the VF request cannot be fulfilled but with a SLP 
> reduction it can.  Of course no_reduc_chain is much easier to actually 
> implement in a strict way while specifying VF will likely need to be 
> documented as a hint (with an eventual diagnostic if it wasn't 
> fulfilled)
> 
> Richard/Jakub, any thoughts?
> 
> Thanks,
> Richard.

Thanks,
Kaipeng Zhou


Re: Refactor peel_iters_{pro,epi}logue cost model handlings

2020-07-27 Thread Richard Sandiford
"Kewen.Lin"  writes:
> Hi,
>
> As Richard S. suggested in the thread:
>
> https://gcc.gnu.org/pipermail/gcc-patches/2020-July/550633.html
>
> this patch is separated from the one of that thread, mainly to refactor the
> existing peel_iters_{pro,epi}logue cost model handlings.
>
> I've addressed Richard S.'s review comments there, moreover because of one
> failure of aarch64 testing, I updated it a bit more to keep the logic 
> unchanged
> as before first (refactor_cost.diff).

Heh, nice when a clean-up exposes an existing bug. ;-)  I agree the
updates look correct.  E.g. if vf is 1, we should assume that there
are no peeled iterations even if the number of iterations is unknown.

Both patches are OK with some very minor nits (sorry):

> gcc/ChangeLog:
>
>   * tree-vect-loop.c (vect_get_known_peeling_cost): Factor out some code
>   to determine peel_iters_epilogue to function ...
>   (vect_get_peel_iters_epilogue): ... this.  New function.

to determine peel_iters_epilogue to...
(vect_get_peel_iters_epilogue): ...this new function.

> +  if (dump_enabled_p ())
> + dump_printf (MSG_NOTE, "cost model: "
> +"prologue peel iters set to vf/2.\n");

Agree this looks nice, but the old formatting was correct: the string
should be indented under “MSG_NOTE, ”.  Same for the epilogue.

> +  /* If peeled iterations are unknown, count a taken branch and a not 
> taken
> +  branch per peeled loop. Even if scalar loop iterations are known,
> +  vector iterations are not known since peeled prologue iterations are
> +  not known. Hence guards remain the same.  */

Should be two spaces rather than one space before “Hence”.

Thanks for doing this.

Richard


Re: [PATCH] expr: build string_constant only for a char type

2020-07-27 Thread Jakub Jelinek via Gcc-patches
On Mon, Jul 27, 2020 at 02:32:15PM +0200, Martin Liška wrote:
> As mentioned in the PR, we should not create a string constant for a type
> that is different from char_type_node. Looking at expr.c, I was inspired
> and used 'TYPE_MAIN_VARIANT (chartype) == char_type_node' to verify that 
> underlying
> type is a character type.

That doesn't look correct, there is char, signed char, unsigned char,
or say std::byte, and all of them are perfectly fine.
So, rather than requiring it is char and nothing else, you should instead
check that it is an INTEGRAL_TYPE_P (maybe better other than BOOLEAN_TYPE?),
which is complete and has the same TYPE_PRECISION as char_type_node.

Jakub



Re: [PATCH v4] vect/rs6000: Support vector with length cost modeling

2020-07-27 Thread Richard Sandiford
"Kewen.Lin"  writes:
> Hi Richard,
>
> Thanks for the review again!
>
> on 2020/7/25 上午12:21, Richard Sandiford wrote:
>> "Kewen.Lin"  writes:
>> 
>> Thanks, the rearrangement of the existing code looks good.  Could you
>> split that and the new LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo) stuff
>> out into separate patches?
>> 
>
> Splitted to https://gcc.gnu.org/pipermail/gcc-patches/2020-July/550691.html.
>
> errr... that subject should be with prefix "[PATCH] vect:".
>
> [snip ...] 
> (Some comments in the snipped content will be done in v4)
>
>>> +here.  */
>>> +
>>> +  /* For now we only operate length-based partial vectors on Power,
>>> +which has constant VF all the time, we need some tweakings below
>>> +if it doesn't hold in future.  */
>>> +  gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo).is_constant ());
>> 
>> Where do you rely on this?  There didn't seem to be any obvious
>> to_constant uses.  Since this is “only” a cost calculation, we should
>> be using assumed_vf.
>
> Sorry for the confusion.  This was intended for the poly things like
> VF or nitems_per_ctrl which isn't constant during compilation time,
> then get people's attention on the possible runtime cost on things like
> scaling up for nitems_step etc.  But I just realized that the computations
> like the multiply with another constant can operate on the coefficient,
> it looks there is no runtime cost then?  If so, I think I thought too
> much before.  ;-)
>
>>> -  prologue_cost_vec.release ();
>>> -  epilogue_cost_vec.release ();
>>> +  (void) add_stmt_cost (loop_vinfo, target_cost_data, prol_cnt, 
>>> scalar_stmt,
>>> +   NULL, NULL_TREE, 0, vect_prologue);
>>> +  (void) add_stmt_cost (loop_vinfo, target_cost_data, body_cnt, 
>>> scalar_stmt,
>>> +   NULL, NULL_TREE, 0, vect_body);
>> 
>> IMO this seems to be reproducing too much of the functions that you
>> referred to.  And the danger with that is that they could easily
>> get out of sync later.
>
> Good point!  The original intention was to model as possible as we can,
> to avoid some bad decision due to some unmodeled pieces, like the case
> the loop body is small and some computation become nonnegligible.
> The unsync risks seems also applied for other codes.  How about adding
> some "note" comments in those functions?
>
> The updated v4 is attached by addressing your comments as well as Segher's
> comments.
>
> BR,
> Kewen
> -
>
> gcc/ChangeLog:
>
>   * config/rs6000/rs6000.c (rs6000_adjust_vect_cost_per_loop): New
>   function.
>   (rs6000_finish_cost): Call rs6000_adjust_vect_cost_per_loop.
>   * tree-vect-loop.c (vect_estimate_min_profitable_iters): Add cost
>   modeling for vector with length.
>   * tree-vect-loop-manip.c (vect_set_loop_controls_directly): Update
>   function comment.
>   * tree-vect-stmts.c (vect_gen_len): Likewise.
>
> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index 009afc5f894..86ef584e09b 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -5177,6 +5177,34 @@ rs6000_add_stmt_cost (class vec_info *vinfo, void 
> *data, int count,
>return retval;
>  }
>  
> +/* For some target specific vectorization cost which can't be handled per 
> stmt,
> +   we check the requisite conditions and adjust the vectorization cost
> +   accordingly if satisfied.  One typical example is to model shift cost for
> +   vector with length by counting number of required lengths under condition
> +   LOOP_VINFO_FULLY_WITH_LENGTH_P.  */
> +
> +static void
> +rs6000_adjust_vect_cost_per_loop (rs6000_cost_data *data)
> +{
> +  struct loop *loop = data->loop_info;
> +  gcc_assert (loop);
> +  loop_vec_info loop_vinfo = loop_vec_info_for_loop (loop);
> +
> +  if (LOOP_VINFO_FULLY_WITH_LENGTH_P (loop_vinfo))
> +{
> +  rgroup_controls *rgc;
> +  unsigned int num_vectors_m1;
> +  unsigned int shift_cnt = 0;
> +  FOR_EACH_VEC_ELT (LOOP_VINFO_LENS (loop_vinfo), num_vectors_m1, rgc)
> + if (rgc->type)
> +   /* Each length needs one shift to fill into bits 0-7.  */
> +   shift_cnt += num_vectors_m1 + 1;
> +
> +  rs6000_add_stmt_cost (loop_vinfo, (void *) data, shift_cnt, 
> scalar_stmt,
> + NULL, NULL_TREE, 0, vect_body);
> +}
> +}
> +
>  /* Implement targetm.vectorize.finish_cost.  */
>  
>  static void
> @@ -5186,7 +5214,10 @@ rs6000_finish_cost (void *data, unsigned 
> *prologue_cost,
>rs6000_cost_data *cost_data = (rs6000_cost_data*) data;
>  
>if (cost_data->loop_info)
> -rs6000_density_test (cost_data);
> +{
> +  rs6000_adjust_vect_cost_per_loop (cost_data);
> +  rs6000_density_test (cost_data);
> +}
>  
>/* Don't vectorize minimum-vectorization-factor, simple copy loops
>   that require versioning for any reason.  The vectorization is at
> diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
> i

[PATCH] [PATCH][GCC] arm: Enable no-writeback vldr.16/vstr.16.

2020-07-27 Thread Joe Ramsay
Hi,

There was previously no way to specify that a register operand cannot
have any writeback modifiers, and as a result the argument to vldr.16
and vstr.16 could be erroneously output with post-increment. This
change adds an operand specifier which forbids all writeback, and
selects it in the relevant case for vldr.16 and vstr.16

Bootstrapped on arm-linux, gcc and CMSIS-DSP testsuites are clean.
Is this patch OK for trunk? If yes, please commit on my behalf as I don't
have commit rights.

Thanks,
Joe

gcc/ChangeLog:

2020-05-20  Joe Ramsay  

* config/arm/arm-protos.h (arm_coproc_mem_operand_no_writeback): 
Declare prototype.
(arm_mve_mode_and_operands_type_check): Declare prototype.
* config/arm/arm.c (arm_coproc_mem_operand): Refactor to use 
_arm_coproc_mem_operand.
(arm_coproc_mem_operand_wb): New function to cover full, limited and no 
writeback.
(arm_coproc_mem_operand_no_writeback): New constraint for memory 
operand with no writeback.
(arm_print_operand): Implement 'j' specifier for memory operand that 
does not support
writeback.
(arm_mve_mode_and_operands_type_check): New constraint check for MVE 
memory operands.
* config/arm/constraints.md: Add Uj constraint for VFP vldr.16 and 
vstr.16.
* config/arm/vfp.md (*mov_load_vfp_hf16): New pattern for vldr.16.
(*mov_store_vfp_hf16): New pattern for vstr.16.
(*mov_vfp_16): Remove MVE moves.

gcc/testsuite/ChangeLog:

2020-05-20  Joe Ramsay  

* gcc.target/arm/mve/intrinsics/mve-vldstr16-no-writeback.c: New test.

---
 gcc/config/arm/arm-protos.h|   3 +
 gcc/config/arm/arm.c   | 100 ++---
 gcc/config/arm/constraints.md  |   7 ++
 gcc/config/arm/vfp.md  |  28 --
 .../arm/mve/intrinsics/mve-vldstr16-no-writeback.c |  17 
 5 files changed, 135 insertions(+), 20 deletions(-)
 create mode 100644 
gcc/testsuite/gcc.target/arm/mve/intrinsics/mve-vldstr16-no-writeback.c

diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 33d162c..e811da4 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -115,8 +115,11 @@ extern enum reg_class coproc_secondary_reload_class 
(machine_mode, rtx,
 extern bool arm_tls_referenced_p (rtx);
 
 extern int arm_coproc_mem_operand (rtx, bool);
+extern int arm_coproc_mem_operand_no_writeback (rtx);
+extern int arm_coproc_mem_operand_wb (rtx, int);
 extern int neon_vector_mem_operand (rtx, int, bool);
 extern int mve_vector_mem_operand (machine_mode, rtx, bool);
+bool arm_mve_mode_and_operands_type_check (machine_mode, rtx, rtx);
 extern int neon_struct_mem_operand (rtx);
 
 extern rtx *neon_vcmla_lane_prepare_operands (rtx *);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 6b7ca82..ed080d2 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -13217,13 +13217,14 @@ neon_element_bits (machine_mode mode)
 /* Predicates for `match_operand' and `match_operator'.  */
 
 /* Return TRUE if OP is a valid coprocessor memory address pattern.
-   WB is true if full writeback address modes are allowed and is false
+   WB level is 2 if full writeback address modes are allowed, 1
if limited writeback address modes (POST_INC and PRE_DEC) are
-   allowed.  */
+   allowed and 0 if no writeback at all is supported.  */
 
 int
-arm_coproc_mem_operand (rtx op, bool wb)
+arm_coproc_mem_operand_wb (rtx op, int wb_level)
 {
+  gcc_assert (wb_level == 0 || wb_level == 1 || wb_level == 2);
   rtx ind;
 
   /* Reject eliminable registers.  */
@@ -13256,16 +13257,18 @@ arm_coproc_mem_operand (rtx op, bool wb)
 
   /* Autoincremment addressing modes.  POST_INC and PRE_DEC are
  acceptable in any case (subject to verification by
- arm_address_register_rtx_p).  We need WB to be true to accept
+ arm_address_register_rtx_p).  We need full writeback to accept
+ PRE_INC and POST_DEC, and at least restricted writeback for
  PRE_INC and POST_DEC.  */
-  if (GET_CODE (ind) == POST_INC
-  || GET_CODE (ind) == PRE_DEC
-  || (wb
- && (GET_CODE (ind) == PRE_INC
- || GET_CODE (ind) == POST_DEC)))
+  if (wb_level > 0
+  && (GET_CODE (ind) == POST_INC
+ || GET_CODE (ind) == PRE_DEC
+ || (wb_level > 1
+ && (GET_CODE (ind) == PRE_INC
+ || GET_CODE (ind) == POST_DEC
 return arm_address_register_rtx_p (XEXP (ind, 0), 0);
 
-  if (wb
+  if (wb_level > 1
   && (GET_CODE (ind) == POST_MODIFY || GET_CODE (ind) == PRE_MODIFY)
   && arm_address_register_rtx_p (XEXP (ind, 0), 0)
   && GET_CODE (XEXP (ind, 1)) == PLUS
@@ -13287,6 +13290,25 @@ arm_coproc_mem_operand (rtx op, bool wb)
   return FALSE;
 }
 
+/* Return TRUE if OP is a valid coprocessor memory address pattern.
+   WB is true if full writeback address modes are allowed and is false
+   if limited writeback addres

Re: [PATCH] expr: build string_constant only for a char type

2020-07-27 Thread Martin Liška

On 7/27/20 3:16 PM, Jakub Jelinek wrote:

On Mon, Jul 27, 2020 at 02:32:15PM +0200, Martin Liška wrote:

As mentioned in the PR, we should not create a string constant for a type
that is different from char_type_node. Looking at expr.c, I was inspired
and used 'TYPE_MAIN_VARIANT (chartype) == char_type_node' to verify that 
underlying
type is a character type.


That doesn't look correct, there is char, signed char, unsigned char,
or say std::byte, and all of them are perfectly fine.
So, rather than requiring it is char and nothing else, you should instead
check that it is an INTEGRAL_TYPE_P (maybe better other than BOOLEAN_TYPE?),
which is complete and has the same TYPE_PRECISION as char_type_node.


All right, the following survives tests and bootstraps.

Ready to be installed?
Thanks,
Martin



Jakub



>From d40967eb2ef27b512ae177b1aee5e85ac2246acd Mon Sep 17 00:00:00 2001
From: Martin Liska 
Date: Mon, 27 Jul 2020 12:30:24 +0200
Subject: [PATCH] expr: build string_constant only for a char type

gcc/ChangeLog:

	PR tree-optimization/96058
	* expr.c (string_constant): Build string_constant only
	for a type that has same precision as char_type_node
	and is an integral type.
---
 gcc/expr.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/gcc/expr.c b/gcc/expr.c
index 5db0a7a8565..a150fa0d3b5 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11828,17 +11828,22 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
 	chartype = TREE_TYPE (chartype);
   while (TREE_CODE (chartype) == ARRAY_TYPE)
 	chartype = TREE_TYPE (chartype);
-  /* Convert a char array to an empty STRING_CST having an array
-	 of the expected type and size.  */
-  if (!initsize)
-	  initsize = integer_zero_node;
 
-  unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize);
-  init = build_string_literal (size, NULL, chartype, size);
-  init = TREE_OPERAND (init, 0);
-  init = TREE_OPERAND (init, 0);
+  if (INTEGRAL_TYPE_P (chartype)
+	  && TYPE_PRECISION (chartype) == TYPE_PRECISION (char_type_node))
+	{
+	  /* Convert a char array to an empty STRING_CST having an array
+	 of the expected type and size.  */
+	  if (!initsize)
+	initsize = integer_zero_node;
+
+	  unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize);
+	  init = build_string_literal (size, NULL, chartype, size);
+	  init = TREE_OPERAND (init, 0);
+	  init = TREE_OPERAND (init, 0);
 
-  *ptr_offset = integer_zero_node;
+	  *ptr_offset = integer_zero_node;
+	}
 }
 
   if (decl)
-- 
2.27.0



Re: [PATCH] expr: build string_constant only for a char type

2020-07-27 Thread Jakub Jelinek via Gcc-patches
On Mon, Jul 27, 2020 at 04:12:09PM +0200, Martin Liška wrote:
> On 7/27/20 3:16 PM, Jakub Jelinek wrote:
> > On Mon, Jul 27, 2020 at 02:32:15PM +0200, Martin Liška wrote:
> > > As mentioned in the PR, we should not create a string constant for a type
> > > that is different from char_type_node. Looking at expr.c, I was inspired
> > > and used 'TYPE_MAIN_VARIANT (chartype) == char_type_node' to verify that 
> > > underlying
> > > type is a character type.
> > 
> > That doesn't look correct, there is char, signed char, unsigned char,
> > or say std::byte, and all of them are perfectly fine.
> > So, rather than requiring it is char and nothing else, you should instead
> > check that it is an INTEGRAL_TYPE_P (maybe better other than BOOLEAN_TYPE?),
> > which is complete and has the same TYPE_PRECISION as char_type_node.
> 
> All right, the following survives tests and bootstraps.

LGTM.

Jakub



[PATCH 00/29] rs6000: Auto-generate builtins from descriptions [V2]

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

This is a slight reworking of the patches posted on June 17.  I have
made a couple of improvements, but the general arrangement of the patches
is the same as before.  Two major things to call out:

 - I've introduced a uniform set of parsing error codes to make it easier
   to follow some of the logic when certain conditions occur during parsing.

 - I reorganized the treatment of built-in stanzas.  Before, the stanza
   conditions were checked prior to initializing entries in the built-in
   table.  Now, all built-ins are initialized, but we check the conditions
   at expand time to determine whether they should be enabled.  This
   addresses a frequent problem we have with the existing methods, where
   "#pragma target" doesn't work as expected when changing the target
   CPU for a single function.

As described before, the current built-in support in the rs6000 back end
requires at least a master's degree in spelunking to comprehend.  It's
full of cruft, redundancy, and unused bits of code, and long overdue for a
replacement.  This is the first part of my project to do that.

My intent is to make adding new built-in functions as simple as adding a
few lines to a couple of files, and automatically generating as much of
the initialization, overload resolution, and expansion logic as possible.
This patch series establishes the format of the input files and creates
a new program (rs600-gen-builtins) to:

 * Parse the input files into an internal representation;
 * Generate a file of #defines (rs6000-vecdefines.h) for eventual
   inclusion into altivec.h; and
 * Generate an initialization file to create and initialize tables of
   built-in functions and overloads.

Patches 1, 3-7, and 9-19 contain the logic for rs6000-gen-builtins.
Patch 8 provides balanced tree search support for parsing scalability.
Patches 2 and 21-27 provide a first cut at the input files.
Patch 20 incorporates the new code into the GCC build.
Patch 28 adds comments to some existing files that will help during the
transition from the previous built-in mechanism.
Patch 29 turns on the initialization logic, while leaving GCC's behavior
unchanged otherwise.

The patch series is constructed so that any prefix set of the patches
can be upstreamed without breaking anything.  There's still plenty of
work left, but I think it will be helpful to get this big chunk of
patches upstream to make further progress easier (translation: avoid
complex rebases like the one I just went through :-).

Following is some additional information about the present and future
design that may be of help.

The set of patches submitted upstream so far does the relatively
straightforward work of reading builtin descriptions from flat files and
generating initialization code for builtin and overload tables.  It also
generates an include file meant to be included in altivec.h, which produces
the #defines that map vec_* to __builtin_* functions for external consumption.

Data structures are automatically initialized in rs6000_builtins.c:
rs6000_autoinit_builtins.  Initialized data structures are:

 - rs6000_gen_builtins:  An enumeration of builtin identifiers, such as
RS6000_BIF_CPU_SUPPORTS.  These names are deliberately different from the
existing builtin identifiers so they can co-exist for a while.

 - rs6000_gen_overloads:  An enumeration of overload identifiers, such as
RS6000_OVLD_MAX.  Again, deliberately different from the old names.  Right
now I have the two enumerations using nonoverlapping numbers.  This is
because the two tables were part of one table in the old design, and I
haven't yet proven for sure that I can separate them without problems.
I think that I can, in which case I will have both enumerations start from
zero.

 - A number of filescope variables representing TREE_TYPEs of functions.
These are named _ftype__ ... _ and
initialized as tree lists from the prototypes in the input files.  The
naming scheme for types is described in the code. 

 - rs6000_builtin_info_x:  An array indexed by rs6000_gen_builtins containing
all the fun stuff for each builtin.  The "_x" is because we already have
rs6000_builtin_info as the old table, and they need to coexist for a while.

 - rs6000_overload_info:  An array indexed by rs6000_gen_overloads containing
all the fun stuff for each overload.

 - bif_hash:  A hash table mapping builtin function names to pointers to
their rs6000_builtin_info_x entries.

 - ovld_hash:  A hash table mapping overload names to pointers to their
rs6000_overload_info entries. 

The new initialization code is called from rs6000_init_builtins. Currently
this function continues to do its existing initialization work, but also
initializes the new tables (and then ignores them). 

The old initialization code contains a lot of ad hoc hackery to handle
different kinds of functions that require extra behavior. The new design
removes as much of that as possible, and instead uses syntax in the flat
file to generate flags and 

[PATCH 01/29] rs6000: Initial create of rs6000-gen-builtins.c

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

Add header commentary explaining the purpose of rs6000-gen-builtins.c,
along with an initial set of includes.

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c: New.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 141 
 1 file changed, 141 insertions(+)
 create mode 100644 gcc/config/rs6000/rs6000-gen-builtins.c

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
new file mode 100644
index 000..462387f4b44
--- /dev/null
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -0,0 +1,141 @@
+/* Generate built-in function initialization and recognition for Power.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   Contributed by Bill Schmidt, IBM 
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+/* This program generates built-in function initialization and
+   recognition code for Power targets, based on text files that
+   describe the built-in functions and vector overloads:
+
+ rs6000-builtin-new.def Table of built-in functions
+ rs6000-overload.defTable of overload functions
+
+   Both files group similar functions together in "stanzas," as
+   described below.
+
+   Each stanza in the built-in function file starts with a line
+   identifying the circumstances in which the group of functions is
+   permitted, with the gating predicate in square brackets.  For
+   example, this could be
+
+ [altivec]
+
+   or it could be
+
+ [power9]
+
+   The bracketed gating predicate is the only information allowed on
+   the stanza header line, other than whitespace.
+
+   Following the stanza header are two lines for each function: the
+   prototype line and the attributes line.  The prototype line has
+   this format, where the square brackets indicate optional
+   information and angle brackets indicate required information:
+
+ [kind]   ();
+
+   Here [kind] can be one of "const", "pure", or "fpmath";
+is a legal type for a built-in function result;
+is the name by which the function can be called;
+   and  is a comma-separated list of legal types
+   for built-in function arguments.  The argument list may be
+   empty, but the parentheses and semicolon are required.
+
+   The attributes line looks like this:
+
+   {}
+
+   Here  is a unique internal identifier for the built-in
+   function that will be used as part of an enumeration of all
+   built-in functions;  is the define_expand or
+   define_insn that will be invoked when the call is expanded;
+   and  is a comma-separated list of special
+   conditions that apply to the built-in function.  The attribute
+   list may be empty, but the braces are required.
+
+   Attributes are strings, such as these:
+
+ init Process as a vec_init function
+ set  Process as a vec_set function
+ extract  Process as a vec_extract function
+ nosoft   Not valid with -msoft-float
+ ldvecNeeds special handling for vec_ld semantics
+ stvecNeeds special handling for vec_st semantics
+ reve Needs special handling for element reversal
+ pred Needs special handling for comparison predicates
+ htm  Needs special handling for transactional memory
+ htmspr   HTM function using an SPR
+ htmcrHTM function using a CR
+ mma  Needs special handling for MMA instructions
+ no32bit  Not valid for TARGET_32BIT
+ cpu  This is a "cpu_is" or "cpu_supports" builtin
+ ldstmask Altivec mask for load or store
+
+   An example stanza might look like this:
+
+[altivec]
+  const vsc __builtin_altivec_abs_v16qi (vsc);
+ABS_V16QI absv16qi2 {}
+  const vss __builtin_altivec_abs_v8hi (vss);
+ABS_V8HI absv8hi2 {}
+
+   Here "vsc" and "vss" are shorthand for "vector signed char" and
+   "vector signed short" to shorten line lengths and improve readability.
+   Note the use of indentation, which is recommended but not required.
+
+   The overload file has more complex stanza headers.  Here the stanza
+   represents all functions with the same overloaded function name:
+
+ [, , ]
+
+   Here the square brackets are part of the syntax,  is a
+   unique internal identifier for the overload that will be used as part
+   of an enumeration of all overloaded functions;  is the name
+   that will appear as a #define in altivec.h; and  is the
+   name that is overload

[PATCH 10/29] rs6000: Parsing built-in input file, part 1 of 3

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (bif_stanza): New enum.
(curr_bif_stanza): Likewise.
(stanza_entry): New struct.
(stanza_map): New initialized filescope variable.
(enable_string): Likewise.
(fnkinds): New enum.
(typelist): New struct.
(attrinfo): Likewise.
(prototype): Likewise.
(MAXBIFS): New defined constant.
(bifdata): New struct.
(bifs): New filescope variable.
(curr_bif): Likewise.
(stanza_name_to_stanza): New function.
(parse_bif_attrs): New stub function.
(parse_prototype): Likewise.
(parse_bif_entry): New function.
(parse_bif_stanza): Likewise.
(parse_bif): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 320 +++-
 1 file changed, 319 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index d6058a8e73b..a8b0d8e4288 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -173,6 +173,93 @@ enum void_status {
   VOID_OK
 };
 
+/* Stanzas are groupings of built-in functions and overloads by some
+   common feature/attribute.  These definitions are for built-in function
+   stanzas.  */
+enum bif_stanza {
+  BSTZ_ALWAYS,
+  BSTZ_P5,
+  BSTZ_P6,
+  BSTZ_ALTIVEC,
+  BSTZ_VSX,
+  BSTZ_P7,
+  BSTZ_P7_64,
+  BSTZ_P8,
+  BSTZ_P8V,
+  BSTZ_P9,
+  BSTZ_P9_64,
+  BSTZ_P9V,
+  BSTZ_IEEE128_HW,
+  BSTZ_DFP,
+  BSTZ_CRYPTO,
+  BSTZ_HTM,
+  BSTZ_P10,
+  BSTZ_MMA,
+  NUMBIFSTANZAS
+};
+
+static bif_stanza curr_bif_stanza;
+
+struct stanza_entry
+{
+  const char *stanza_name;
+  bif_stanza stanza;
+};
+
+static stanza_entry stanza_map[NUMBIFSTANZAS] =
+  {
+{ "always",BSTZ_ALWAYS },
+{ "power5",BSTZ_P5 },
+{ "power6",BSTZ_P6 },
+{ "altivec",   BSTZ_ALTIVEC},
+{ "vsx",   BSTZ_VSX},
+{ "power7",BSTZ_P7 },
+{ "power7-64", BSTZ_P7_64  },
+{ "power8",BSTZ_P8 },
+{ "power8-vector", BSTZ_P8V},
+{ "power9",BSTZ_P9 },
+{ "power9-64", BSTZ_P9_64  },
+{ "power9-vector", BSTZ_P9V},
+{ "ieee128-hw",BSTZ_IEEE128_HW },
+{ "dfp",   BSTZ_DFP},
+{ "crypto",BSTZ_CRYPTO },
+{ "htm",   BSTZ_HTM},
+{ "power10",   BSTZ_P10},
+{ "mma",   BSTZ_MMA}
+  };
+
+static const char *enable_string[NUMBIFSTANZAS] =
+  {
+"ENB_ALWAYS",
+"ENB_P5",
+"ENB_P6",
+"ENB_ALTIVEC",
+"ENB_VSX",
+"ENB_P7",
+"ENB_P7_64",
+"ENB_P8",
+"ENB_P8V",
+"ENB_P9",
+"ENB_P9_64",
+"ENB_P9V",
+"ENB_IEEE128_HW",
+"ENB_DFP",
+"ENB_CRYPTO",
+"ENB_HTM",
+"ENB_P10",
+"ENB_MMA"
+  };
+
+/* Function modifiers provide special handling for const, pure, and fpmath
+   functions.  These are mutually exclusive, and therefore kept separate
+   from other bif attributes.  */
+enum fnkinds {
+  FNK_NONE,
+  FNK_CONST,
+  FNK_PURE,
+  FNK_FPMATH
+};
+
 /* Legal base types for an argument or return type.  */
 enum basetype {
   BT_CHAR,
@@ -221,7 +308,58 @@ struct typeinfo {
   int val2;
 };
 
+/* A list of argument types.  */
+struct typelist {
+  typeinfo info;
+  typelist *next;
+};
+
+/* Attributes of a builtin function.  */
+struct attrinfo {
+  char isinit;
+  char isset;
+  char isextract;
+  char isnosoft;
+  char isldvec;
+  char isstvec;
+  char isreve;
+  char ispred;
+  char ishtm;
+  char ishtmspr;
+  char ishtmcr;
+  char ismma;
+  char isno32bit;
+  char iscpu;
+  char isldstmask;
+};
+
+/* Fields associated with a function prototype (bif or overload).  */
+struct prototype {
+  typeinfo rettype;
+  char *bifname;
+  int nargs;
+  typelist *args;
+  int restr_opnd[2];
+  restriction restr[2];
+  int restr_val1[2];
+  int restr_val2[2];
+};
+
+/* Data associated with a builtin function, and a table of such data.  */
+#define MAXBIFS 16384
+struct bifdata {
+  int stanza;
+  fnkinds kind;
+  prototype proto;
+  char *idname;
+  char *patname;
+  attrinfo attrs;
+  char *fndecl;
+};
+
+static bifdata bifs[MAXBIFS];
 static int num_bifs;
+static int curr_bif;
 static int num_ovld_stanzas;
 static int num_ovlds;
 
@@ -404,6 +542,15 @@ handle_pointer (typeinfo *typedata)
 }
 }
 
+static bif_stanza
+stanza_name_to_stanza (const char *stanza_name)
+{
+  for (int i = 0; i < NUMBIFSTANZAS; i++)
+if (!strcmp (stanza_name, stanza_map[i].stanza_name))
+  return stanza_map[i].stanza;
+  assert (false);
+}
+
 /* Match one of the allowable base types.  Consumes one token unless the
token is "long", which must be paired with a second "long".  Optionally
consumes a following '*' token for pointers.  Return 1 fo

[PATCH 03/29] rs6000: Add file support and functions for diagnostic support

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (bif_file): New filescope
variable.
(ovld_file): Likewise.
(header_file): Likewise.
(init_file): Likewise.
(defines_file): Likewise.
(pgm_path): Likewise.
(bif_path): Likewise.
(ovld_path): Likewise.
(header_path): Likewise.
(init_path): Likewise.
(defines_path): Likewise.
(LINELEN): New defined constant.
(linebuf): New filescope variable.
(line): Likewise.
(pos): Likewise.
(diag): Likewise.
(bif_diag): New function.
(ovld_diag): New function.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 48 +
 1 file changed, 48 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 462387f4b44..8c8fad66edf 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -139,3 +139,51 @@ along with GCC; see the file COPYING3.  If not see
 #include 
 #include 
 #include 
+
+/* Input and output file descriptors and pathnames.  */
+static FILE *bif_file;
+static FILE *ovld_file;
+static FILE *header_file;
+static FILE *init_file;
+static FILE *defines_file;
+
+static const char *pgm_path;
+static const char *bif_path;
+static const char *ovld_path;
+static const char *header_path;
+static const char *init_path;
+static const char *defines_path;
+
+/* Position information.  Note that "pos" is zero-indexed, but users
+   expect one-indexed column information, so representations of "pos"
+   as columns in diagnostic messages must be adjusted.  */
+#define LINELEN 1024
+static char linebuf[LINELEN];
+static int line;
+static int pos;
+
+/* Pointer to a diagnostic function.  */
+void (*diag) (const char *, ...) __attribute__ ((format (printf, 1, 2)))
+  = NULL;
+
+/* Custom diagnostics.  */
+static void __attribute__ ((format (printf, 1, 2)))
+bif_diag (const char * fmt, ...)
+{
+  va_list args;
+  fprintf (stderr, "%s:%d: ", bif_path, line);
+  va_start (args, fmt);
+  vfprintf (stderr, fmt, args);
+  va_end (args);
+}
+
+static void __attribute__ ((format (printf, 1, 2)))
+ovld_diag (const char * fmt, ...)
+{
+  va_list args;
+  fprintf (stderr, "%s:%d: ", ovld_path, line);
+  va_start (args, fmt);
+  vfprintf (stderr, fmt, args);
+  va_end (args);
+}
+
-- 
2.17.1



[PATCH 07/29] rs6000: Add functions for matching types, part 3 of 3

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (restriction): New enum.
(typeinfo): Add restriction field.
(match_const_restriction): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 136 
 1 file changed, 136 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index efc0b2dec65..18c67ce2202 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -188,6 +188,21 @@ enum basetype {
   BT_IBM128
 };
 
+/* Ways in which a const int value can be restricted.  RES_BITS indicates
+   that the integer is restricted to val1 bits, interpreted as an unsigned
+   number.  RES_RANGE indicates that the integer is restricted to values
+   between val1 and val2, inclusive.  RES_VAR_RANGE is like RES_RANGE, but
+   the argument may be variable, so it can only be checked if it is constant.
+   RES_VALUES indicates that the integer must have one of the values val1
+   or val2.  */
+enum restriction {
+  RES_NONE,
+  RES_BITS,
+  RES_RANGE,
+  RES_VAR_RANGE,
+  RES_VALUES
+};
+
 /* Type modifiers for an argument or return type.  */
 struct typeinfo {
   char isvoid;
@@ -200,6 +215,7 @@ struct typeinfo {
   char ispointer;
   char isopaque;
   basetype base;
+  restriction restr;
   int val1;
   int val2;
 };
@@ -433,6 +449,126 @@ match_basetype (typeinfo *typedata)
 static int
 match_const_restriction (typeinfo *typedata)
 {
+  int oldpos = pos;
+  if (linebuf[pos] == '<')
+{
+  safe_inc_pos ();
+  oldpos = pos;
+  int x = match_integer ();
+  if (x == MININT)
+   {
+ (*diag) ("malformed integer at column %d.\n", oldpos + 1);
+ return 0;
+   }
+  consume_whitespace ();
+  if (linebuf[pos] == '>')
+   {
+ typedata->restr = RES_BITS;
+ typedata->val1 = x;
+ safe_inc_pos ();
+ return 1;
+   }
+  else if (linebuf[pos] != ',')
+   {
+ (*diag) ("malformed restriction at column %d.\n", pos + 1);
+ return 0;
+   }
+  safe_inc_pos ();
+  oldpos = pos;
+  int y = match_integer ();
+  if (y == MININT)
+   {
+ (*diag) ("malformed integer at column %d.\n", oldpos + 1);
+ return 0;
+   }
+  typedata->restr = RES_RANGE;
+  typedata->val1 = x;
+  typedata->val2 = y;
+
+  consume_whitespace ();
+  if (linebuf[pos] != '>')
+   {
+ (*diag) ("malformed restriction at column %d.\n", pos + 1);
+ return 0;
+   }
+  safe_inc_pos ();
+}
+  else if (linebuf[pos] == '{')
+{
+  safe_inc_pos ();
+  oldpos = pos;
+  int x = match_integer ();
+  if (x == MININT)
+   {
+ (*diag) ("malformed integer at column %d.\n", oldpos + 1);
+ return 0;
+   }
+  consume_whitespace ();
+  if (linebuf[pos] != ',')
+   {
+ (*diag) ("missing comma at column %d.\n", pos + 1);
+ return 0;
+   }
+  safe_inc_pos ();
+  consume_whitespace ();
+  oldpos = pos;
+  int y = match_integer ();
+  if (y == MININT)
+   {
+ (*diag) ("malformed integer at column %d.\n", oldpos + 1);
+ return 0;
+   }
+  typedata->restr = RES_VALUES;
+  typedata->val1 = x;
+  typedata->val2 = y;
+
+  consume_whitespace ();
+  if (linebuf[pos] != '}')
+   {
+ (*diag) ("malformed restriction at column %d.\n", pos + 1);
+ return 0;
+   }
+  safe_inc_pos ();
+}
+  else
+{
+  assert (linebuf[pos] == '[');
+  safe_inc_pos ();
+  oldpos = pos;
+  int x = match_integer ();
+  if (x == MININT)
+   {
+ (*diag) ("malformed integer at column %d.\n", oldpos + 1);
+ return 0;
+   }
+  consume_whitespace ();
+  if (linebuf[pos] != ',')
+   {
+ (*diag) ("missing comma at column %d.\n", pos + 1);
+ return 0;
+   }
+  safe_inc_pos ();
+  consume_whitespace ();
+  oldpos = pos;
+  int y = match_integer ();
+  if (y == MININT)
+   {
+ (*diag) ("malformed integer at column %d.\n", oldpos + 1);
+ return 0;
+   }
+  typedata->restr = RES_VAR_RANGE;
+  typedata->val1 = x;
+  typedata->val2 = y;
+
+  consume_whitespace ();
+  if (linebuf[pos] != ']')
+   {
+ (*diag) ("malformed restriction at column %d.\n", pos + 1);
+ return 0;
+   }
+  safe_inc_pos ();
+}
+
   return 1;
 }
 
-- 
2.17.1



[PATCH 09/29] rs6000: Main function with stubs for parsing and output

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (rbtree.h): New #include.
(num_bifs): Likewise.
(num_ovld_stanzas): Likewise.
(num_ovlds): Likewise.
(exit_codes): Add more enum values.
(parse_codes): New enum.
(bif_rbt): New filescope variable.
(ovld_rbt): Likewise.
(fntype_rbt): Likewise.
(parse_bif): New stub function.
(parse_ovld): Likewise.
(write_header_file): Likewise.
(write_init_file): Likewise.
(write_defines_file): Likewise.
(delete_output_files): New function.
(main): Likewise.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 210 
 1 file changed, 210 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 18c67ce2202..d6058a8e73b 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -139,6 +139,7 @@ along with GCC; see the file COPYING3.  If not see
 #include 
 #include 
 #include 
+#include "rbtree.h"
 
 /* Used as a sentinel for range constraints on integer fields.  No field can
be 32 bits wide, so this is a safe sentinel value.  */
@@ -220,11 +221,41 @@ struct typeinfo {
   int val2;
 };
 
+static int num_bifs;
+static int num_ovld_stanzas;
+static int num_ovlds;
+
 /* Exit codes for the shell.  */
 enum exit_codes {
+  EC_OK,
+  EC_BADARGS,
+  EC_NOBIF,
+  EC_NOOVLD,
+  EC_NOHDR,
+  EC_NOINIT,
+  EC_NODEFINES,
+  EC_PARSEBIF,
+  EC_PARSEOVLD,
+  EC_WRITEHDR,
+  EC_WRITEINIT,
+  EC_WRITEDEFINES,
   EC_INTERR
 };
 
+/* Return codes for parsing routines.  */
+enum parse_codes {
+  PC_OK,
+  PC_EOFILE,
+  PC_EOSTANZA,
+  PC_PARSEFAIL
+};
+
+/* The red-black trees for built-in function identifiers, built-in
+   overload identifiers, and function type descriptors.  */
+static rbt_strings bif_rbt;
+static rbt_strings ovld_rbt;
+static rbt_strings fntype_rbt;
+
 /* Pointer to a diagnostic function.  */
 void (*diag) (const char *, ...) __attribute__ ((format (printf, 1, 2)))
   = NULL;
@@ -875,3 +906,182 @@ match_type (typeinfo *typedata, int voidok)
   return match_basetype (typedata);
 }
 
+/* Parse the built-in file.  */
+static parse_codes
+parse_bif ()
+{
+  return PC_OK;
+}
+
+/* Parse the overload file.  */
+static parse_codes
+parse_ovld ()
+{
+  return PC_OK;
+}
+
+/* Write everything to the header file (rs6000-builtins.h).  */
+static int
+write_header_file ()
+{
+  return 1;
+}
+
+/* Write everything to the initialization file (rs6000-builtins.c).  */
+static int
+write_init_file ()
+{
+  return 1;
+}
+
+/* Write everything to the include file (rs6000-vecdefines.h).  */
+static int
+write_defines_file ()
+{
+  return 1;
+}
+
+/* Close and delete output files after any failure, so that subsequent
+   build dependencies will fail.  */
+static void
+delete_output_files ()
+{
+  /* Depending on whence we're called, some of these may already be
+ closed.  Don't check for errors.  */
+  fclose (header_file);
+  fclose (init_file);
+  fclose (defines_file);
+
+  unlink (header_path);
+  unlink (init_path);
+  unlink (defines_path);
+}
+
+/* Main program to convert flat files into built-in initialization code.  */
+int
+main (int argc, const char **argv)
+{
+  if (argc != 6)
+{
+  fprintf (stderr,
+  "Five arguments required: two input file and three output "
+  "files.\n");
+  exit (EC_BADARGS);
+}
+
+  pgm_path = argv[0];
+  bif_path = argv[1];
+  ovld_path = argv[2];
+  header_path = argv[3];
+  init_path = argv[4];
+  defines_path = argv[5];
+
+  bif_file = fopen (bif_path, "r");
+  if (!bif_file)
+{
+  fprintf (stderr, "Cannot find input built-in file '%s'.\n", bif_path);
+  exit (EC_NOBIF);
+}
+  ovld_file = fopen (ovld_path, "r");
+  if (!ovld_file)
+{
+  fprintf (stderr, "Cannot find input overload file '%s'.\n", ovld_path);
+  exit (EC_NOOVLD);
+}
+  header_file = fopen (header_path, "w");
+  if (!header_file)
+{
+  fprintf (stderr, "Cannot open header file '%s' for output.\n",
+  header_path);
+  exit (EC_NOHDR);
+}
+  init_file = fopen (init_path, "w");
+  if (!init_file)
+{
+  fprintf (stderr, "Cannot open init file '%s' for output.\n", init_path);
+  exit (EC_NOINIT);
+}
+  defines_file = fopen (defines_path, "w");
+  if (!defines_file)
+{
+  fprintf (stderr, "Cannot open defines file '%s' for output.\n",
+  defines_path);
+  exit (EC_NODEFINES);
+}
+
+  /* Initialize the balanced trees containing built-in function ids,
+ overload function ids, and function type declaration ids.  */
+  bif_rbt.rbt_nil = (rbt_string_node *) malloc (sizeof (rbt_string_node));
+  bif_rbt.rbt_nil->color = RBT_BLACK;
+  bif_rbt.rbt_root = bif_rbt.rbt_nil;
+
+  ovld_rbt.rbt_nil = (rbt_string_node *) malloc (sizeof (rbt_string_node));
+  ovld_rbt.rbt_nil->color

[PATCH 02/29] rs6000: Add initial input files

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

This patch adds a tiny subset of the built-in and overload descriptions.

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-builtin-new.def: New.
* config/rs6000/rs6000-overload.def: New.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 179 +++
 gcc/config/rs6000/rs6000-overload.def|  57 
 2 files changed, 236 insertions(+)
 create mode 100644 gcc/config/rs6000/rs6000-builtin-new.def
 create mode 100644 gcc/config/rs6000/rs6000-overload.def

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
new file mode 100644
index 000..5fc7e1301c3
--- /dev/null
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -0,0 +1,179 @@
+; Built-in functions for PowerPC.
+; Copyright (C) 2020 Free Software Foundation, Inc.
+; Contributed by Bill Schmidt, IBM 
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; .  */
+
+
+; Built-in functions in this file are organized into "stanzas", where
+; all built-ins in a given stanza are enabled together.  Each stanza
+; starts with a line identifying the circumstances in which the group of
+; functions is permitted, with the gating predicate in square brackets.
+; This is the only information allowed on the stanza header line, other
+; than whitespace.
+;
+; Following the stanza header are two lines for each function: the
+; prototype line and the attributes line.  The prototype line has
+; this format, where the square brackets indicate optional
+; information and angle brackets indicate required information:
+;
+;   [kind]   ();
+;
+; Here [kind] can be one of "const", "pure", or "fpmath";
+;  is a legal type for a built-in function result;
+;  is the name by which the function can be called;
+; and  is a comma-separated list of legal types
+; for built-in function arguments.  The argument list may be
+; empty, but the parentheses and semicolon are required.
+;
+; A legal type is of the form:
+;
+;   [const] [[signed|unsigned]  | ] [*]
+;
+; where "const" applies only to a  of "int".  Legal values
+; of  are (for now):
+;
+;   char
+;   short
+;   int
+;   long long
+;   float
+;   double
+;   __int128
+;   _Float128
+;   _Decimal32
+;   _Decimal64
+;   _Decimal128
+;   __ibm128
+;
+; Legal values of  are as follows, and are shorthand for
+; the associated meaning:
+;
+;   vscvector signed char
+;   vucvector unsigned char
+;   vbcvector bool char
+;   vssvector signed short
+;   vusvector unsigned short
+;   vbsvector bool short
+;   vsivector signed int
+;   vuivector unsigned int
+;   vbivector bool int
+;   vsll   vector signed long long
+;   vull   vector unsigned long long
+;   vbll   vector bool long long
+;   vsqvector signed __int128
+;   vuqvector unsigned __int128
+;   vbqvector bool __int128
+;   vp vector pixel
+;   vf vector float
+;   vd vector double
+;   vopopaque vector (matches all vectors)
+;
+; For simplicity, We don't support "short int" and "long long int".
+; We don't currently support a  of "bool", "long double",
+; or "_Float16".  "signed" and "unsigned" only apply to integral base
+; types.  The optional * indicates a pointer type, which can be used
+; only with "void" and "const char" in this file.  (More specific
+; pointer types are allowed in overload prototypes.)
+;
+; The attributes line looks like this:
+;
+; {}
+;
+; Here  is a unique internal identifier for the built-in
+; function that will be used as part of an enumeration of all
+; built-in functions;  is the define_expand or
+; define_insn that will be invoked when the call is expanded;
+; and  is a comma-separated list of special
+; conditions that apply to the built-in function.  The attribute
+; list may be empty, but the braces are required.
+;
+; Attributes are strings, and the allowed ones are listed below.
+;
+;   init Process as a vec_init function
+;   set  Process as a vec_set function
+;   extract  Process as a vec_extract function
+;   nosoft   Not valid with -msoft-float
+;   ldvecNeeds special handling for vec_ld semantics
+;   stvecNeeds special handling for vec_st semantics
+;   reve Needs special ha

[PATCH 08/29] rs6000: Red-black tree implementation for balanced tree search

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rbtree.c: New file.
* config/rs6000/rbtree.h: New file.
---
 gcc/config/rs6000/rbtree.c | 233 +
 gcc/config/rs6000/rbtree.h |  51 
 2 files changed, 284 insertions(+)
 create mode 100644 gcc/config/rs6000/rbtree.c
 create mode 100644 gcc/config/rs6000/rbtree.h

diff --git a/gcc/config/rs6000/rbtree.c b/gcc/config/rs6000/rbtree.c
new file mode 100644
index 000..50e5f57a50c
--- /dev/null
+++ b/gcc/config/rs6000/rbtree.c
@@ -0,0 +1,233 @@
+/* Partial red-black tree implementation for rs6000-gen-builtins.c.
+   Copyright (C) 2020 Free Software Foundation, Inc.
+   Contributed by Bill Schmidt, IBM 
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+#include 
+#include 
+#include 
+#include 
+#include "rbtree.h"
+
+/* Create a new node to be inserted into the red-black tree.  An inserted
+   node starts out red.  */
+static struct rbt_string_node *
+rbt_create_node (struct rbt_strings *t, char *str)
+{
+  struct rbt_string_node *nodeptr
+= (struct rbt_string_node *) malloc (sizeof (struct rbt_string_node));
+  nodeptr->str = str;
+  nodeptr->left = t->rbt_nil;
+  nodeptr->right = t->rbt_nil;
+  nodeptr->par = NULL;
+  nodeptr->color = RBT_RED;
+  return nodeptr;
+}
+
+/* Perform a left-rotate operation on NODE in the red-black tree.  */
+static void
+rbt_left_rotate (struct rbt_strings *t, struct rbt_string_node *node)
+{
+  struct rbt_string_node *right = node->right;
+  assert (right);
+
+  /* Turn RIGHT's left subtree into NODE's right subtree.  */
+  node->right = right->left;
+  if (right->left != t->rbt_nil)
+right->left->par = node;
+
+  /* Link NODE's parent to RIGHT.  */
+  right->par = node->par;
+
+  if (node->par == t->rbt_nil)
+t->rbt_root = right;
+  else if (node == node->par->left)
+node->par->left = right;
+  else
+node->par->right = right;
+
+  /* Put NODE on RIGHT's left.  */
+  right->left = node;
+  node->par = right;
+}
+
+/* Perform a right-rotate operation on NODE in the red-black tree.  */
+static void
+rbt_right_rotate (struct rbt_strings *t, struct rbt_string_node *node)
+{
+  struct rbt_string_node *left = node->left;
+  assert (left);
+
+  /* Turn LEFT's right subtree into NODE's left subtree.  */
+  node->left = left->right;
+  if (left->right != t->rbt_nil)
+left->right->par = node;
+
+  /* Link NODE's parent to LEFT.  */
+  left->par = node->par;
+
+  if (node->par == t->rbt_nil)
+t->rbt_root = left;
+  else if (node == node->par->right)
+node->par->right = left;
+  else
+node->par->left = left;
+
+  /* Put NODE on LEFT's right.  */
+  left->right = node;
+  node->par = left;
+}
+
+/* Insert STR into the tree, returning 1 for success and 0 if STR already
+   appears in the tree.  */
+int
+rbt_insert (struct rbt_strings *t, char *str)
+{
+  struct rbt_string_node *curr = t->rbt_root;
+  struct rbt_string_node *trail = t->rbt_nil;
+
+  while (curr != t->rbt_nil)
+{
+  trail = curr;
+  int cmp = strcmp (str, curr->str);
+  if (cmp < 0)
+   curr = curr->left;
+  else if (cmp > 0)
+   curr = curr->right;
+  else
+   return 0;
+}
+
+  struct rbt_string_node *fresh = rbt_create_node (t, str);
+  fresh->par = trail;
+
+  if (trail == t->rbt_nil)
+t->rbt_root = fresh;
+  else if (strcmp (fresh->str, trail->str) < 0)
+trail->left = fresh;
+  else
+trail->right = fresh;
+
+  fresh->left = t->rbt_nil;
+  fresh->right = t->rbt_nil;
+
+  /* FRESH has now been inserted as a red leaf.  If we have invalidated
+ one of the following preconditions, we must fix things up:
+  (a) If a node is red, both of its children are black.
+  (b) The root must be black.
+ Note that only (a) or (b) applies at any given time during the
+ process.  This algorithm works up the tree from NEW looking
+ for a red child with a red parent, and cleaning that up.  If the
+ root ends up red, it gets turned black at the end.  */
+  curr = fresh;
+  while (curr->par->color == RBT_RED)
+if (curr->par == curr->par->par->left)
+  {
+   struct rbt_string_node *uncle = curr->par->par->right;
+   if (uncle->color == RBT_RED)
+ {
+   curr->par->color = RBT_BLACK;
+   uncle->color = RBT_BLACK;
+   curr->par->par->color = RBT_RED;
+   curr = curr->par->pa

[PATCH 04/29] rs6000: Add helper functions for parsing

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (MININT): New defined
constant.
(exit_codes): New enum.
(consume_whitespace): New function.
(advance_line): Likewise.
(safe_inc_pos): Likewise.
(match_identifier): Likewise.
(match_integer): Likewise.
(match_to_right_bracket): Likewise.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 121 
 1 file changed, 121 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 8c8fad66edf..e2a9b28eb16 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -140,6 +140,10 @@ along with GCC; see the file COPYING3.  If not see
 #include 
 #include 
 
+/* Used as a sentinel for range constraints on integer fields.  No field can
+   be 32 bits wide, so this is a safe sentinel value.  */
+#define MININT INT32_MIN
+
 /* Input and output file descriptors and pathnames.  */
 static FILE *bif_file;
 static FILE *ovld_file;
@@ -162,6 +166,11 @@ static char linebuf[LINELEN];
 static int line;
 static int pos;
 
+/* Exit codes for the shell.  */
+enum exit_codes {
+  EC_INTERR
+};
+
 /* Pointer to a diagnostic function.  */
 void (*diag) (const char *, ...) __attribute__ ((format (printf, 1, 2)))
   = NULL;
@@ -187,3 +196,115 @@ ovld_diag (const char * fmt, ...)
   va_end (args);
 }
 
+/* Pass over unprintable characters and whitespace (other than a newline,
+   which terminates the scan).  */
+static void
+consume_whitespace ()
+{
+  while (pos < LINELEN && isspace(linebuf[pos]) && linebuf[pos] != '\n')
+pos++;
+  return;
+}
+
+/* Get the next nonblank, noncomment line, returning 0 on EOF, 1 otherwise.  */
+static int
+advance_line (FILE *file)
+{
+  while (1)
+{
+  /* Read ahead one line and check for EOF.  */
+  if (!fgets (linebuf, sizeof(linebuf), file))
+   return 0;
+  line++;
+  pos = 0;
+  consume_whitespace ();
+  if (linebuf[pos] != '\n' && linebuf[pos] != ';')
+   return 1;
+}
+}
+
+static inline void
+safe_inc_pos ()
+{
+  if (pos++ >= LINELEN)
+{
+  (*diag) ("line length overrun.\n");
+  exit (EC_INTERR);
+}
+}
+
+/* Match an identifier, returning NULL on failure, else a pointer to a
+   buffer containing the identifier.  */
+static char *
+match_identifier ()
+{
+  int lastpos = pos - 1;
+  while (isalnum (linebuf[lastpos + 1]) || linebuf[lastpos + 1] == '_')
+if (++lastpos >= LINELEN - 1)
+  {
+   (*diag) ("line length overrun.\n");
+   exit (EC_INTERR);
+  }
+
+  if (lastpos < pos)
+return 0;
+
+  char *buf = (char *) malloc (lastpos - pos + 2);
+  memcpy (buf, &linebuf[pos], lastpos - pos + 1);
+  buf[lastpos - pos + 1] = '\0';
+
+  pos = lastpos + 1;
+  return buf;
+}
+
+/* Match an integer and return its value, or MININT on failure.  */
+static int
+match_integer ()
+{
+  int startpos = pos;
+  if (linebuf[pos] == '-')
+safe_inc_pos ();
+
+  int lastpos = pos - 1;
+  while (isdigit (linebuf[lastpos + 1]))
+if (++lastpos >= LINELEN - 1)
+  {
+   (*diag) ("line length overrun in match_integer.\n");
+   exit (EC_INTERR);
+  }
+
+  if (lastpos < pos)
+return MININT;
+
+  pos = lastpos + 1;
+  char *buf = (char *) malloc (lastpos - startpos + 2);
+  memcpy (buf, &linebuf[startpos], lastpos - startpos + 1);
+  buf[lastpos - startpos + 1] = '\0';
+
+  int x;
+  sscanf (buf, "%d", &x);
+  return x;
+}
+
+static const char *
+match_to_right_bracket ()
+{
+  int lastpos = pos - 1;
+  while (linebuf[lastpos + 1] != ']')
+if (++lastpos >= LINELEN - 1)
+  {
+   (*diag) ("line length overrun.\n");
+   exit (EC_INTERR);
+  }
+
+  if (lastpos < pos)
+return 0;
+
+  char *buf = (char *) malloc (lastpos - pos + 2);
+  memcpy (buf, &linebuf[pos], lastpos - pos + 1);
+  buf[lastpos - pos + 1] = '\0';
+
+  pos = lastpos + 1;
+  return buf;
+}
+
-- 
2.17.1



[PATCH 06/29] rs6000: Add functions for matching types, part 2 of 3

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (match_basetype):
Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 49 +
 1 file changed, 49 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index ea1ebedfa52..efc0b2dec65 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -364,6 +364,55 @@ handle_pointer (typeinfo *typedata)
 static int
 match_basetype (typeinfo *typedata)
 {
+  consume_whitespace ();
+  int oldpos = pos;
+  char *token = match_identifier ();
+  if (!token)
+{
+  (*diag) ("missing base type in return type at column %d\n", pos + 1);
+  return 0;
+}
+
+  if (!strcmp (token, "char"))
+typedata->base = BT_CHAR;
+  else if (!strcmp (token, "short"))
+typedata->base = BT_SHORT;
+  else if (!strcmp (token, "int"))
+typedata->base = BT_INT;
+  else if (!strcmp (token, "long"))
+{
+  consume_whitespace ();
+  char *mustbelong = match_identifier ();
+  if (!mustbelong || strcmp (mustbelong, "long"))
+   {
+ (*diag) ("incomplete 'long long' at column %d\n", oldpos + 1);
+ return 0;
+   }
+  typedata->base = BT_LONGLONG;
+}
+  else if (!strcmp (token, "float"))
+typedata->base = BT_FLOAT;
+  else if (!strcmp (token, "double"))
+typedata->base = BT_DOUBLE;
+  else if (!strcmp (token, "__int128"))
+typedata->base = BT_INT128;
+  else if (!strcmp (token, "_Float128"))
+typedata->base = BT_FLOAT128;
+  else if (!strcmp (token, "_Decimal32"))
+typedata->base = BT_DECIMAL32;
+  else if (!strcmp (token, "_Decimal64"))
+typedata->base = BT_DECIMAL64;
+  else if (!strcmp (token, "_Decimal128"))
+typedata->base = BT_DECIMAL128;
+  else if (!strcmp (token, "__ibm128"))
+typedata->base = BT_IBM128;
+  else
+{
+  (*diag) ("unrecognized base type at column %d\n", oldpos + 1);
+  return 0;
+}
+
+  handle_pointer (typedata);
   return 1;
 }
 
-- 
2.17.1



[PATCH 05/29] rs6000: Add functions for matching types, part 1 of 3

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (void_status): New enum.
(basetype): Likewise.
(typeinfo): New struct.
(handle_pointer): New function.
(match_basetype): New stub function.
(match_const_restriction): Likewise.
(match_type): New function.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 382 
 1 file changed, 382 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index e2a9b28eb16..ea1ebedfa52 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -166,6 +166,44 @@ static char linebuf[LINELEN];
 static int line;
 static int pos;
 
+/* Used to determine whether a type can be void (only return types).  */
+enum void_status {
+  VOID_NOTOK,
+  VOID_OK
+};
+
+/* Legal base types for an argument or return type.  */
+enum basetype {
+  BT_CHAR,
+  BT_SHORT,
+  BT_INT,
+  BT_LONGLONG,
+  BT_FLOAT,
+  BT_DOUBLE,
+  BT_INT128,
+  BT_FLOAT128,
+  BT_DECIMAL32,
+  BT_DECIMAL64,
+  BT_DECIMAL128,
+  BT_IBM128
+};
+
+/* Type modifiers for an argument or return type.  */
+struct typeinfo {
+  char isvoid;
+  char isconst;
+  char isvector;
+  char issigned;
+  char isunsigned;
+  char isbool;
+  char ispixel;
+  char ispointer;
+  char isopaque;
+  basetype base;
+  int val1;
+  int val2;
+};
+
 /* Exit codes for the shell.  */
 enum exit_codes {
   EC_INTERR
@@ -308,3 +346,347 @@ match_to_right_bracket ()
   return buf;
 }
 
+static inline void
+handle_pointer (typeinfo *typedata)
+{
+  consume_whitespace ();
+  if (linebuf[pos] == '*')
+{
+  typedata->ispointer = 1;
+  safe_inc_pos ();
+}
+}
+
+/* Match one of the allowable base types.  Consumes one token unless the
+   token is "long", which must be paired with a second "long".  Optionally
+   consumes a following '*' token for pointers.  Return 1 for success,
+   0 for failure.  */
+static int
+match_basetype (typeinfo *typedata)
+{
+  return 1;
+}
+
+/* A const int argument may be restricted to certain values.  This is
+   indicated by one of the following occurring after the "int' token:
+
+restricts the constant to x bits, interpreted as unsigned
+  restricts the constant to the inclusive range [x,y]
+ [x,y] restricts the constant to the inclusive range [x,y],
+  but only applies if the argument is constant.
+ {x,y} restricts the constant to one of two values, x or y.
+
+   Here x and y are integer tokens.  Note that the "const" token is a
+   lie when the restriction is [x,y], but this simplifies the parsing
+   significantly and is hopefully forgivable.
+
+   Return 1 for success, else 0.  */
+static int
+match_const_restriction (typeinfo *typedata)
+{
+  return 1;
+}
+
+/* Look for a type, which can be terminated by a token that is not part of
+   a type, a comma, or a closing parenthesis.  Place information about the
+   type in TYPEDATA.  Return 1 for success, 0 for failure.  */
+static int
+match_type (typeinfo *typedata, int voidok)
+{
+  /* A legal type is of the form:
+
+   [const] [[signed|unsigned]  | ] [*]
+
+ where "const" applies only to a  of "int".  Legal values
+ of  are (for now):
+
+   char
+   short
+   int
+   long long
+   float
+   double
+   __int128
+   _Float128
+   _Decimal32
+   _Decimal64
+   _Decimal128
+   __ibm128
+
+ Legal values of  are as follows, and are shorthand for
+ the associated meaning:
+
+   vsc vector signed char
+   vuc vector unsigned char
+   vbc vector bool char
+   vss vector signed short
+   vus vector unsigned short
+   vbs vector bool short
+   vsi vector signed int
+   vui vector unsigned int
+   vbi vector bool int
+   vsllvector signed long long
+   vullvector unsigned long long
+   vbllvector bool long long
+   vsq vector signed __int128
+   vuq vector unsigned __int128
+   vbq vector bool __int128
+   vp  vector pixel
+   vf  vector float
+   vd  vector double
+   vop opaque vector (matches all vectors)
+
+ For simplicity, We don't support "short int" and "long long int".
+ We don't support a  of "bool", "long double", or "_Float16",
+ but will add these if builtins require it.  "signed" and "unsigned"
+ only apply to integral base types.  The optional * indicates a pointer
+ type, which can be used with any base type, but is treated for type
+ signature purposes as a pointer to void.  */
+
+  consume_whitespace ();
+  memset (typedata, 0, sizeof(*typedata));
+  int oldpos = pos;
+
+  char *token = match_identifier ();
+  if (!token)
+return 0;
+
+  if (!strcmp (token, "void"))
+typedata->isvoid = 1;
+
+  if (!strcmp (token, "const"))
+{
+  typedata->isconst = 1;
+  consu

[PATCH 11/29] rs6000: Parsing built-in input file, part 2 of 3

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (parse_args): New function.
(parse_prototype): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 143 
 1 file changed, 143 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index a8b0d8e4288..5265b591ec6 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1053,6 +1053,91 @@ match_type (typeinfo *typedata, int voidok)
   return match_basetype (typedata);
 }
 
+/* Parse the argument list.  */
+static parse_codes
+parse_args (prototype *protoptr)
+{
+  typelist **argptr = &protoptr->args;
+  int *nargs = &protoptr->nargs;
+  int *restr_opnd = protoptr->restr_opnd;
+  restriction *restr = protoptr->restr;
+  int *val1 = protoptr->restr_val1;
+  int *val2 = protoptr->restr_val2;
+  int restr_cnt = 0;
+
+  int success;
+  *nargs = 0;
+
+  /* Start the argument list.  */
+  consume_whitespace ();
+  if (linebuf[pos] != '(')
+{
+  (*diag) ("missing '(' at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  safe_inc_pos ();
+
+  do {
+consume_whitespace ();
+int oldpos = pos;
+typelist *argentry = (typelist *) malloc (sizeof (typelist));
+memset (argentry, 0, sizeof (*argentry));
+typeinfo *argtype = &argentry->info;
+success = match_type (argtype, VOID_NOTOK);
+if (success)
+  {
+   if (argtype->restr)
+ {
+   if (restr_cnt >= 2)
+ {
+   (*diag) ("More than two restricted operands\n");
+   return PC_PARSEFAIL;
+ }
+   restr_opnd[restr_cnt] = *nargs + 1;
+   restr[restr_cnt] = argtype->restr;
+   val1[restr_cnt] = argtype->val1;
+   val2[restr_cnt++] = argtype->val2;
+ }
+   (*nargs)++;
+   *argptr = argentry;
+   argptr = &argentry->next;
+   consume_whitespace ();
+   if (linebuf[pos] == ',')
+ safe_inc_pos ();
+   else if (linebuf[pos] != ')')
+ {
+   (*diag) ("arg not followed by ',' or ')' at column %d.\n",
+pos + 1);
+   return PC_PARSEFAIL;
+ }
+
+#ifdef DEBUG
+   (*diag) ("argument type: isvoid = %d, isconst = %d, isvector = %d, \
+issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, ispointer = %d, \
+base = %d, restr = %d, val1 = %d, val2 = %d, pos = %d.\n",
+argtype->isvoid, argtype->isconst, argtype->isvector,
+argtype->issigned, argtype->isunsigned, argtype->isbool,
+argtype->ispixel, argtype->ispointer, argtype->base,
+argtype->restr, argtype->val1, argtype->val2, pos + 1);
+#endif
+  }
+else
+  {
+   free (argentry);
+   *argptr = NULL;
+   pos = oldpos;
+   if (linebuf[pos] != ')')
+ {
+   (*diag) ("badly terminated arg list at column %d.\n", pos + 1);
+   return PC_PARSEFAIL;
+ }
+   safe_inc_pos ();
+  }
+  } while (success);
+
+  return PC_OK;
+}
+
 /* Parse the attribute list.  */
 static parse_codes
 parse_bif_attrs (attrinfo *attrptr)
@@ -1065,6 +1150,64 @@ parse_bif_attrs (attrinfo *attrptr)
 static parse_codes
 parse_prototype (prototype *protoptr)
 {
+  typeinfo *ret_type = &protoptr->rettype;
+  char **bifname = &protoptr->bifname;
+
+  /* Get the return type.  */
+  consume_whitespace ();
+  int oldpos = pos;
+  int success = match_type (ret_type, VOID_OK);
+  if (!success)
+{
+  (*diag) ("missing or badly formed return type at column %d.\n",
+  oldpos + 1);
+  return PC_PARSEFAIL;
+}
+
+#ifdef DEBUG
+  (*diag) ("return type: isvoid = %d, isconst = %d, isvector = %d, \
+issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, ispointer = %d, \
+base = %d, restr[0] = %d, val1[0] = %d, val2[0] = %d, restr1[1] = %d, \
+val1[1] = %d, val2[1] = %d, pos = %d.\n",
+  ret_type->isvoid, ret_type->isconst, ret_type->isvector,
+  ret_type->issigned, ret_type->isunsigned, ret_type->isbool,
+  ret_type->ispixel, ret_type->ispointer, ret_type->base,
+  ret_type->restr, ret_type->val1, ret_type->val2, pos + 1);
+#endif
+
+  /* Get the bif name.  */
+  consume_whitespace ();
+  oldpos = pos;
+  *bifname = match_identifier ();
+  if (!*bifname)
+{
+  (*diag) ("missing function name at column %d.\n", oldpos + 1);
+  return PC_PARSEFAIL;
+}
+
+#ifdef DEBUG
+  (*diag) ("function name is '%s'.\n", *bifname);
+#endif
+
+  /* Process arguments.  */
+  if (parse_args (protoptr) == PC_PARSEFAIL)
+return PC_PARSEFAIL;
+
+  /* Process terminating semicolon.  */
+  consume_whitespace ();
+  if (linebuf[pos] != ';')
+{
+  (*diag) ("missing semicolon at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  safe_inc_pos ();
+  consume_whitespace ();
+  if (linebuf[pos] != '\n')
+{
+  (*diag) ("

[PATCH 12/29] rs6000: Parsing built-in input file, part 3 of 3

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (parse_bif_attrs):
Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 86 +
 1 file changed, 86 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 5265b591ec6..c4bc5c724a3 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1142,6 +1142,92 @@ base = %d, restr = %d, val1 = %d, val2 = %d, pos = 
%d.\n",
 static parse_codes
 parse_bif_attrs (attrinfo *attrptr)
 {
+  consume_whitespace ();
+  if (linebuf[pos] != '{')
+{
+  (*diag) ("missing attribute set at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  safe_inc_pos ();
+
+  memset (attrptr, 0, sizeof (*attrptr));
+  char *attrname = NULL;
+
+  do {
+consume_whitespace ();
+int oldpos = pos;
+attrname = match_identifier ();
+if (attrname)
+  {
+   if (!strcmp (attrname, "init"))
+ attrptr->isinit = 1;
+   else if (!strcmp (attrname, "set"))
+ attrptr->isset = 1;
+   else if (!strcmp (attrname, "extract"))
+ attrptr->isextract = 1;
+   else if (!strcmp (attrname, "nosoft"))
+ attrptr->isnosoft = 1;
+   else if (!strcmp (attrname, "ldvec"))
+ attrptr->isldvec = 1;
+   else if (!strcmp (attrname, "stvec"))
+ attrptr->isstvec = 1;
+   else if (!strcmp (attrname, "reve"))
+ attrptr->isreve = 1;
+   else if (!strcmp (attrname, "pred"))
+ attrptr->ispred = 1;
+   else if (!strcmp (attrname, "htm"))
+ attrptr->ishtm = 1;
+   else if (!strcmp (attrname, "htmspr"))
+ attrptr->ishtmspr = 1;
+   else if (!strcmp (attrname, "htmcr"))
+ attrptr->ishtmcr = 1;
+   else if (!strcmp (attrname, "mma"))
+ attrptr->ismma = 1;
+   else if (!strcmp (attrname, "no32bit"))
+ attrptr->isno32bit = 1;
+   else if (!strcmp (attrname, "cpu"))
+ attrptr->iscpu = 1;
+   else if (!strcmp (attrname, "ldstmask"))
+ attrptr->isldstmask = 1;
+   else
+ {
+   (*diag) ("unknown attribute at column %d.\n", oldpos + 1);
+   return PC_PARSEFAIL;
+ }
+
+   consume_whitespace ();
+   if (linebuf[pos] == ',')
+ safe_inc_pos ();
+   else if (linebuf[pos] != '}')
+ {
+   (*diag) ("arg not followed by ',' or '}' at column %d.\n",
+pos + 1);
+   return PC_PARSEFAIL;
+ }
+  }
+else
+  {
+   pos = oldpos;
+   if (linebuf[pos] != '}')
+ {
+   (*diag) ("badly terminated attr set at column %d.\n", pos + 1);
+   return PC_PARSEFAIL;
+ }
+   safe_inc_pos ();
+  }
+  } while (attrname);
+
+#ifdef DEBUG
+  (*diag) ("attribute set: init = %d, set = %d, extract = %d, \
+nosoft = %d, ldvec = %d, stvec = %d, reve = %d, pred = %d, htm = %d, \
+htmspr = %d, htmcr = %d, mma = %d, no32bit = %d, cpu = %d, ldstmask = %d.\n",
+  attrptr->isinit, attrptr->isset, attrptr->isextract,
+  attrptr->isnosoft, attrptr->isldvec, attrptr->isstvec,
+  attrptr->isreve, attrptr->ispred, attrptr->ishtm, attrptr->ishtmspr,
+  attrptr->ishtmcr, attrptr->ismma, attrptr->isno32bit,
+  attrptr->iscpu, attrptr->isldstmask);
+#endif
+
   return PC_OK;
 }
 
-- 
2.17.1



[PATCH 19/29] rs6000: Write output to the builtins init file, part 3 of 3

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (typemap): New struct.
(TYPE_MAP_SIZE): New defined constant.
(type_map): New filescope variable; initialize.
(map_token_to_type_node): New function.
(write_type_node): New function.
(write_fntype_init): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 116 
 1 file changed, 116 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 43d13b46a43..d2c029c0fb5 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -417,6 +417,60 @@ static rbt_strings bif_rbt;
 static rbt_strings ovld_rbt;
 static rbt_strings fntype_rbt;
 
+/* Mapping from type tokens to type node names.  */
+struct typemap
+{
+  const char *key;
+  const char *value;
+};
+
+/* This table must be kept in alphabetical order, as we use binary
+   search for table lookups in map_token_to_type_node.  The table
+   maps tokens from a fntype string to a tree type.  For example,
+   in "si_ftype_hi" we would map "si" to "intSI_type_node" and
+   map "hi" to "intHI_type_node".  */
+#define TYPE_MAP_SIZE 37
+static typemap type_map[TYPE_MAP_SIZE] =
+  {
+{ "bv16qi","bool_V16QI" },
+{ "bv2di", "bool_V2DI" },
+{ "bv4si", "bool_V4SI" },
+{ "bv8hi", "bool_V8HI" },
+{ "dd","dfloat64" },
+{ "df","double" },
+{ "di","intDI" },
+{ "hi","intHI" },
+{ "if","ibm128_float" },
+{ "opaque", "opaque_V4SI" },
+{ "pv","ptr" },
+{ "qi","intQI" },
+{ "sd","dfloat32" },
+{ "sf","float" },
+{ "si","intSI" },
+{ "td","dfloat128" },
+{ "tf","long_double" },
+{ "ti","intTI" },
+{ "udi",   "unsigned_intDI" },
+{ "uhi",   "unsigned_intHI" },
+{ "uqi",   "unsigned_intQI" },
+{ "usi",   "unsigned_intSI" },
+{ "uti",   "unsigned_intTI" },
+{ "uv16qi","unsigned_V16QI" },
+{ "uv1ti", "unsigned_V1TI" },
+{ "uv2di", "unsigned_V2DI" },
+{ "uv4si", "unsigned_V4SI" },
+{ "uv8hi", "unsigned_V8HI" },
+{ "v", "void" },
+{ "v16qi", "V16QI" },
+{ "v1ti",  "V1TI" },
+{ "v2df",  "V2DF" },
+{ "v2di",  "V2DI" },
+{ "v4sf",  "V4SF" },
+{ "v4si",  "V4SI" },
+{ "v8hi",  "V8HI" },
+{ "vp8hi", "pixel_V8HI" },
+  };
+
 /* Pointer to a diagnostic function.  */
 void (*diag) (const char *, ...) __attribute__ ((format (printf, 1, 2)))
   = NULL;
@@ -2061,10 +2115,72 @@ write_fntype (char *str)
   fprintf (init_file, "tree %s;\n", str);
 }
 
+/* Look up TOK in the type map and return the corresponding string used
+   to build the type node.  */
+static const char *
+map_token_to_type_node (char *tok)
+{
+  int low = 0;
+  int high = TYPE_MAP_SIZE - 1;
+  int mid = (low + high) >> 1;
+  int cmp;
+
+  while ((cmp = strcmp (type_map[mid].key, tok)) && low < high)
+{
+  if (cmp < 0)
+   low = (low == mid ? mid + 1 : mid);
+  else
+   high = (high == mid ? mid - 1: mid);
+  mid = (low + high) >> 1;
+}
+
+  if (low > high)
+{
+  (*diag) ("token '%s' doesn't appear in the type map!\n", tok);
+  exit (EC_INTERR);
+}
+
+  return type_map[mid].value;
+}
+
+/* Write the type node corresponding to TOK.  */
+static void
+write_type_node (char *tok)
+{
+  const char *str = map_token_to_type_node (tok);
+  fprintf (init_file, "%s_type_node", str);
+}
+
 /* Write an initializer for a function type identified by STR.  */
 void
 write_fntype_init (char *str)
 {
+  char *tok;
+
+  /* Avoid side effects of strtok on the original string by using a copy.  */
+  char *buf = (char *) malloc (strlen (str) + 1);
+  strcpy (buf, str);
+
+  fprintf (init_file, "  %s\n= build_function_type_list (", buf);
+  tok = strtok (buf, "_");
+  write_type_node (tok);
+  tok = strtok (0, "_");
+  assert (tok);
+  assert (!strcmp (tok, "ftype"));
+
+  tok = strtok (0, "_");
+  if (tok)
+fprintf (init_file, ",\n\t\t\t\t");
+
+  /* Note:  A function with no arguments ends with '_ftype_v'.  */
+  while (tok && strcmp (tok, "v"))
+{
+  write_type_node (tok);
+  tok = strtok (0, "_");
+  fprintf (init_file, ",\n\t\t\t\t");
+}
+  fprintf (init_file, "NULL_TREE);\n");
+  free (buf);
 }
 
 /* Write everything to the header file (rs6000-builtins.h).  */
-- 
2.17.1



[PATCH 18/29] rs6000: Write output to the builtins init file, part 2 of 3

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (write_init_bif_table):
Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 153 
 1 file changed, 153 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 3ac199ff2e5..43d13b46a43 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2094,6 +2094,159 @@ write_header_file ()
 static void
 write_init_bif_table ()
 {
+  const char *attr_string;
+
+  for (int i = 0; i <= curr_bif; i++)
+{
+  fprintf (init_file,
+  "  rs6000_builtin_info_x[RS6000_BIF_%s].bifname"
+  "\n= \"%s\";\n",
+  bifs[i].idname, bifs[i].proto.bifname);
+  fprintf (init_file,
+  "  rs6000_builtin_info_x[RS6000_BIF_%s].enable"
+  "\n= %s;\n",
+  bifs[i].idname, enable_string[bifs[i].stanza]);
+  fprintf (init_file,
+  "  rs6000_builtin_info_x[RS6000_BIF_%s].fntype"
+  "\n= %s;\n",
+  bifs[i].idname, bifs[i].fndecl);
+  fprintf (init_file,
+  "  rs6000_builtin_info_x[RS6000_BIF_%s].nargs"
+  "\n= %d;\n",
+  bifs[i].idname, bifs[i].proto.nargs);
+  fprintf (init_file,
+  "  rs6000_builtin_info_x[RS6000_BIF_%s].icode"
+  "\n= CODE_FOR_%s;\n",
+  bifs[i].idname, bifs[i].patname);
+  fprintf (init_file,
+  "  rs6000_builtin_info_x[RS6000_BIF_%s].bifattrs"
+  "\n= 0",
+  bifs[i].idname);
+  if (bifs[i].attrs.isinit)
+   fprintf (init_file, " | bif_init_bit");
+  if (bifs[i].attrs.isset)
+   fprintf (init_file, " | bif_set_bit");
+  if (bifs[i].attrs.isextract)
+   fprintf (init_file, " | bif_extract_bit");
+  if (bifs[i].attrs.isnosoft)
+   fprintf (init_file, " | bif_nosoft_bit");
+  if (bifs[i].attrs.isldvec)
+   fprintf (init_file, " | bif_ldvec_bit");
+  if (bifs[i].attrs.isstvec)
+   fprintf (init_file, " | bif_stvec_bit");
+  if (bifs[i].attrs.isreve)
+   fprintf (init_file, " | bif_reve_bit");
+  if (bifs[i].attrs.ispred)
+   fprintf (init_file, " | bif_pred_bit");
+  if (bifs[i].attrs.ishtm)
+   fprintf (init_file, " | bif_htm_bit");
+  if (bifs[i].attrs.ishtmspr)
+   fprintf (init_file, " | bif_htmspr_bit");
+  if (bifs[i].attrs.ishtmcr)
+   fprintf (init_file, " | bif_htmcr_bit");
+  if (bifs[i].attrs.ismma)
+   fprintf (init_file, " | bif_mma_bit");
+  if (bifs[i].attrs.isno32bit)
+   fprintf (init_file, " | bif_no32bit_bit");
+  if (bifs[i].attrs.iscpu)
+   fprintf (init_file, " | bif_cpu_bit");
+  if (bifs[i].attrs.isldstmask)
+   fprintf (init_file, " | bif_ldstmask_bit");
+  fprintf (init_file, ";\n");
+  for (int j = 0; j < 1; j++)
+   {
+ fprintf (init_file,
+  "  rs6000_builtin_info_x[RS6000_BIF_%s].restr_opnd[%d]"
+  "\n= %d;\n",
+  bifs[i].idname, j, bifs[i].proto.restr_opnd[j]);
+ if (bifs[i].proto.restr_opnd[j])
+   {
+ const char *res
+   = (bifs[i].proto.restr[j] == RES_BITS ? "RES_BITS"
+  : (bifs[i].proto.restr[j] == RES_RANGE ? "RES_RANGE"
+ : (bifs[i].proto.restr[j] == RES_VALUES ? "RES_VALUES"
+: (bifs[i].proto.restr[j] == RES_VAR_RANGE
+   ? "RES_VAR_RANGE" : "ERROR";
+ fprintf (init_file,
+  "  rs6000_builtin_info_x[RS6000_BIF_%s].restr[%d]"
+  "\n= %s;\n",
+  bifs[i].idname, j, res);
+ fprintf (init_file,
+  "  rs6000_builtin_info_x[RS6000_BIF_%s].restr_val1[%d]"
+  "\n= %d;\n",
+  bifs[i].idname, j, bifs[i].proto.restr_val1[j]);
+ fprintf (init_file,
+  "  rs6000_builtin_info_x[RS6000_BIF_%s].restr_val2[%d]"
+  "\n= %d;\n",
+  bifs[i].idname, j, bifs[i].proto.restr_val2[j]);
+   }
+ fprintf (init_file, "\n");
+   }
+
+  fprintf (init_file,
+  "  bifaddr = &rs6000_builtin_info_x[RS6000_BIF_%s];\n",
+  bifs[i].idname);
+  fprintf (init_file,
+  "  hash = rs6000_bif_hasher::hash (bifaddr);\n");
+  fprintf (init_file,
+  "  slot = bif_hash.find_slot_with_hash (\n");
+  fprintf (init_file,
+  "   \"%s\", hash, INSERT\n",
+  bifs[i].proto.bifname);
+  fprintf (init_file,
+  " );\n");
+  fprintf (init_file,
+  "  *slot = bifaddr;\n\n");
+
+  fprintf (init_file,
+  "  if (new_builtins_are_live)\n");
+  fprin

[PATCH 16/29] rs6000: Write output to the builtins header file

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c
(write_autogenerated_header): New function.
(write_bif_enum): Likewise.
(write_ovld_enum): Likewise.
(write_decls): Likewise.
(write_extern_fntype): Likewise.
(write_header_file): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 193 
 1 file changed, 193 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 67336152550..67c7b22aad6 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1878,10 +1878,203 @@ parse_ovld ()
   return result;
 }
 
+/* Write a comment at the top of FILE about how the code was generated.  */
+static void
+write_autogenerated_header (FILE *file)
+{
+  fprintf (file, "/* Automatically generated by the program '%s'\n",
+  pgm_path);
+  fprintf (file, "   from the files '%s' and '%s'.  */\n\n",
+  bif_path, ovld_path);
+}
+
+/* Callback functions used in creating enumerations.  */
+void write_bif_enum (char *str)
+{
+  fprintf (header_file, "  RS6000_BIF_%s,\n", str);
+}
+
+void write_ovld_enum (char *str)
+{
+  fprintf (header_file, "  RS6000_OVLD_%s,\n", str);
+}
+
+/* Write declarations into the header file.  */
+static void
+write_decls ()
+{
+  fprintf (header_file, "enum rs6000_gen_builtins\n{\n  RS6000_BIF_NONE,\n");
+  rbt_inorder_callback (&bif_rbt, bif_rbt.rbt_root, write_bif_enum);
+  fprintf (header_file, "  RS6000_BIF_MAX\n};\n\n");
+
+  fprintf (header_file, "enum restriction {\n");
+  fprintf (header_file, "  RES_NONE,\n");
+  fprintf (header_file, "  RES_BITS,\n");
+  fprintf (header_file, "  RES_RANGE,\n");
+  fprintf (header_file, "  RES_VAR_RANGE,\n");
+  fprintf (header_file, "  RES_VALUES\n");
+  fprintf (header_file, "};\n\n");
+
+  fprintf (header_file, "enum bif_enable {\n");
+  fprintf (header_file, "  ENB_ALWAYS,\n");
+  fprintf (header_file, "  ENB_P5,\n");
+  fprintf (header_file, "  ENB_P6,\n");
+  fprintf (header_file, "  ENB_ALTIVEC,\n");
+  fprintf (header_file, "  ENB_VSX,\n");
+  fprintf (header_file, "  ENB_P7,\n");
+  fprintf (header_file, "  ENB_P7_64,\n");
+  fprintf (header_file, "  ENB_P8,\n");
+  fprintf (header_file, "  ENB_P8V,\n");
+  fprintf (header_file, "  ENB_P9,\n");
+  fprintf (header_file, "  ENB_P9_64,\n");
+  fprintf (header_file, "  ENB_P9V,\n");
+  fprintf (header_file, "  ENB_IEEE128_HW,\n");
+  fprintf (header_file, "  ENB_DFP,\n");
+  fprintf (header_file, "  ENB_CRYPTO,\n");
+  fprintf (header_file, "  ENB_HTM,\n");
+  fprintf (header_file, "  ENB_P10,\n");
+  fprintf (header_file, "  ENB_MMA\n");
+  fprintf (header_file, "};\n\n");
+
+  fprintf (header_file, "struct bifdata\n");
+  fprintf (header_file, "{\n");
+  fprintf (header_file, "  const char *bifname;\n");
+  fprintf (header_file, "  bif_enable enable;\n");
+  fprintf (header_file, "  tree fntype;\n");
+  fprintf (header_file, "  insn_code icode;\n");
+  fprintf (header_file, "  int  nargs;\n");
+  fprintf (header_file, "  int  bifattrs;\n");
+  fprintf (header_file, "  int  restr_opnd[2];\n");
+  fprintf (header_file, "  restriction restr[2];\n");
+  fprintf (header_file, "  int  restr_val1[2];\n");
+  fprintf (header_file, "  int  restr_val2[2];\n");
+  fprintf (header_file, "};\n\n");
+
+  fprintf (header_file, "#define bif_init_bit\t\t(0x0001)\n");
+  fprintf (header_file, "#define bif_set_bit\t\t(0x0002)\n");
+  fprintf (header_file, "#define bif_extract_bit\t\t(0x0004)\n");
+  fprintf (header_file, "#define bif_nosoft_bit\t\t(0x0008)\n");
+  fprintf (header_file, "#define bif_ldvec_bit\t\t(0x0010)\n");
+  fprintf (header_file, "#define bif_stvec_bit\t\t(0x0020)\n");
+  fprintf (header_file, "#define bif_reve_bit\t\t(0x0040)\n");
+  fprintf (header_file, "#define bif_pred_bit\t\t(0x0080)\n");
+  fprintf (header_file, "#define bif_htm_bit\t\t(0x0100)\n");
+  fprintf (header_file, "#define bif_htmspr_bit\t\t(0x0200)\n");
+  fprintf (header_file, "#define bif_htmcr_bit\t\t(0x0400)\n");
+  fprintf (header_file, "#define bif_mma_bit\t\t(0x0800)\n");
+  fprintf (header_file, "#define bif_no32bit_bit\t\t(0x1000)\n");
+  fprintf (header_file, "#define bif_cpu_bit\t\t(0x2000)\n");
+  fprintf (header_file, "#define bif_ldstmask_bit\t(0x4000)\n");
+  fprintf (header_file, "\n");
+  fprintf (header_file,
+  "#define bif_is_init(x)\t\t((x).bifattrs & bif_init_bit)\n");
+  fprintf (header_file,
+  "#define bif_is_set(x)\t\t((x).bifattrs & bif_set_bit)\n");
+  fprintf (header_file,
+  "#define bif_is_extract(x)\t((x).bifattrs & bif_extract_bit)\n");
+  fprintf (header_file,
+  "#define bif_is_nosoft(x)\t((x).bifattrs & bif_nosoft_bit)\n");
+  fprintf (header_file,
+  "#define bif_is_ldvec(x)\t\t((x).bifattrs & bif_ldvec_bit)\n");
+  fprintf (header_file,
+  "#define bif_is_

[PATCH 23/29] rs6000: Add available-everywhere and ancient builtins

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-builtin-new.def: Add always, power5,
and power6 builtins.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 78 
 1 file changed, 78 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index 6c60177e4bb..1cb019bd4fb 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -163,6 +163,84 @@
 ; a semicolon are also treated as blank lines.
 
 
+; Builtins that have been around since time immemorial or are just
+; considered available everywhere.
+[always]
+  void __builtin_cpu_init ();
+CPU_INIT nothing {cpu}
+
+  unsigned int __builtin_cpu_is (const char *);
+CPU_IS nothing {cpu}
+
+  unsigned int __builtin_cpu_supports (const char *);
+CPU_SUPPORTS nothing {cpu}
+
+  unsigned long long __builtin_ppc_get_timebase ();
+GET_TB rs6000_get_timebase {}
+
+  double __builtin_mffs ();
+MFFS rs6000_mffs {}
+
+  unsigned long long __builtin_ppc_mftb ();
+MFTB rs6000_mftb_di {}
+
+  void __builtin_mtfsb0 (const int<5>);
+MTFSB0 rs6000_mtfsb0 {}
+
+  void __builtin_mtfsb1 (const int<5>);
+MTFSB1 rs6000_mtfsb1 {}
+
+  void __builtin_mtfsf (const int<8>, double);
+MTFSF rs6000_mtfsf {}
+
+  const __ibm128 __builtin_pack_ibm128 (double, double);
+PACK_IF packif {}
+
+  void __builtin_set_fpscr_rn (signed int);
+SET_FPSCR_RN rs6000_set_fpscr_rn {}
+
+  const double __builtin_unpack_ibm128 (__ibm128, const int<1>);
+UNPACK_IF unpackif {}
+
+
+; Builtins that have been around just about forever, but not quite.
+[power5]
+;  Not sure what to do with this one.  It is apparently another
+; name for __builtin_pack_ibm128 when long double == __ibm128.
+; There isn't a lot of sense in having pack and unpack for _Float128.
+; Inclined to deprecate, should discuss with Steve Munroe.
+;  const long double __builtin_pack_longdouble (double, double);
+;PACK_TF packtf {}
+
+  fpmath double __builtin_recipdiv (double, double);
+RECIP recipdf3 {}
+
+  fpmath float __builtin_recipdivf (float, float);
+RECIPF recipsf3 {}
+
+  fpmath double __builtin_rsqrt (double);
+RSQRT rsqrtdf2 {}
+
+  fpmath float __builtin_rsqrtf (float);
+RSQRTF rsqrtsf2 {}
+
+;  Not sure what to do with this one.  It is apparently another
+; name for __builtin_unpack_ibm128 when long double == __ibm128.
+; There isn't a lot of sense in having pack and unpack for _Float128.
+; Inclined to deprecate, should discuss with Steve Munroe.
+;  const double __builtin_unpack_longdouble (long double, const int<1>);
+;UNPACK_TF unpacktf {}
+
+
+; Power6 builtins.
+[power6]
+  const signed int __builtin_p6_cmpb (signed int, signed int);
+CMPB cmpbdi3 {}
+
+  const signed int __builtin_p6_cmpb_32 (signed int, signed int);
+CMPB_32 cmpbsi3 {}
+
+
 ; AltiVec builtins.
 [altivec]
   const vsc __builtin_altivec_abs_v16qi (vsc);
-- 
2.17.1



[PATCH 14/29] rs6000: Build and store function type identifiers

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (complete_vector_type): New
function.
(complete_base_type): Likewise.
(construct_fntype_id): Likewise.
(parse_bif_entry): Call construct_fntype_id.
(parse_ovld_entry): Likewise.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 211 
 1 file changed, 211 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 5413cc2681e..b31b666e071 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1254,6 +1254,209 @@ htmspr = %d, htmcr = %d, mma = %d, no32bit = %d, cpu = 
%d, ldstmask = %d.\n",
   return PC_OK;
 }
 
+/* Convert a vector type into a mode string.  */
+static void
+complete_vector_type (typeinfo *typeptr, char *buf, int *bufi)
+{
+  if (typeptr->isbool)
+buf[(*bufi)++] = 'b';
+  buf[(*bufi)++] = 'v';
+  if (typeptr->ispixel)
+{
+  memcpy (&buf[*bufi], "p8hi", 4);
+  *bufi += 4;
+}
+  else
+{
+  switch (typeptr->base)
+   {
+   case BT_CHAR:
+ memcpy (&buf[*bufi], "16qi", 4);
+ *bufi += 4;
+ break;
+   case BT_SHORT:
+ memcpy (&buf[*bufi], "8hi", 3);
+ *bufi += 3;
+ break;
+   case BT_INT:
+ memcpy (&buf[*bufi], "4si", 3);
+ *bufi += 3;
+ break;
+   case BT_LONGLONG:
+ memcpy (&buf[*bufi], "2di", 3);
+ *bufi += 3;
+ break;
+   case BT_FLOAT:
+ memcpy (&buf[*bufi], "4sf", 3);
+ *bufi += 3;
+ break;
+   case BT_DOUBLE:
+ memcpy (&buf[*bufi], "2df", 3);
+ *bufi += 3;
+ break;
+   case BT_INT128:
+ memcpy (&buf[*bufi], "1ti", 3);
+ *bufi += 3;
+ break;
+   case BT_FLOAT128:
+ memcpy (&buf[*bufi], "1tf", 3);
+ *bufi += 3;
+ break;
+   default:
+ (*diag) ("unhandled basetype %d.\n", typeptr->base);
+ exit (EC_INTERR);
+   }
+}
+}
+
+/* Convert a base type into a mode string.  */
+static void
+complete_base_type (typeinfo *typeptr, char *buf, int *bufi)
+{
+  switch (typeptr->base)
+{
+case BT_CHAR:
+  memcpy (&buf[*bufi], "qi", 2);
+  break;
+case BT_SHORT:
+  memcpy (&buf[*bufi], "hi", 2);
+  break;
+case BT_INT:
+  memcpy (&buf[*bufi], "si", 2);
+  break;
+case BT_LONGLONG:
+  memcpy (&buf[*bufi], "di", 2);
+  break;
+case BT_FLOAT:
+  memcpy (&buf[*bufi], "sf", 2);
+  break;
+case BT_DOUBLE:
+  memcpy (&buf[*bufi], "df", 2);
+  break;
+case BT_INT128:
+  memcpy (&buf[*bufi], "ti", 2);
+  break;
+case BT_FLOAT128:
+  memcpy (&buf[*bufi], "tf", 2);
+  break;
+case BT_DECIMAL32:
+  memcpy (&buf[*bufi], "sd", 2);
+  break;
+case BT_DECIMAL64:
+  memcpy (&buf[*bufi], "dd", 2);
+  break;
+case BT_DECIMAL128:
+  memcpy (&buf[*bufi], "td", 2);
+  break;
+case BT_IBM128:
+  memcpy (&buf[*bufi], "if", 2);
+  break;
+default:
+  (*diag) ("unhandled basetype %d.\n", typeptr->base);
+  exit (EC_INTERR);
+}
+
+  *bufi += 2;
+}
+
+/* Build a function type descriptor identifier from the return type
+   and argument types described by PROTOPTR, and store it if it does
+   not already exist.  Return the identifier.  */
+static char *
+construct_fntype_id (prototype *protoptr)
+{
+  /* Determine the maximum space for a function type descriptor id.
+ Each type requires at most 8 characters (6 for the mode*, 1 for
+ the optional 'u' preceding the mode, and 1 for an underscore
+ following the mode).  We also need 5 characters for the string
+ "ftype" that separates the return mode from the argument modes.
+ The last argument doesn't need a trailing underscore, but we
+ count that as the one trailing "ftype" instead.  For the special
+ case of zero arguments, we need 8 for the return type and 7
+ for "ftype_v".  Finally, we need one character for the
+ terminating null.  Thus for a function with N arguments, we
+ need at most 8N+14 characters for N>0, otherwise 16.
+ 
+   *Worst case is bv16qi for "vector bool char".  */
+  int len = protoptr->nargs ? (protoptr->nargs + 1) * 8 + 6 : 16;
+  char *buf = (char *) malloc (len);
+  int bufi = 0;
+
+  if (protoptr->rettype.ispointer)
+{
+  assert (protoptr->rettype.isvoid);
+  buf[bufi++] = 'p';
+}
+  if (protoptr->rettype.isvoid)
+buf[bufi++] = 'v';
+  else
+{
+  if (protoptr->rettype.isopaque)
+   {
+ memcpy (&buf[bufi], "opaque", 6);
+ bufi += 6;
+   }
+  else
+   {
+ if (protoptr->rettype.isunsigned)
+   buf[bufi++] = 'u';
+ if (protoptr->rettype.isvector)
+   complete_vector_type (&protoptr->rettype, buf, &bufi);
+ else
+   

[PATCH 22/29] rs6000: Add VSX builtins

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-builtin-new.def: Add VSX builtins.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 840 +++
 1 file changed, 840 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index 0b79f155389..6c60177e4bb 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -1020,3 +1020,843 @@
   const vss __builtin_vec_set_v8hi (vss, signed short, const int<3>);
 VEC_SET_V8HI nothing {set}
 
+
+; VSX builtins.
+[vsx]
+  pure vsq __builtin_altivec_lvx_v1ti (signed long long, void *);
+LVX_V1TI altivec_lvx_v1ti {ldvec}
+
+  pure vd __builtin_altivec_lvx_v2df (signed long long, void *);
+LVX_V2DF altivec_lvx_v2df {ldvec}
+
+  pure vsll __builtin_altivec_lvx_v2di (signed long long, void *);
+LVX_V2DI altivec_lvx_v2di {ldvec}
+
+  pure vd __builtin_altivec_lvxl_v2df (signed long long, void *);
+LVXL_V2DF altivec_lvxl_v2df {ldvec}
+
+  pure vsll __builtin_altivec_lvxl_v2di (signed long long, void *);
+LVXL_V2DI altivec_lvxl_v2di {ldvec}
+
+  const vd __builtin_altivec_nabs_v2df (vd);
+NABS_V2DF vsx_nabsv2df2 {}
+
+  const vsll __builtin_altivec_nabs_v2di (vsll);
+NABS_V2DI nabsv2di2 {}
+
+  void __builtin_altivec_stvx_v2df (vd, signed long long, void *);
+STVX_V2DF altivec_stvx_v2df {stvec}
+
+  void __builtin_altivec_stvx_v2di (vop, signed long long, void *);
+STVX_V2DI altivec_stvx_v2di {stvec}
+
+  void __builtin_altivec_stvxl_v2df (vd, signed long long, void *);
+STVXL_V2DF altivec_stvxl_v2df {stvec}
+
+  void __builtin_altivec_stvxl_v2di (vop, signed long long, void *);
+STVXL_V2DI altivec_stvxl_v2di {stvec}
+
+  const vd __builtin_altivec_vand_v2df (vd, vd);
+VAND_V2DF andv2df3 {}
+
+  const vsll __builtin_altivec_vand_v2di (vsll, vsll);
+VAND_V2DI andv2di3 {}
+
+  const vull __builtin_altivec_vand_v2di_uns (vull, vull);
+VAND_V2DI_UNS andv2di3 {}
+
+  const vd __builtin_altivec_vandc_v2df (vd, vd);
+VANDC_V2DF andcv2df3 {}
+
+  const vsll __builtin_altivec_vandc_v2di (vsll, vsll);
+VANDC_V2DI andcv2di3 {}
+
+  const vull __builtin_altivec_vandc_v2di_uns (vull, vull);
+VANDC_V2DI_UNS andcv2di3 {}
+
+  const vd __builtin_altivec_vnor_v2df (vd, vd);
+VNOR_V2DF norv2df3 {}
+
+  const vsll __builtin_altivec_vnor_v2di (vsll, vsll);
+VNOR_V2DI norv2di3 {}
+
+  const vull __builtin_altivec_vnor_v2di_uns (vull, vull);
+VNOR_V2DI_UNS norv2di3 {}
+
+  const vd __builtin_altivec_vor_v2df (vd, vd);
+VOR_V2DF iorv2df3 {}
+
+  const vsll __builtin_altivec_vor_v2di (vsll, vsll);
+VOR_V2DI iorv2di3 {}
+
+  const vull __builtin_altivec_vor_v2di_uns (vull, vull);
+VOR_V2DI_UNS iorv2di3 {}
+
+  const vd __builtin_altivec_vperm_2df (vd, vd, vuc);
+VPERM_2DF altivec_vperm_v2df {}
+
+  const vsll __builtin_altivec_vperm_2di (vsll, vsll, vuc);
+VPERM_2DI altivec_vperm_v2di {}
+
+  const vull __builtin_altivec_vperm_2di_uns (vull, vull, vuc);
+VPERM_2DI_UNS altivec_vperm_v2di_uns {}
+
+  const vd __builtin_altivec_vreve_v2df (vd);
+VREVE_V2DF altivec_vrevev2df2 {}
+
+  const vsll __builtin_altivec_vreve_v2di (vsll);
+VREVE_V2DI altivec_vrevev2di2 {}
+
+  const vd __builtin_altivec_vsel_2df (vd, vd, vop);
+VSEL_2DF vector_select_v2df {}
+
+  const vsll __builtin_altivec_vsel_2di (vsll, vsll, vsll, vbll);
+VSEL_2DI_B vector_select_v2di {}
+
+  const vull __builtin_altivec_vsel_2di_uns (vull, vull, vull);
+VSEL_2DI_UNS vector_select_v2di_uns {}
+
+  const vd __builtin_altivec_vsldoi_2df (vd, vd, const int<4>);
+VSLDOI_2DF altivec_vsldoi_v2df {}
+
+  const vsll __builtin_altivec_vsldoi_2di (vsll, vsll, const int<4>);
+VSLDOI_2DI altivec_vsldoi_v2di {}
+
+  const vd __builtin_altivec_vxor_v2df (vd, vd);
+VXOR_V2DF xorv2df3 {}
+
+  const vsll __builtin_altivec_vxor_v2di (vsll, vsll);
+VXOR_V2DI xorv2di3 {}
+
+  const vull __builtin_altivec_vxor_v2di_uns (vull, vull);
+VXOR_V2DI_UNS xorv2di3 {}
+
+  const vbc __builtin_vsx_cmpge_16qi (vsc, vsc);
+CMPGE_16QI vector_nltv16qi {}
+
+  const vbll __builtin_vsx_cmpge_2di (vsll, vsll);
+CMPGE_2DI vector_nltv2di {}
+
+  const vbi __builtin_vsx_cmpge_4si (vsi, vsi);
+CMPGE_4SI vector_nltv4si {}
+
+  const vbs __builtin_vsx_cmpge_8hi (vss, vss);
+CMPGE_8HI vector_nltv8hi {}
+
+  const vbc __builtin_vsx_cmpge_u16qi (vuc, vuc);
+CMPGE_U16QI vector_nltuv16qi {}
+
+  const vbll __builtin_vsx_cmpge_u2di (vull, vull);
+CMPGE_U2DI vector_nltuv2di {}
+
+  const vbi __builtin_vsx_cmpge_u4si (vui, vui);
+CMPGE_U4SI vector_nltuv4si {}
+
+  const vbs __builtin_vsx_cmpge_u8hi (vus, vus);
+CMPGE_U8HI vector_nltuv8hi {}
+
+  const vbc __builtin_vsx_cmple_16qi (vsc, vsc);
+CMPLE_16QI vector_ngtv16qi {}
+
+  const vbll __builtin_vsx_cmple_2di (vsll, vsll);
+CMPLE_2DI vector_ngtv2di {}
+
+  const vbi __builtin_vsx_cmple_4si (vsi, vsi);
+CMPLE

[PATCH 15/29] rs6000: Write output to the vector definition include file

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (write_defines_file):
Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index b31b666e071..67336152550 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -1896,6 +1896,10 @@ write_init_file ()
 static int
 write_defines_file ()
 {
+  for (int i = 0; i < num_ovld_stanzas; i++)
+fprintf (defines_file, "#define %s %s\n",
+ovld_stanzas[i].extern_name,
+ovld_stanzas[i].intern_name);
   return 1;
 }
 
-- 
2.17.1



[PATCH 24/29] rs6000: Add Power7 builtins

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-builtin-new.def: Add power7 and
power7-64 builtins.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 39 
 1 file changed, 39 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index 1cb019bd4fb..0a17cad446c 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -1938,3 +1938,42 @@
 XXSPLTD_V2DI vsx_xxspltd_v2di {}
 
 
+; Power7 builtins (ISA 2.06).
+[power7]
+  const unsigned int __builtin_addg6s (unsigned int, unsigned int);
+ADDG6S addg6s {}
+
+  const signed long long __builtin_bpermd (signed long long, signed long long);
+BPERMD bpermd_di {}
+
+  const unsigned int __builtin_cbcdtd (unsigned int);
+CBCDTD cbcdtd {}
+
+  const unsigned int __builtin_cdtbcd (unsigned int);
+CDTBCD cdtbcd {}
+
+  const signed int __builtin_divwe (signed int, signed int);
+DIVWE dive_si {}
+
+  const unsigned int __builtin_divweu (unsigned int, unsigned int);
+DIVWEU diveu_si {}
+
+  const vsq __builtin_pack_vector_int128 (unsigned long long, unsigned long 
long);
+PACK_V1TI packv1ti {}
+
+  void __builtin_ppc_speculation_barrier ();
+SPECBARR speculation_barrier {}
+
+  const unsigned long long __builtin_unpack_vector_int128 (vsq, const int<1>);
+UNPACK_V1TI unpackv1ti {}
+
+
+; Power7 builtins requiring 64-bit GPRs (even with 32-bit addressing).
+[power7-64]
+  const signed long long __builtin_divde (signed long long, signed long long);
+DIVDE dive_di {}
+
+  const unsigned long long __builtin_divdeu (unsigned long long, unsigned long 
long);
+DIVDEU diveu_di {}
+
+
-- 
2.17.1



[PATCH 17/29] rs6000: Write output to the builtins init file, part 1 of 3

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (write_fntype): New
function.
(write_fntype_init): New stub function.
(write_init_bif_table): Likewise.
(write_init_ovld_table): New function.
(write_init_file): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 149 
 1 file changed, 149 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index 67c7b22aad6..3ac199ff2e5 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -2055,6 +2055,18 @@ write_extern_fntype (char *str)
   fprintf (header_file, "extern tree %s;\n", str);
 }
 
+void
+write_fntype (char *str)
+{
+  fprintf (init_file, "tree %s;\n", str);
+}
+
+/* Write an initializer for a function type identified by STR.  */
+void
+write_fntype_init (char *str)
+{
+}
+
 /* Write everything to the header file (rs6000-builtins.h).  */
 static int
 write_header_file ()
@@ -2078,10 +2090,147 @@ write_header_file ()
   return 1;
 }
 
+/* Write code to initialize the built-in function table.  */
+static void
+write_init_bif_table ()
+{
+}
+
+/* Write code to initialize the overload table.  */
+static void
+write_init_ovld_table ()
+{
+  fprintf (init_file, "  int base = RS6000_BIF_MAX;\n\n");
+
+  for (int i = 0; i <= curr_ovld; i++)
+{
+  fprintf (init_file,
+  "  rs6000_overload_info[RS6000_OVLD_%s - base].bifname"
+  "\n= \"%s\";\n",
+  ovlds[i].idname, ovlds[i].proto.bifname);
+  fprintf (init_file,
+  "  rs6000_overload_info[RS6000_OVLD_%s - base].bifid"
+  "\n= RS6000_BIF_%s;\n",
+  ovlds[i].idname, ovlds[i].idname);
+  fprintf (init_file,
+  "  rs6000_overload_info[RS6000_OVLD_%s - base].fntype"
+  "\n= %s;\n",
+  ovlds[i].idname, ovlds[i].fndecl);
+  fprintf (init_file,
+  "  rs6000_overload_info[RS6000_OVLD_%s - base].next"
+  "\n= ", ovlds[i].idname);
+  if (i < curr_ovld
+ && !strcmp (ovlds[i+1].proto.bifname, ovlds[i].proto.bifname))
+   fprintf (init_file,
+"&rs6000_overload_info[RS6000_OVLD_%s - base];\n",
+ovlds[i+1].idname);
+  else
+   fprintf (init_file, "NULL;\n");
+
+  if (i == 0 || ovlds[i].stanza != ovlds[i-1].stanza)
+   {
+ fprintf (init_file, "\n");
+
+ fprintf (init_file,
+  "  ovldaddr = &rs6000_overload_info"
+  "[RS6000_OVLD_%s - base];\n",
+  ovlds[i].idname);
+ fprintf (init_file,
+  "  hash = rs6000_ovld_hasher::hash (ovldaddr);\n");
+ fprintf (init_file,
+  "  oslot = ovld_hash.find_slot_with_hash (\n");
+ fprintf (init_file,
+  "\"%s\", hash, INSERT\n",
+  ovlds[i].proto.bifname);
+ fprintf (init_file,
+  " );\n");
+ fprintf (init_file,
+  "  *oslot = ovldaddr;\n");
+   }
+
+  if (i < curr_ovld)
+   fprintf (init_file, "\n");
+}
+}
+
 /* Write everything to the initialization file (rs6000-builtins.c).  */
 static int
 write_init_file ()
 {
+  write_autogenerated_header (init_file);
+
+  fprintf (init_file, "#include \"config.h\"\n");
+  fprintf (init_file, "#include \"system.h\"\n");
+  fprintf (init_file, "#include \"coretypes.h\"\n");
+  fprintf (init_file, "#include \"backend.h\"\n");
+  fprintf (init_file, "#include \"rtl.h\"\n");
+  fprintf (init_file, "#include \"tree.h\"\n");
+  fprintf (init_file, "#include \"langhooks.h\"\n");
+  fprintf (init_file, "#include \"insn-codes.h\"\n");
+  fprintf (init_file, "#include \"rs6000-builtins.h\"\n");
+  fprintf (init_file, "\n");
+
+#ifdef DEBUG_NEW_BUILTINS
+  fprintf (init_file, "int new_builtins_are_live = 1;\n\n");
+#else
+  fprintf (init_file, "int new_builtins_are_live = 0;\n\n");
+#endif
+
+  fprintf (init_file,
+  "bifdata rs6000_builtin_info_x[RS6000_BIF_MAX];\n\n");
+  fprintf (init_file,
+  "ovlddata rs6000_overload_info[RS6000_OVLD_MAX"
+  " - RS6000_BIF_MAX];\n\n");
+
+  rbt_inorder_callback (&fntype_rbt, fntype_rbt.rbt_root, write_fntype);
+  fprintf (init_file, "\n");
+
+  fprintf (init_file, "hashval_t\n");
+  fprintf (init_file, "rs6000_bif_hasher::hash (bifdata *bd)\n");
+  fprintf (init_file, "{\n");
+  fprintf (init_file, "  return htab_hash_string (bd->bifname);\n");
+  fprintf (init_file, "}\n\n");
+
+  fprintf (init_file, "bool\n");
+  fprintf (init_file,
+  "rs6000_bif_hasher::equal (bifdata *bd, const char *name)\n");
+  fprintf (init_file, "{\n");
+  fprintf (init_file, "  return bd && name && !strcmp (bd->bifname, name);\n");
+  fprintf (init_file, "}\n\n");
+
+  fprintf (init_file, "hash_table bif_hash (1024);\n\n");
+
+  fprintf (init_file, 

[PATCH 13/29] rs6000: Parsing of overload input file

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-gen-builtins.c (ovld_stanza): New struct.
(MAXOVLDSTANZAS): New defined constant.
(ovld_stanzas): New filescope variable.
(curr_ovld_stanza): Likewise.
(MAXOVLDS): New defined constant.
(ovlddata): New struct.
(ovlds): New filescope variable.
(curr_ovld): Likewise.
(parse_ovld_entry): New function.
(parse_ovld_stanza): Likewise.
(parse_ovld): Implement.
---
 gcc/config/rs6000/rs6000-gen-builtins.c | 202 +++-
 1 file changed, 201 insertions(+), 1 deletion(-)

diff --git a/gcc/config/rs6000/rs6000-gen-builtins.c 
b/gcc/config/rs6000/rs6000-gen-builtins.c
index c4bc5c724a3..5413cc2681e 100644
--- a/gcc/config/rs6000/rs6000-gen-builtins.c
+++ b/gcc/config/rs6000/rs6000-gen-builtins.c
@@ -360,8 +360,31 @@ struct bifdata {
 static bifdata bifs[MAXBIFS];
 static int num_bifs;
 static int curr_bif;
+
+/* Stanzas are groupings of built-in functions and overloads by some
+   common feature/attribute.  These definitions are for overload stanzas.  */
+struct ovld_stanza {
+  char *stanza_id;
+  char *extern_name;
+  char *intern_name;
+};
+
+#define MAXOVLDSTANZAS 256
+static ovld_stanza ovld_stanzas[MAXOVLDSTANZAS];
 static int num_ovld_stanzas;
+static int curr_ovld_stanza;
+
+#define MAXOVLDS 16384
+struct ovlddata {
+  int stanza;
+  prototype proto;
+  char *idname;
+  char *fndecl;
+};
+
+static ovlddata ovlds[MAXOVLDS];
 static int num_ovlds;
+static int curr_ovld;
 
 /* Exit codes for the shell.  */
 enum exit_codes {
@@ -1460,11 +1483,188 @@ parse_bif ()
   return result;
 }
 
+/* Parse one two-line entry in the overload file.  */
+static parse_codes
+parse_ovld_entry ()
+{
+  /* Check for end of stanza.  */
+  pos = 0;
+  consume_whitespace ();
+  if (linebuf[pos] == '[')
+return PC_EOSTANZA;
+
+  /* Allocate an entry in the overload table.  */
+  if (num_ovlds >= MAXOVLDS - 1)
+{
+  (*diag) ("too many overloads.\n");
+  return PC_PARSEFAIL;
+}
+
+  curr_ovld = num_ovlds++;
+  ovlds[curr_ovld].stanza = curr_ovld_stanza;
+
+  if (parse_prototype (&ovlds[curr_ovld].proto) == PC_PARSEFAIL)
+return PC_PARSEFAIL;
+
+  /* Now process line 2, which just contains the builtin id.  */
+  if (!advance_line (ovld_file))
+{
+  (*diag) ("unexpected EOF.\n");
+  return PC_EOFILE;
+}
+
+  pos = 0;
+  consume_whitespace ();
+  int oldpos = pos;
+  char *id = match_identifier ();
+  ovlds[curr_ovld].idname = id;
+  if (!id)
+{
+  (*diag) ("missing overload id at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+
+#ifdef DEBUG
+  (*diag) ("ID name is '%s'.\n", id);
+#endif
+
+  /* The builtin id has to match one from the bif file.  */
+  if (!rbt_find (&bif_rbt, id))
+{
+  (*diag) ("builtin ID '%s' not found in bif file.\n", id);
+  return PC_PARSEFAIL;
+}
+
+  /* Save the ID in a lookup structure.  */
+  if (!rbt_insert (&ovld_rbt, id))
+{
+  (*diag) ("duplicate function ID '%s' at column %d.\n", id, oldpos + 1);
+  return PC_PARSEFAIL;
+}
+
+  consume_whitespace ();
+  if (linebuf[pos] != '\n')
+{
+  (*diag) ("garbage at end of line at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  return PC_OK;
+}
+
+/* Parse one stanza of the input overload file.  linebuf already contains the
+   first line to parse.  */
+static parse_codes
+parse_ovld_stanza ()
+{
+  /* Parse the stanza header.  */
+  pos = 0;
+  consume_whitespace ();
+
+  if (linebuf[pos] != '[')
+{
+  (*diag) ("ill-formed stanza header at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  safe_inc_pos ();
+
+  char *stanza_name = match_identifier ();
+  if (!stanza_name)
+{
+  (*diag) ("no identifier found in stanza header.\n");
+  return PC_PARSEFAIL;
+}
+
+  /* Add the identifier to a table and set the number to be recorded
+ with subsequent overload entries.  */
+  if (num_ovld_stanzas >= MAXOVLDSTANZAS)
+{
+  (*diag) ("too many stanza headers.\n");
+  return PC_PARSEFAIL;
+}
+
+  curr_ovld_stanza = num_ovld_stanzas++;
+  ovld_stanza *stanza = &ovld_stanzas[curr_ovld_stanza];
+  stanza->stanza_id = stanza_name;
+
+  consume_whitespace ();
+  if (linebuf[pos] != ',')
+{
+  (*diag) ("missing comma at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  safe_inc_pos ();
+
+  consume_whitespace ();
+  stanza->extern_name = match_identifier ();
+  if (!stanza->extern_name)
+{
+  (*diag) ("missing external name at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+
+  consume_whitespace ();
+  if (linebuf[pos] != ',')
+{
+  (*diag) ("missing comma at column %d.\n", pos + 1);
+  return PC_PARSEFAIL;
+}
+  safe_inc_pos ();
+
+  consume_whitespace ();
+  stanza->intern_name = match_identifier ();
+  if (!stanza->intern_name)
+{
+  (*diag) ("missing internal name at column

[PATCH 20/29] rs6000: Incorporate new builtins code into the build machinery

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config.gcc (powerpc*-*-*): Add rs6000-builtins.o to extra_objs.
* config/rs6000/t-rs6000 (rs6000-gen-builtins.o): New target.
(rbtree.o): Likewise.
(rs6000-gen-builtins): Likewise.
(rs6000-builtins.c): Likewise.
(rs6000-builtins.o): Likewise.
(rs6000-call.o): Add dependency on rs6000-builtins.c.
---
 gcc/config.gcc |  3 ++-
 gcc/config/rs6000/t-rs6000 | 25 -
 2 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 30b51c3dc81..b6aa0c2d15d 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -505,7 +505,8 @@ or1k*-*-*)
;;
 powerpc*-*-*)
cpu_type=rs6000
-   extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o 
rs6000-call.o"
+   extra_objs="rs6000-string.o rs6000-p8swap.o rs6000-logue.o"
+   extra_objs="${extra_objs} rs6000-call.o rs6000-builtins.o"
extra_headers="ppc-asm.h altivec.h htmintrin.h htmxlintrin.h"
extra_headers="${extra_headers} bmi2intrin.h bmiintrin.h"
extra_headers="${extra_headers} xmmintrin.h mm_malloc.h emmintrin.h"
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index 1ddb5729cb2..6053721f76c 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -43,7 +43,30 @@ rs6000-logue.o: $(srcdir)/config/rs6000/rs6000-logue.c
$(COMPILE) $<
$(POSTCOMPILE)
 
-rs6000-call.o: $(srcdir)/config/rs6000/rs6000-call.c
+rs6000-gen-builtins.o: $(srcdir)/config/rs6000/rs6000-gen-builtins.c
+   $(COMPILE) $<
+   $(POSTCOMPILE)
+
+rbtree.o: $(srcdir)/config/rs6000/rbtree.c
+   $(COMPILE) $<
+   $(POSTCOMPILE)
+
+rs6000-gen-builtins: rs6000-gen-builtins.o rbtree.o
+   +$(LINKER_FOR_BUILD) $(BUILD_LINKERFLAGS) $(BUILD_LDFLAGS) -o $@ \
+   $(filter-out $(BUILD_LIBDEPS), $^) $(BUILD_LIBS)
+
+rs6000-builtins.c: rs6000-gen-builtins \
+  $(srcdir)/config/rs6000/rs6000-builtin-new.def \
+  $(srcdir)/config/rs6000/rs6000-overload.def
+   ./rs6000-gen-builtins $(srcdir)/config/rs6000/rs6000-builtin-new.def \
+   $(srcdir)/config/rs6000/rs6000-overload.def rs6000-builtins.h \
+   rs6000-builtins.c rs6000-vecdefines.h
+
+rs6000-builtins.o: rs6000-builtins.c
+   $(COMPILE) $<
+   $(POSTCOMPILE)
+
+rs6000-call.o: $(srcdir)/config/rs6000/rs6000-call.c rs6000-builtins.c
$(COMPILE) $<
$(POSTCOMPILE)
 
-- 
2.17.1



[PATCH 21/29] rs6000: Add remaining AltiVec builtins

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-builtin-new.def: Add remaining AltiVec
builtins.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 843 +++
 1 file changed, 843 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index 5fc7e1301c3..0b79f155389 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -177,3 +177,846 @@
   const vss __builtin_altivec_abs_v8hi (vss);
 ABS_V8HI absv8hi2 {}
 
+  const vsc __builtin_altivec_abss_v16qi (vsc);
+ABSS_V16QI altivec_abss_v16qi {}
+
+  const vsi __builtin_altivec_abss_v4si (vsi);
+ABSS_V4SI altivec_abss_v4si {}
+
+  const vss __builtin_altivec_abss_v8hi (vss);
+ABSS_V8HI altivec_abss_v8hi {}
+
+  const vf __builtin_altivec_copysignfp (vf, vf);
+COPYSIGN_V4SF vector_copysignv4sf3 {}
+
+  void __builtin_altivec_dss (const int<2>);
+DSS altivec_dss {}
+
+  void __builtin_altivec_dssall ();
+DSSALL altivec_dssall {}
+
+  void __builtin_altivec_dst (void *, const int, const int<2>);
+DST altivec_dst {}
+
+  void __builtin_altivec_dstst (void *, const int, const int<2>);
+DSTST altivec_dstst {}
+
+  void __builtin_altivec_dststt (void *, const int, const int<2>);
+DSTSTT altivec_dststt {}
+
+  void __builtin_altivec_dstt (void *, const int, const int<2>);
+DSTT altivec_dstt {}
+
+  fpmath vsi __builtin_altivec_fix_sfsi (vf);
+FIX_V4SF_V4SI fix_truncv4sfv4si2 {}
+
+  fpmath vui __builtin_altivec_fixuns_sfsi (vf);
+FIXUNS_V4SF_V4SI fixuns_truncv4sfv4si2 {}
+
+  fpmath vf __builtin_altivec_float_sisf (vsi);
+FLOAT_V4SI_V4SF floatv4siv4sf2 {}
+
+  pure vop __builtin_altivec_lvebx (signed long long, void *);
+LVEBX altivec_lvebx {ldvec}
+
+  pure vop __builtin_altivec_lvehx (signed long long, void *);
+LVEHX altivec_lvehx {ldvec}
+
+  pure vop __builtin_altivec_lvewx (signed long long, void *);
+LVEWX altivec_lvewx {ldvec}
+
+  pure vop __builtin_altivec_lvlx (signed long long, void *);
+LVLX altivec_lvlx {ldvec}
+
+  pure vop __builtin_altivec_lvlxl (signed long long, void *);
+LVLXL altivec_lvlxl {ldvec}
+
+  pure vop __builtin_altivec_lvrx (signed long long, void *);
+LVRX altivec_lvrx {ldvec}
+
+  pure vop __builtin_altivec_lvrxl (signed long long, void *);
+LVRXL altivec_lvrxl {ldvec}
+
+  pure vuc __builtin_altivec_lvsl (signed long long, void *);
+LVSL altivec_lvsl {ldvec}
+
+  pure vuc __builtin_altivec_lvsr (signed long long, void *);
+LVSR altivec_lvsr {ldvec}
+
+; Following LVX one is redundant, and I don't think we need to
+; keep it.  It only maps to LVX_V4SI.  Probably remove.
+  pure vop __builtin_altivec_lvx (signed long long, void *);
+LVX altivec_lvx_v4si {ldvec}
+
+  pure vsc __builtin_altivec_lvx_v16qi (signed long long, void *);
+LVX_V16QI altivec_lvx_v16qi {ldvec}
+
+  pure vf __builtin_altivec_lvx_v4sf (signed long long, void *);
+LVX_V4SF altivec_lvx_v4sf {ldvec}
+
+  pure vsi __builtin_altivec_lvx_v4si (signed long long, void *);
+LVX_V4SI altivec_lvx_v4si {ldvec}
+
+  pure vss __builtin_altivec_lvx_v8hi (signed long long, void *);
+LVX_V8HI altivec_lvx_v8hi {ldvec}
+
+  pure vsi __builtin_altivec_lvxl (signed long long, signed int *);
+LVXL altivec_lvxl_v4si {ldvec}
+
+  pure vsc __builtin_altivec_lvxl_v16qi (signed long long, void *);
+LVXL_V16QI altivec_lvxl_v16qi {ldvec}
+
+  pure vf __builtin_altivec_lvxl_v4sf (signed long long, void *);
+LVXL_V4SF altivec_lvxl_v4sf {ldvec}
+
+  pure vsi __builtin_altivec_lvxl_v4si (signed long long, void *);
+LVXL_V4SI altivec_lvxl_v4si {ldvec}
+
+  pure vss __builtin_altivec_lvxl_v8hi (signed long long, void *);
+LVXL_V8HI altivec_lvxl_v8hi {ldvec}
+
+  vuc __builtin_altivec_mask_for_load (long long, void *);
+MASK_FOR_LOAD altivec_lvsr_direct {ldstmask}
+
+  vuc __builtin_altivec_mask_for_store (long long, void *);
+MASK_FOR_STORE altivec_lvsr_direct {ldstmask}
+
+  vus __builtin_altivec_mfvscr ();
+MFVSCR altivec_mfvscr {}
+
+  void __builtin_altivec_mtvscr (vop);
+MTVSCR altivec_mtvscr {}
+
+  const vsc __builtin_altivec_nabs_v16qi (vsc);
+NABS_V16QI nabsv16qi2 {}
+
+  const vf __builtin_altivec_nabs_v4sf (vf);
+NABS_V4SF vsx_nabsv4sf2 {}
+
+  const vsi __builtin_altivec_nabs_v4si (vsi);
+NABS_V4SI nabsv4si2 {}
+
+  const vss __builtin_altivec_nabs_v8hi (vss);
+NABS_V8HI nabsv8hi2 {}
+
+  void __builtin_altivec_stvebx (vuc, signed long long, void *);
+STVEBX altivec_stvebx {stvec}
+
+  void __builtin_altivec_stvehx (vss, signed long long, void *);
+STVEHX_VSS altivec_stvehx {stvec}
+
+  void __builtin_altivec_stvewx (vsi, signed long long, void *);
+STVEWX altivec_stvewx {stvec}
+
+  void __builtin_altivec_stvlx (vop, signed long long, void *);
+STVLX altivec_stvlx {stvec}
+
+  void __builtin_altivec_stvlxl (vop, signed long long, void *);
+STVLXL altiv

[PATCH 26/29] rs6000: Add Power9 builtins

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-builtin-new.def: Add power9,
power9-vector, and power9-64 builtins.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 354 +++
 1 file changed, 354 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index 2f918c1d69e..1338f543a6a 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -2394,3 +2394,357 @@
 XSCVSPDPN vsx_xscvspdpn {}
 
 
+; Power9 vector builtins.
+[power9-vector]
+  const vus __builtin_altivec_convert_4f32_8i16 (vf, vf);
+CONVERT_4F32_8I16 convert_4f32_8i16 {}
+
+  const unsigned int __builtin_altivec_first_match_index_v16qi (vsc, vsc);
+VFIRSTMATCHINDEX_V16QI first_match_index_v16qi {}
+
+  const unsigned int __builtin_altivec_first_match_index_v8hi (vss, vss);
+VFIRSTMATCHINDEX_V8HI first_match_index_v8hi {}
+
+  const unsigned int __builtin_altivec_first_match_index_v4si (vsi, vsi);
+VFIRSTMATCHINDEX_V4SI first_match_index_v4si {}
+
+  const unsigned int __builtin_altivec_first_match_or_eos_index_v16qi (vsc, 
vsc);
+VFIRSTMATCHOREOSINDEX_V16QI first_match_or_eos_index_v16qi {}
+
+  const unsigned int __builtin_altivec_first_match_or_eos_index_v8hi (vss, 
vss);
+VFIRSTMATCHOREOSINDEX_V8HI first_match_or_eos_index_v8hi {}
+
+  const unsigned int __builtin_altivec_first_match_or_eos_index_v4si (vsi, 
vsi);
+VFIRSTMATCHOREOSINDEX_V4SI first_match_or_eos_index_v4si {}
+
+  const unsigned int __builtin_altivec_first_mismatch_index_v16qi (vsc, vsc);
+VFIRSTMISMATCHINDEX_V16QI first_mismatch_index_v16qi {}
+
+  const unsigned int __builtin_altivec_first_mismatch_index_v8hi (vss, vss);
+VFIRSTMISMATCHINDEX_V8HI first_mismatch_index_v8hi {}
+
+  const unsigned int __builtin_altivec_first_mismatch_index_v4si (vsi, vsi);
+VFIRSTMISMATCHINDEX_V4SI first_mismatch_index_v4si {}
+
+  const unsigned int __builtin_altivec_first_mismatch_or_eos_index_v16qi (vsc, 
vsc);
+VFIRSTMISMATCHOREOSINDEX_V16QI first_mismatch_or_eos_index_v16qi {}
+
+  const unsigned int __builtin_altivec_first_mismatch_or_eos_index_v8hi (vss, 
vss);
+VFIRSTMISMATCHOREOSINDEX_V8HI first_mismatch_or_eos_index_v8hi {}
+
+  const unsigned int __builtin_altivec_first_mismatch_or_eos_index_v4si (vsi, 
vsi);
+VFIRSTMISMATCHOREOSINDEX_V4SI first_mismatch_or_eos_index_v4si {}
+
+  const vuc __builtin_altivec_vadub (vuc, vuc);
+VADUB vaduv16qi3 {}
+
+  const vus __builtin_altivec_vaduh (vus, vus);
+VADUH vaduv8hi3 {}
+
+  const vui __builtin_altivec_vaduw (vui, vui);
+VADUW vaduv4si3 {}
+
+  const vull __builtin_altivec_vbpermd (vull, vuc);
+VBPERMD altivec_vbpermd {}
+
+  const signed int __builtin_altivec_vclzlsbb_v16qi (vsc);
+VCLZLSBB_V16QI vclzlsbb_v16qi {}
+
+  const signed int __builtin_altivec_vclzlsbb_v4si (vsi);
+VCLZLSBB_V4SI vclzlsbb_v4si {}
+
+  const signed int __builtin_altivec_vclzlsbb_v8hi (vss);
+VCLZLSBB_V8HI vclzlsbb_v8hi {}
+
+  const vsc __builtin_altivec_vctzb (vsc);
+VCTZB ctzv16qi2 {}
+
+  const vsll __builtin_altivec_vctzd (vsll);
+VCTZD ctzv2di2 {}
+
+  const vss __builtin_altivec_vctzh (vss);
+VCTZH ctzv8hi2 {}
+
+  const vsi __builtin_altivec_vctzw (vsi);
+VCTZW ctzv4si2 {}
+
+  const signed int __builtin_altivec_vctzlsbb_v16qi (vsc);
+VCTZLSBB_V16QI vctzlsbb_v16qi {}
+
+  const signed int __builtin_altivec_vctzlsbb_v4si (vsi);
+VCTZLSBB_V4SI vctzlsbb_v4si {}
+
+  const signed int __builtin_altivec_vctzlsbb_v8hi (vss);
+VCTZLSBB_V8HI vctzlsbb_v8hi {}
+
+  const signed int __builtin_altivec_vcmpaeb_p (vsc, vsc);
+VCMPAEB_P vector_ae_v16qi_p {pred}
+
+  const signed int __builtin_altivec_vcmpaed_p (vsll, vsll);
+VCMPAED_P vector_ae_v2di_p {pred}
+
+  const signed int __builtin_altivec_vcmpaedp_p (vd, vd);
+VCMPAEDP_P vector_ae_v2df_p {pred}
+
+  const signed int __builtin_altivec_vcmpaefp_p (vf, vf);
+VCMPAEFP_P vector_ae_v4sf_p {pred}
+
+  const signed int __builtin_altivec_vcmpaeh_p (vss, vss);
+VCMPAEH_P vector_ae_v8hi_p {pred}
+
+  const signed int __builtin_altivec_vcmpaew_p (vsi, vsi);
+VCMPAEW_P vector_ae_v4si_p {pred}
+
+  const vbc __builtin_altivec_vcmpneb (vsc, vsc);
+CMPNEB vcmpneb {}
+
+  const signed int __builtin_altivec_vcmpneb_p (vsc, vsc);
+VCMPNEB_P vector_ne_v16qi_p {pred}
+
+  const signed int __builtin_altivec_vcmpned_p (vsll, vsll);
+VCMPNED_P vector_ne_v2di_p {pred}
+
+  const signed int __builtin_altivec_vcmpnedp_p (vd, vd);
+VCMPNEDP_P vector_ne_v2df_p {pred}
+
+  const signed int __builtin_altivec_vcmpnefp_p (vf, vf);
+VCMPNEFP_P vector_ne_v4sf_p {pred}
+
+  const vbs __builtin_altivec_vcmpneh (vss, vss);
+CMPNEH vcmpneh {}
+
+  const signed int __builtin_altivec_vcmpneh_p (vss, vss);
+VCMPNEH_P vector_ne_v8hi_p {pred}
+
+  const vbi __builtin_altivec_vcmpnew (vsi, vsi);
+CMPNEW vcmpnew {}
+
+  const signed int _

[PATCH 25/29] rs6000: Add Power8 vector builtins

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-builtin-new.def: Add power8-vector
builtins.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 417 +++
 1 file changed, 417 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index 0a17cad446c..2f918c1d69e 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -1977,3 +1977,420 @@
 DIVDEU diveu_di {}
 
 
+; Power8 vector built-ins.
+[power8-vector]
+  const vsll __builtin_altivec_abs_v2di (vsll);
+ABS_V2DI absv2di2 {}
+
+  const vsc __builtin_altivec_eqv_v16qi (vsc, vsc);
+EQV_V16QI eqvv16qi3 {}
+
+  const vuc __builtin_altivec_eqv_v16qi_uns (vuc, vuc);
+EQV_V16QI_UNS eqvv16qi3 {}
+
+  const vsq __builtin_altivec_eqv_v1ti (vsq, vsq);
+EQV_V1TI eqvv1ti3 {}
+
+  const vuq __builtin_altivec_eqv_v1ti_uns (vuq, vuq);
+EQV_V1TI_UNS eqvv1ti3 {}
+
+  const vd __builtin_altivec_eqv_v2df (vd, vd);
+EQV_V2DF eqvv2df3 {}
+
+  const vsll __builtin_altivec_eqv_v2di (vsll, vsll);
+EQV_V2DI eqvv2di3 {}
+
+  const vull __builtin_altivec_eqv_v2di_uns (vull, vull);
+EQV_V2DI_UNS eqvv2di3 {}
+
+  const vf __builtin_altivec_eqv_v4sf (vf, vf);
+EQV_V4SF eqvv4sf3 {}
+
+  const vsi __builtin_altivec_eqv_v4si (vsi, vsi);
+EQV_V4SI eqvv4si3 {}
+
+  const vui __builtin_altivec_eqv_v4si_uns (vui, vui);
+EQV_V4SI_UNS eqvv4si3 {}
+
+  const vss __builtin_altivec_eqv_v8hi (vss, vss);
+EQV_V8HI eqvv8hi3 {}
+
+  const vus __builtin_altivec_eqv_v8hi_uns (vus, vus);
+EQV_V8HI_UNS eqvv8hi3 {}
+
+  const vsc __builtin_altivec_nand_v16qi (vsc, vsc);
+NAND_V16QI nandv16qi3 {}
+
+  const vuc __builtin_altivec_nand_v16qi_uns (vuc, vuc);
+NAND_V16QI_UNS nandv16qi3 {}
+
+  const vsq __builtin_altivec_nand_v1ti (vsq, vsq);
+NAND_V1TI nandv1ti3 {}
+
+  const vuq __builtin_altivec_nand_v1ti_uns (vuq, vuq);
+NAND_V1TI_UNS nandv1ti3 {}
+
+  const vd __builtin_altivec_nand_v2df (vd, vd);
+NAND_V2DF nandv2df3 {}
+
+  const vsll __builtin_altivec_nand_v2di (vsll, vsll);
+NAND_V2DI nandv2di3 {}
+
+  const vull __builtin_altivec_nand_v2di_uns (vull, vull);
+NAND_V2DI_UNS nandv2di3 {}
+
+  const vf __builtin_altivec_nand_v4sf (vf, vf);
+NAND_V4SF nandv4sf3 {}
+
+  const vsi __builtin_altivec_nand_v4si (vsi, vsi);
+NAND_V4SI nandv4si3 {}
+
+  const vui __builtin_altivec_nand_v4si_uns (vui, vui);
+NAND_V4SI_UNS nandv4si3 {}
+
+  const vss __builtin_altivec_nand_v8hi (vss, vss);
+NAND_V8HI nandv8hi3 {}
+
+  const vus __builtin_altivec_nand_v8hi_uns (vus, vus);
+NAND_V8HI_UNS nandv8hi3 {}
+
+  const vsc __builtin_altivec_neg_v16qi (vsc);
+NEG_V16QI negv16qi2 {}
+
+  const vd __builtin_altivec_neg_v2df (vd);
+NEG_V2DF negv2df2 {}
+
+  const vsll __builtin_altivec_neg_v2di (vsll);
+NEG_V2DI negv2di2 {}
+
+  const vf __builtin_altivec_neg_v4sf (vf);
+NEG_V4SF negv4sf2 {}
+
+  const vsi __builtin_altivec_neg_v4si (vsi);
+NEG_V4SI negv4si2 {}
+
+  const vss __builtin_altivec_neg_v8hi (vss);
+NEG_V8HI negv8hi2 {}
+
+  const vsc __builtin_altivec_orc_v16qi (vsc, vsc);
+ORC_V16QI orcv16qi3 {}
+
+  const vuc __builtin_altivec_orc_v16qi_uns (vuc, vuc);
+ORC_V16QI_UNS orcv16qi3 {}
+
+  const vsq __builtin_altivec_orc_v1ti (vsq, vsq);
+ORC_V1TI orcv1ti3 {}
+
+  const vuq __builtin_altivec_orc_v1ti_uns (vuq, vuq);
+ORC_V1TI_UNS orcv1ti3 {}
+
+  const vd __builtin_altivec_orc_v2df (vd, vd);
+ORC_V2DF orcv2df3 {}
+
+  const vsll __builtin_altivec_orc_v2di (vsll, vsll);
+ORC_V2DI orcv2di3 {}
+
+  const vull __builtin_altivec_orc_v2di_uns (vull, vull);
+ORC_V2DI_UNS orcv2di3 {}
+
+  const vf __builtin_altivec_orc_v4sf (vf, vf);
+ORC_V4SF orcv4sf3 {}
+
+  const vsi __builtin_altivec_orc_v4si (vsi, vsi);
+ORC_V4SI orcv4si3 {}
+
+  const vui __builtin_altivec_orc_v4si_uns (vui, vui);
+ORC_V4SI_UNS orcv4si3 {}
+
+  const vss __builtin_altivec_orc_v8hi (vss, vss);
+ORC_V8HI orcv8hi3 {}
+
+  const vus __builtin_altivec_orc_v8hi_uns (vus, vus);
+ORC_V8HI_UNS orcv8hi3 {}
+
+  const vsc __builtin_altivec_vclzb (vsc);
+VCLZB clzv16qi2 {}
+
+  const vsll __builtin_altivec_vclzd (vsll);
+VCLZD clzv2di2 {}
+
+  const vss __builtin_altivec_vclzh (vss);
+VCLZH clzv8hi2 {}
+
+  const vsi __builtin_altivec_vclzw (vsi);
+VCLZW clzv4si2 {}
+
+  const vsc __builtin_altivec_vgbbd (vsc);
+VGBBD p8v_vgbbd {}
+
+  const vsq __builtin_altivec_vaddcuq (vsq, vsq);
+VADDCUQ altivec_vaddcuq {}
+
+  const vsq __builtin_altivec_vaddecuq (vsq, vsq, vsq);
+VADDECUQ altivec_vaddecuq {}
+
+  const vuq __builtin_altivec_vaddeuqm (vuq, vuq, vuq);
+VADDEUQM altivec_vaddeuqm {}
+
+  const vsll __builtin_altivec_vaddudm (vsll, vsll);
+VADDUDM addv2di3 {}
+
+  const vsq __builtin_altivec_vadduqm (vsq, vsq);
+VADDUQM altivec_vadduqm {}
+
+  const vsll __builtin_altivec_vbpermq (vop, vsc);
+VB

[PATCH 27/29] rs6000: Add remaining builtins

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-builtin-new.def: Add ieee128-hw, dfp,
crypto, and htm builtins.
---
 gcc/config/rs6000/rs6000-builtin-new.def | 217 +++
 1 file changed, 217 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin-new.def 
b/gcc/config/rs6000/rs6000-builtin-new.def
index 1338f543a6a..ce2e3c2476b 100644
--- a/gcc/config/rs6000/rs6000-builtin-new.def
+++ b/gcc/config/rs6000/rs6000-builtin-new.def
@@ -2748,3 +2748,220 @@
 XL_LEN_R xl_len_r {}
 
 
+; Builtins requiring hardware support for IEEE-128 floating-point.
+[ieee128-hw]
+  fpmath _Float128 __builtin_vsx_addf128_round_to_odd (_Float128, _Float128);
+ADDF128_ODD addkf3_odd {}
+
+  fpmath _Float128 __builtin_vsx_divf128_round_to_odd (_Float128, _Float128);
+DIVF128_ODD divkf3_odd {}
+
+  fpmath _Float128 __builtin_vsx_fmaf128_round_to_odd (_Float128, _Float128, 
_Float128);
+FMAF128_ODD fmakf4_odd {}
+
+  fpmath _Float128 __builtin_vsx_mulf128_round_to_odd (_Float128, _Float128);
+MULF128_ODD mulkf3_odd {}
+
+  const unsigned long long __builtin_vsx_scalar_extract_expq (_Float128);
+VSEEQP xsxexpqp_kf {}
+
+  const unsigned __int128 __builtin_vsx_scalar_extract_sigq (_Float128);
+VSESQP xsxsigqp_kf {}
+
+  const signed int __buiiltin_vsx_scalar_cmp_exp_qp_eq (_Float128, _Float128);
+VSCEQPEQ xscmpexpqp_eq_kf {}
+
+  const signed int __builtin_vsx_scalar_cmp_exp_qp_gt (_Float128, _Float128);
+VSCEQPGT xscmpexpqp_gt_kf {}
+
+  const signed int __builtin_vsx_scalar_cmp_exp_qp_lt (_Float128, _Float128);
+VSCEQPLT xscmpexpqp_lt_kf {}
+
+  const signed int __builtin_vsx_scalar_cmp_exp_qp_unordered (_Float128, 
_Float128);
+VSCEQPUO xscmpexpqp_unordered_kf {}
+
+  const _Float128 __builtin_vsx_scalar_insert_exp_q (unsigned __int128, 
unsigned long long);
+VSIEQP xsiexpqp_kf {}
+
+  const _Float128 __builtin_vsx_scalar_insert_exp_qp (_Float128, unsigned long 
long);
+VSIEQPF xsiexpqpf_kf {}
+
+  const unsigned int __builtin_vsx_scalar_test_data_class_qp (_Float128, 
signed int);
+VSTDCQP xststdcqp_kf {}
+
+  const unsigned int __builtin_vsx_scalar_test_neg_qp (_Float128);
+VSTDCNQP xststdcnegqp_kf {}
+
+  fpmath _Float128 __builtin_vsx_sqrtf128_round_to_odd (_Float128);
+SQRTF128_ODD sqrtkf2_odd {}
+
+  fpmath _Float128 __builtin_vsx_subf128_round_to_odd (_Float128, _Float128);
+SUBF128_ODD subkf3_odd {}
+
+  fpmath double __builtin_vsx_truncf128_round_to_odd (_Float128);
+TRUNCF128_ODD trunckfdf2_odd {}
+
+
+
+; Decimal floating-point builtins.
+[dfp]
+  const _Decimal64 __builtin_ddedpd (const int<0,2>, _Decimal64);
+DDEDPD dfp_ddedpd_dd {}
+
+  const _Decimal128 __builtin_ddedpdq (const int<0,2>, _Decimal128);
+DDEDPDQ dfp_ddedpd_td {}
+
+  const _Decimal64 __builtin_denbcd (const int<1>, _Decimal64);
+DENBCD dfp_denbcd_dd {}
+
+  const _Decimal128 __builtin_denbcdq (const int<1>, _Decimal128);
+DENBCDQ dfp_denbcd_td {}
+
+  const _Decimal64 __builtin_diex (signed long long, _Decimal64);
+DIEX dfp_diex_dd {}
+
+  const _Decimal128 __builtin_diexq (signed long long, _Decimal128);
+DIEXQ dfp_diex_td {}
+
+  const _Decimal64 __builtin_dscli (_Decimal64, const int<6>);
+DSCLI dfp_dscli_dd {}
+
+  const _Decimal128 __builtin_dscliq (_Decimal128, const int<6>);
+DSCLIQ dfp_dscli_td {}
+
+  const _Decimal64 __builtin_dscri (_Decimal64, const int<6>);
+DSCRI dfp_dscri_dd {}
+
+  const _Decimal128 __builtin_dscriq (_Decimal128, const int<6>);
+DSCRIQ dfp_dscri_td {}
+
+  const signed long long __builtin_dxex (_Decimal64);
+DXEX dfp_dxex_dd {}
+
+  const signed long long __builtin_dxexq (_Decimal128);
+DXEXQ dfp_dxex_td {}
+
+  const _Decimal128 __builtin_pack_dec128 (unsigned long long, unsigned long 
long);
+PACK_TD packtd {}
+
+  void __builtin_set_fpscr_drn (signed int);
+SET_FPSCR_DRN rs6000_set_fpscr_drn {}
+
+  const unsigned long long __builtin_unpack_dec128 (_Decimal128, const int<1>);
+UNPACK_TD unpacktd {}
+
+
+[crypto]
+  const vull __builtin_crypto_vcipher (vull, vull);
+VCIPHER crypto_vcipher_v2di {}
+
+  const vuc __builtin_crypto_vcipher_be (vuc, vuc);
+VCIPHER_BE crypto_vcipher_v16qi {}
+
+  const vull __builtin_crypto_vcipherlast (vull, vull);
+VCIPHERLAST crypto_vcipherlast_v2di {}
+
+  const vuc __builtin_crypto_vcipherlast_be (vuc, vuc);
+VCIPHERLAST_BE crypto_vcipherlast_v16qi {}
+
+  const vull __builtin_crypto_vncipher (vull, vull);
+VNCIPHER crypto_vncipher_v2di {}
+
+  const vuc __builtin_crypto_vncipher_be (vuc, vuc);
+VNCIPHER_BE crypto_vncipher_v16qi {}
+
+  const vull __builtin_crypto_vncipherlast (vull, vull);
+VNCIPHERLAST crypto_vncipherlast_v2di {}
+
+  const vuc __builtin_crypto_vncipherlast_be (vuc, vuc);
+VNCIPHERLAST_BE crypto_vncipherlast_v16qi {}
+
+  const vull __builtin_crypto_vsbox (vull);
+VSBOX crypto_vsbox_v2di {}
+
+  const vuc __builtin_crypto_vsbox_be (vuc);
+   

[PATCH 29/29] rs6000: Call rs6000_autoinit_builtins from rs6000_builtins

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-call.c (rs6000-builtins.h): New #include.
(rs6000_init_builtins): Call rs6000_autoinit_builtins.
---
 gcc/config/rs6000/rs6000-call.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 70813a3bb9f..032203f5e9a 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -71,6 +71,7 @@
 #include "opts.h"
 
 #include "rs6000-internal.h"
+#include "rs6000-builtins.h"
 
 #if TARGET_MACHO
 #include "gstab.h"  /* for N_SLINE */
@@ -12864,6 +12865,9 @@ rs6000_init_builtins (void)
   pixel_V8HI_type_node = rs6000_vector_type ("__vector __pixel",
 pixel_type_node, 8);
 
+  /* Execute the autogenerated initialization code for builtins.  */
+  rs6000_autoinit_builtins ();
+
   /* Create Altivec, VSX and MMA builtins on machines with at least the
  general purpose extensions (970 and newer) to allow the use of
  the target attribute.  */
-- 
2.17.1



[PATCH 28/29] rs6000: Add comments to help with transition

2020-07-27 Thread Bill Schmidt
From: Bill Schmidt 

2020-07-26  Bill Schmidt  

* config/rs6000/rs6000-builtin.def: Add comments.
* config/rs6000/rs6000-call.c: Likewise.
---
 gcc/config/rs6000/rs6000-builtin.def |  15 +++
 gcc/config/rs6000/rs6000-call.c  | 166 +++
 2 files changed, 181 insertions(+)

diff --git a/gcc/config/rs6000/rs6000-builtin.def 
b/gcc/config/rs6000/rs6000-builtin.def
index f7037552faf..83b31cbbbce 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -1783,8 +1783,10 @@ BU_VSX_3 (XXPERMDI_4SF,   "xxpermdi_4sf",   CONST,   
vsx_xxpermdi_v4sf)
 BU_VSX_3 (XXPERMDI_4SI,   "xxpermdi_4si",   CONST, 
vsx_xxpermdi_v4si)
 BU_VSX_3 (XXPERMDI_8HI,   "xxpermdi_8hi",   CONST, 
vsx_xxpermdi_v8hi)
 BU_VSX_3 (XXPERMDI_16QI,  "xxpermdi_16qi",  CONST, 
vsx_xxpermdi_v16qi)
+/* Following one needs an _UNS version.  */
 BU_VSX_3 (SET_1TI,"set_1ti",CONST, vsx_set_v1ti)
 BU_VSX_3 (SET_2DF,"set_2df",CONST, vsx_set_v2df)
+/* Following one needs an _UNS version.  */
 BU_VSX_3 (SET_2DI,"set_2di",CONST, vsx_set_v2di)
 BU_VSX_3 (XXSLDWI_2DI,"xxsldwi_2di",CONST, 
vsx_xxsldwi_v2di)
 BU_VSX_3 (XXSLDWI_2DF,"xxsldwi_2df",CONST, 
vsx_xxsldwi_v2df)
@@ -1828,8 +1830,11 @@ BU_VSX_2 (CPSGNDP, "cpsgndp",CONST,  
vector_copysignv2df3)
 BU_VSX_2 (CPSGNSP,   "cpsgnsp",CONST,  vector_copysignv4sf3)
 
 BU_VSX_2 (CONCAT_2DF,"concat_2df", CONST,  vsx_concat_v2df)
+/* Following one needs an _UNS version.  */
 BU_VSX_2 (CONCAT_2DI,"concat_2di", CONST,  vsx_concat_v2di)
+/* Following two should be unary functions?!  */
 BU_VSX_2 (SPLAT_2DF, "splat_2df",  CONST,  vsx_splat_v2df)
+/* Following one also needs an _UNS version.  */
 BU_VSX_2 (SPLAT_2DI, "splat_2di",  CONST,  vsx_splat_v2di)
 BU_VSX_2 (XXMRGHW_4SF,   "xxmrghw",CONST,  vsx_xxmrghw_v4sf)
 BU_VSX_2 (XXMRGHW_4SI,   "xxmrghw_4si",CONST,  vsx_xxmrghw_v4si)
@@ -2009,6 +2014,12 @@ BU_VSX_X (ST_ELEMREV_V4SF,"st_elemrev_v4sf",  MEM)
 BU_VSX_X (ST_ELEMREV_V4SI,"st_elemrev_v4si",  MEM)
 BU_VSX_X (ST_ELEMREV_V8HI,"st_elemrev_v8hi",  MEM)
 BU_VSX_X (ST_ELEMREV_V16QI,   "st_elemrev_v16qi", MEM)
+/*  Following builtins appear to be orphaned with no implementation.
+   They are all marked as requiring special handling, but there is no
+   special handling for them.  For now I am not sure we really miss
+   anything by not having these; they all have regular float counterparts
+   and there is little utility in forcing these with builtins.  No plan
+   to put them in rs6000-builtins-new.def.  */
 BU_VSX_X (XSABSDP,   "xsabsdp",CONST)
 BU_VSX_X (XSADDDP,   "xsadddp",FP)
 BU_VSX_X (XSCMPODP,  "xscmpodp",   FP)
@@ -2033,6 +2044,7 @@ BU_VSX_X (XSNMADDMDP,   "xsnmaddmdp", FP)
 BU_VSX_X (XSNMSUBADP,"xsnmsubadp", FP)
 BU_VSX_X (XSNMSUBMDP,"xsnmsubmdp", FP)
 BU_VSX_X (XSSUBDP,   "xssubdp",FP)
+/*  End orphaned builtins.  */
 BU_VSX_X (VEC_INIT_V1TI,  "vec_init_v1ti", CONST)
 BU_VSX_X (VEC_INIT_V2DF,  "vec_init_v2df", CONST)
 BU_VSX_X (VEC_INIT_V2DI,  "vec_init_v2di", CONST)
@@ -2394,6 +2406,7 @@ BU_P9V_VSX_2 (VSCEDPLT,   "scalar_cmp_exp_dp_lt", CONST,  
xscmpexpdp_lt)
 BU_P9V_VSX_2 (VSCEDPEQ,"scalar_cmp_exp_dp_eq", CONST,  xscmpexpdp_eq)
 BU_P9V_VSX_2 (VSCEDPUO,"scalar_cmp_exp_dp_unordered",  CONST,  
xscmpexpdp_unordered)
 
+/* Shouldn't these be BU_FLOAT128_HW_VSX_2?  */
 BU_P9V_VSX_2 (VSCEQPGT,"scalar_cmp_exp_qp_gt", CONST,  
xscmpexpqp_gt_kf)
 BU_P9V_VSX_2 (VSCEQPLT,"scalar_cmp_exp_qp_lt", CONST,  
xscmpexpqp_lt_kf)
 BU_P9V_VSX_2 (VSCEQPEQ,"scalar_cmp_exp_qp_eq", CONST,  
xscmpexpqp_eq_kf)
@@ -2500,6 +2513,8 @@ BU_FLOAT128_HW_3 (FMAF128_ODD,   "fmaf128_round_to_odd",  
 FP, fmakf4_odd)
 
 /* 3 argument vector functions returning void, treated as SPECIAL,
added in ISA 3.0 (power9).  */
+/* ??? Why are these named __builtin_altivec_* when the corresponding
+   load builtins are named __builtin_vsx_*??  */
 BU_P9V_64BIT_AV_X (STXVL,  "stxvl",MISC)
 BU_P9V_64BIT_AV_X (XST_LEN_R,  "xst_len_r",MISC)
 
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 5ec3f2c55ad..70813a3bb9f 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -444,48 +444,56 @@ const struct altivec_builtin_types 
altivec_overloaded_builtins[] = {
 RS6000_BTI_bool_V8HI, RS6000_BTI_bool_V16QI, 0, 0 },
 
   /* Binary AltiVec/VSX builtins.  */
+  /* Next 2 deprecated, not in rs6000-builtin-new.def.  */
   { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_BUILTIN_VADDUBM,
 RS6000_BTI_V16QI, RS6000_BTI_bool_V16QI, RS6000_BTI_V16QI, 0 },
   { ALTIVEC_BUILTIN_VEC_ADD, ALTIVEC_B

Re: [PATCH] [RFC] vect: Fix infinite loop while determining peeling amount

2020-07-27 Thread Stefan Schulze Frielinghaus via Gcc-patches
On Mon, Jul 27, 2020 at 12:29:11PM +0200, Richard Biener wrote:
> On Mon, Jul 27, 2020 at 11:45 AM Richard Sandiford
>  wrote:
> >
> > Richard Biener  writes:
> > > On Mon, Jul 27, 2020 at 11:09 AM Richard Sandiford
> > >  wrote:
> > >>
> > >> Richard Biener via Gcc-patches  writes:
> > >> > On Wed, Jul 22, 2020 at 5:18 PM Stefan Schulze Frielinghaus via
> > >> > Gcc-patches  wrote:
> > >> >>
> > >> >> This is a follow up to commit 5c9669a0e6c respectively discussion
> > >> >> https://gcc.gnu.org/pipermail/gcc-patches/2020-June/549132.html
> > >> >>
> > >> >> In case that an alignment constraint is less than the size of a
> > >> >> corresponding scalar type, ensure that we advance at least by one
> > >> >> iteration.  For example, on s390x we have for a long double an 
> > >> >> alignment
> > >> >> constraint of 8 bytes whereas the size is 16 bytes.  Therefore,
> > >> >> TARGET_ALIGN / DR_SIZE equals zero resulting in an infinite loop which
> > >> >> can be reproduced by the following MWE:
> > >> >
> > >> > But we guard this case with vector_alignment_reachable_p, so we 
> > >> > shouldn't
> > >> > have ended up here and the patch looks bogus.
> > >>
> > >> The above sounds like it ought to count as reachable alignment though.
> > >> If a type requires a lower alignment than its size, then that's even
> > >> more easily reachable than a type that requires the same alignment as
> > >> the size.  I guess at one extreme, a target alignment of 1 is always
> > >> reachable.
> > >
> > > Well, if the element alignment is 8 but its size is 16 then when 
> > > presumably
> > > the desired vector alignment is a multiple of 16 we can never reach it.
> > > Isn't this the case here?
> >
> > If the desired vector alignment (TARGET_ALIGN) is a multiple of 16 then
> > TARGET_ALIGN / DR_SIZE will be nonzero and the problem the patch is
> > fixing wouldn't occur.  I agree that we might never be able to reach
> > that alignment if the pointer starts out misaligned by 8 bytes.
> >
> > But I think that's why it makes sense for the target to only ask
> > for 8-byte alignment for vectors too, if it can cope with it.  8-byte
> > alignment should always be achievable if the scalars are ABI-aligned.
> > And if the target does ask for only 8-byte alignment, TARGET_ALIGN /
> > DR_SIZE would be zero and the loop would never progress, which is the
> > problem that the patch is fixing.
> >
> > It would even make sense for the target to ask for 1-byte alignment,
> > if the target doesn't care about alignment at all.
> 
> Hmm, OK.  Guess I still think we should detect this somewhere upward
> and avoid this peeling compute at all.  Somehow.

I've been playing around with another solution which works for me by
changing vector_alignment_reachable_p to return also false if the
alignment requirements are already satisfied, i.e., by adding:

if (known_alignment_for_access_p (dr_info) && aligned_access_p (dr_info))
  return false;

Though, I'm not entirely sure whether this makes it better or not.
Strictly speaking if the alignment was reachable before peeling, then
reaching alignment with peeling is also possible but probably not what
was intended.  So I guess returning false in this case is sensible.  Any
comments?

Thanks,
Stefan

> 
> Richard.
> 
> > Thanks,
> > Richard


  1   2   >