Re: [PATCH] [PR68097] Try to avoid recursing for floats in tree_*_nonnegative_warnv_p.

2022-11-17 Thread Richard Biener via Gcc-patches
On Wed, Nov 16, 2022 at 6:38 PM Aldy Hernandez  wrote:
>
>
>
> On 11/16/22 17:04, Richard Biener wrote:
> > On Tue, Nov 15, 2022 at 11:46 AM Aldy Hernandez  wrote:
> >>
> >>
> >>
> >> On 11/15/22 08:15, Richard Biener wrote:
> >>> On Mon, Nov 14, 2022 at 8:05 PM Aldy Hernandez  wrote:
> 
> 
> 
>  On 11/14/22 10:12, Richard Biener wrote:
> > On Sat, Nov 12, 2022 at 7:30 PM Aldy Hernandez  wrote:
> >>
> >> It irks me that a PR named "we should track ranges for floating-point
> >> hasn't been closed in this release.  This is an attempt to do just
> >> that.
> >>
> >> As mentioned in the PR, even though we track ranges for floats, it has
> >> been suggested that avoiding recursing through SSA defs in
> >> gimple_assign_nonnegative_warnv_p is also a goal.  We can do this with
> >> various ranger components without the need for a heavy handed approach
> >> (i.e. a full ranger).
> >>
> >> I have implemented two versions of known_float_sign_p() that answer
> >> the question whether we definitely know the sign for an operation or a
> >> tree expression.
> >>
> >> Both versions use get_global_range_query, which is a wrapper to query
> >> global ranges.  This means, that no caching or propagation is done.
> >> In the case of an SSA, we just return the global range for it (think
> >> SSA_NAME_RANGE_INFO).  In the case of a tree code with operands, we
> >> also use get_global_range_query to resolve the operands, and then call
> >> into range-ops, which is our lowest level component.  There is no
> >> ranger or gori involved.  All we're doing is resolving the operation
> >> with the ranges passed.
> >>
> >> This is enough to avoid recursing in the case where we definitely know
> >> the sign of a range.  Otherwise, we still recurse.
> >>
> >> Note that instead of get_global_range_query(), we could use
> >> get_range_query() which uses a ranger (if active in a pass), or
> >> get_global_range_query if not.  This would allow passes that have an
> >> active ranger (with enable_ranger) to use a full ranger.  These passes
> >> are currently, VRP, loop unswitching, DOM, loop versioning, etc.  If
> >> no ranger is active, get_range_query defaults to global ranges, so
> >> there's no additional penalty.
> >>
> >> Would this be acceptable, at least enough to close (or rename the PR 
> >> ;-))?
> >
> > I think the checks would belong to the gimple_stmt_nonnegative_warnv_p 
> > function
> > only (that's the SSA name entry from the fold-const.cc ones)?
> 
>  That was my first approach, but I thought I'd cover the unary and binary
>  operators as well, since they had other callers.  But I'm happy with
>  just the top-level tweak.  It's a lot less code :).
> >>>
> >>> @@ -9234,6 +9235,15 @@ bool
> >>>gimple_stmt_nonnegative_warnv_p (gimple *stmt, bool *strict_overflow_p,
> >>>int depth)
> >>>{
> >>> +  tree type = gimple_range_type (stmt);
> >>> +  if (type && frange::supports_p (type))
> >>> +{
> >>> +  frange r;
> >>> +  bool sign;
> >>> +  return (get_global_range_query ()->range_of_stmt (r, stmt)
> >>> + && r.signbit_p (sign)
> >>> + && sign == false);
> >>> +}
> >>>
> >>> the above means we never fall through to the switch below if
> >>> frange::supports_p (type) - that's eventually good enough, I
> >>> don't think we ever call this very function directly but it gets
> >>> invoked via recursion through operands only.  But of course
> >>
> >> Woah, sorry.  That was not intended.  For that matter, the patch as
> >> posted caused:
> >>
> >> FAIL: gcc.dg/builtins-10.c (test for excess errors)
> >> FAIL: gcc.dg/builtins-57.c (test for excess errors)
> >> FAIL: gcc.dg/torture/builtin-nonneg-1.c   -O1  (test for excess errors)
> >> FAIL: gcc.dg/torture/builtin-nonneg-1.c   -O2  (test for excess errors)
> >> FAIL: gcc.dg/torture/builtin-nonneg-1.c   -O2 -flto
> >> -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
> >> FAIL: gcc.dg/torture/builtin-nonneg-1.c   -O3 -g  (test for excess errors)
> >> FAIL: gcc.dg/torture/builtin-nonneg-1.c   -Os  (test for excess errors)
> >> FAIL: gcc.dg/torture/builtin-power-1.c   -O1  (test for excess errors)
> >> FAIL: gcc.dg/torture/builtin-power-1.c   -O2  (test for excess errors)
> >> FAIL: gcc.dg/torture/builtin-power-1.c   -O2 -flto
> >> -fno-use-linker-plugin -flto-partition=none  (test for excess errors)
> >> FAIL: gcc.dg/torture/builtin-power-1.c   -O3 -g  (test for excess errors)
> >> FAIL: gcc.dg/torture/builtin-power-1.c   -Os  (test for excess errors)
> >
> > Did you investigate why?  Because the old patch removed the recursion
> > while the new keeps it in case the global range isn't present which isn't
> > as nice.
>
> For gcc.dg/builtins-10.c, there are a few calls to
> gimple_stmt_nonneg

Re: [PATCH 1/2] symtab: also change RTL decl name

2022-11-17 Thread Bernhard Reutner-Fischer via Gcc-patches
Hi Honza, Ping.
Regtests cleanly for c,fortran,c++,ada,d,go,lto,objc,obj-c++
Ok?
I'd need this for attribute target_clones for the Fortran FE.
thanks,

On Wed,  9 Nov 2022 20:02:24 +0100
Bernhard Reutner-Fischer  wrote:

> We were changing the ASSEMBLER_NAME of the function decl
> but not the name in DECL_RTL which is used as the function name
> fnname in rest_of_handle_final(). This led to using the old, wrong name
> for the attribute target default function when using target_clones.
> 
> Bootstrapped and regtested cleanly on x86_64-unknown-linux
> for c,c++,fortran,lto.
> Ok for trunk?
> 
> gcc/ChangeLog:
> 
>   * symtab.cc: Remove stray comment.
>   (symbol_table::change_decl_assembler_name): Also update the
>   name in DECL_RTL.
> 
> Cc: Jan Hubicka 
> ---
>  gcc/symtab.cc | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/gcc/symtab.cc b/gcc/symtab.cc
> index f2d96c0268b..2e20bf5fefc 100644
> --- a/gcc/symtab.cc
> +++ b/gcc/symtab.cc
> @@ -154,8 +154,6 @@ symbol_table::decl_assembler_name_equal (tree decl, 
> const_tree asmname)
>  }
>  
>  
> -/* Returns nonzero if P1 and P2 are equal.  */
> -
>  /* Insert NODE to assembler name hash.  */
>  
>  void
> @@ -303,6 +301,10 @@ symbol_table::change_decl_assembler_name (tree decl, 
> tree name)
>   warning (0, "%qD renamed after being referenced in assembly", decl);
>  
>SET_DECL_ASSEMBLER_NAME (decl, name);
> +  /* Set the new name in rtl.  */
> +  if (DECL_RTL_SET_P (decl))
> + XSTR (XEXP (DECL_RTL (decl), 0), 0) = IDENTIFIER_POINTER (name);
> +
>if (alias)
>   {
> IDENTIFIER_TRANSPARENT_ALIAS (name) = 1;



Re: [PATCH 3/8]middle-end: Support extractions of subvectors from arbitrary element position inside a vector

2022-11-17 Thread Hongtao Liu via Gcc-patches
On Wed, Nov 16, 2022 at 1:39 AM Richard Sandiford
 wrote:
>
> Tamar Christina  writes:
> >> -Original Message-
> >> From: Hongtao Liu 
> >> Sent: Tuesday, November 15, 2022 9:37 AM
> >> To: Tamar Christina 
> >> Cc: Richard Sandiford ; Tamar Christina via
> >> Gcc-patches ; nd ;
> >> rguent...@suse.de
> >> Subject: Re: [PATCH 3/8]middle-end: Support extractions of subvectors from
> >> arbitrary element position inside a vector
> >>
> >> On Tue, Nov 15, 2022 at 4:51 PM Tamar Christina
> >>  wrote:
> >> >
> >> > > -Original Message-
> >> > > From: Hongtao Liu 
> >> > > Sent: Tuesday, November 15, 2022 8:36 AM
> >> > > To: Tamar Christina 
> >> > > Cc: Richard Sandiford ; Tamar Christina
> >> > > via Gcc-patches ; nd ;
> >> > > rguent...@suse.de
> >> > > Subject: Re: [PATCH 3/8]middle-end: Support extractions of
> >> > > subvectors from arbitrary element position inside a vector
> >> > >
> >> > > Hi:
> >> > >   I'm from https://gcc.gnu.org/pipermail/gcc-patches/2022-
> >> > > November/606040.html.
> >> > > >  }
> >> > > >
> >> > > >/* See if we can get a better vector mode before extracting.
> >> > > > */ diff --git a/gcc/optabs.cc b/gcc/optabs.cc index
> >> > > >
> >> > >
> >> cff37ccb0dfc3dd79b97d0abfd872f340855dc96..f338df410265dfe55b68961600
> >> > > 9
> >> > > 0
> >> > > > a453cc6a28d9 100644
> >> > > > --- a/gcc/optabs.cc
> >> > > > +++ b/gcc/optabs.cc
> >> > > > @@ -6267,6 +6267,7 @@ expand_vec_perm_const (machine_mode
> >> mode,
> >> > > rtx v0, rtx v1,
> >> > > >v0_qi = gen_lowpart (qimode, v0);
> >> > > >v1_qi = gen_lowpart (qimode, v1);
> >> > > >if (targetm.vectorize.vec_perm_const != NULL
> >> > > > + && targetm.can_change_mode_class (mode, qimode,
> >> > > > + ALL_REGS)
> >> > > It looks like you want to guard gen_lowpart, shouldn't it be better
> >> > > to use validate_subreg  or (tmp = gen_lowpart_if_possible (mode,
> >> target_qi)).
> >> > > IMHO, targetm.can_change_mode_class is mostly used for RA, but not
> >> > > to guard gen_lowpart.
> >> >
> >> > Hmm I don't think this is quite true, there are existing usages in
> >> > expr.cc and rtanal.cc That do this and aren't part of RA.  As I
> >> > mentioned before for instance the canoncalization of vec_select to subreg
> >> in rtlanal for instances uses this.
> >> In theory, we need to iterate through all reg classes that can be assigned 
> >> for
> >> both qimode and mode, if any regclass returns true for
> >> targetm.can_change_mode_class, the bitcast(validate_subreg) should be ok.
> >> Here we just passed ALL_REGS.
> >
> > Yes, and most targets where this transformation is valid return true here.
> >
> > I've checked:
> >  * alpha
> >  * arm
> >  * aarch64
> >  * rs6000
> >  * s390
> >  * sparc
> >  * pa
> >  * mips
> >
> > And even the default example that other targets use from the documentation
> > would return true as the size of the modes are the same.
> >
> > X86 and RISCV are the only two targets that I found (but didn't check all) 
> > that
> > blankly return a result based on just the register classes.
> >
> > That is to say, there are more targets that adhere to the interpretation 
> > that
> > rclass here means "should be possible in some class in rclass" rather than
> > "should be possible in ALL classes of rclass".
>
> Yeah, I agree.  A query "can something stored in ALL_REGS change from
> mode M1 to mode M2?" is meaningful if at least one register R in ALL_REGS
> can hold both M1 and M2.  It's then the target's job to answer
> conservatively so that the result covers all such R.
>
> In principle it's OK for a target to err on the side of caution and forbid
> things that are actually OK.  But that's going to risk losing performance
> in some cases, and sometimes that loss of performance will be unacceptable.
> IMO that's what's happening here.  The target is applying x87 rules to
> things that (AIUI) are never stored in x87 registers, and so losing
Yes, it can be optimized since some mode will never assigned to x87 registers.
> performance as a result.
>
> Note that the RA also uses ALL_REGS for some things, so this usage
> isn't specific to non-RA code.
RA passes the minimal reg class(REGNO_REG_CLASS) which contains REGN
to decide if can_change_mode_class, not ALL_REGS.
511/* Given a hard REGN a FROM mode and a TO mode, return true if
512   REGN can change from mode FROM to mode TO.  */
513#define REG_CAN_CHANGE_MODE_P(REGN, FROM, TO)  \
514  (targetm.can_change_mode_class (FROM, TO, REGNO_REG_CLASS (REGN)))
515

So I still think using can_change_mode_class outside of RA with
ALL_REGS passed to decide whether it's ok to generate subreg is not a
good idea.
>
> IMO it's not the job of target-independent code to iterate through
> individual classes and aggregate the result.  One of the reasons for
> having union classes is to avoid the need to do that.  And ALL_REGS
> is the ultimate union class. :-)
>
> The patch looks correct to me.
>
> Thanks,
> Rich

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-17 Thread Bernhard Reutner-Fischer via Gcc-patches
On Tue, 15 Nov 2022 18:52:41 -0500
Jason Merrill  wrote:

> On 11/12/22 13:45, Bernhard Reutner-Fischer wrote:
> > gcc/cp/ChangeLog:
> > 
> > * decl.cc (start_function): Set the result decl source location to
> > the location of the typespec.
> > 
> > ---
> > Bootstrapped and regtested on x86_86-unknown-linux with no regressions.
> > Ok for trunk?
> > 
> > Cc: Nathan Sidwell 
> > Cc: Jason Merrill 
> > ---
> >   gcc/cp/decl.cc | 15 ++-
> >   1 file changed, 14 insertions(+), 1 deletion(-)
> > 
> > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> > index 6e98ea35a39..ed40815e645 100644
> > --- a/gcc/cp/decl.cc
> > +++ b/gcc/cp/decl.cc
> > @@ -17449,6 +17449,8 @@ start_function (cp_decl_specifier_seq *declspecs,
> > tree attrs)
> >   {
> > tree decl1;
> > +  tree result;
> > +  bool ret;  
> 
> We now prefer to declare new variables as late as possible, usually when 
> they are initialized.

Moved. Ok like attached? Bootstrapped and regtested fine.

> > decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
> > invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1);
> > @@ -17461,7 +17463,18 @@ start_function (cp_decl_specifier_seq *declspecs,
> >   gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
> >  integer_type_node));
> >   
> > -  return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
> > +  ret = start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
> > +
> > +  /* decl1 might be ggc_freed here.  */
> > +  decl1 = current_function_decl;
> > +
> > +  /* Set the result decl source location to the location of the typespec.  
> > */
> > +  if (TREE_CODE (decl1) == FUNCTION_DECL
> > +  && declspecs->locations[ds_type_spec] != UNKNOWN_LOCATION
> > +  && (result = DECL_RESULT (decl1)) != NULL_TREE
> > +  && DECL_SOURCE_LOCATION (result) == input_location)
> > +DECL_SOURCE_LOCATION (result) = declspecs->locations[ds_type_spec];  
> 
> One way to handle the template case would be for the code in 
> start_preparsed_function that sets DECL_RESULT to check whether decl1 is 
> a template instantiation, and in that case copy the location from the 
> template's DECL_RESULT, i.e.
> 
> DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1)))

Well, that would probably work if something would set the location of
that template result decl properly, which nothing does out of the box.

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index ed7226b82f0..65d78c82a2d 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17230,6 +17231,17 @@ start_preparsed_function (tree decl1, tree attrs, int 
flags)
   cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
 }
 
+  /* Set the result decl source location to the location of the typespec.  */
+  if (DECL_RESULT (decl1)
+  && !DECL_USE_TEMPLATE (decl1)
+  && DECL_TEMPLATE_INFO (decl1)
+  && DECL_TI_TEMPLATE (decl1)
+  && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1))
+  && DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1
+  DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
+   = DECL_SOURCE_LOCATION (
+   DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1;
+
   /* Record the decl so that the function name is defined.
  If we already have a decl for this name, and it is a FUNCTION_DECL,
  use the old decl.  */

(gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result 
locus before")
../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus before
7 |   { return _M_finish != 0; }
  |   ^
(gdb) n
(gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result 
locus from TI")
../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus from TI
(gdb) p DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
$1 = 267168

I'm leaving the template case alone for now, maybe i'm motivated later
on to again look at grokfndecl and/or grokmethod to fill in the proper
location. For starters i only need normal functions.
But many thanks for the hint on where the template stuff is, i thought
i would not need it at all but had hoped that there is a spot where
both declspec are at hand and something is "derived" from the templates.

> 
> > +  return ret;
> >   }
> >   
> >   /* Returns true iff an EH_SPEC_BLOCK should be created in the body of  
> 

>From 5595eb2d3056f6bca3d2b80bc8b2796d86da0ce8 Mon Sep 17 00:00:00 2001
From: Bernhard Reutner-Fischer 
Date: Sun, 13 Nov 2022 00:45:40 +0100
Subject: [PATCH 2/5] c++: Set the locus of the function result decl

gcc/cp/ChangeLog:

	* decl.cc (start_function): Set the result decl source location to
	the location of the typespec.
---
 gcc/cp/decl.cc | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 890cfcabd35..ed7226b82f0 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17527,7 +17527,19 @@ start_function (cp_decl_specifier_seq *declspecs,
   

Re: [committed] libstdc++: Improve performance of chrono::utc_clock::now()

2022-11-17 Thread Jonathan Wakely via Gcc-patches
On Thu, 17 Nov 2022, 06:30 Daniel Krügler via Libstdc++, <
libstd...@gcc.gnu.org> wrote:

> Am Mi., 16. Nov. 2022 um 22:00 Uhr schrieb Jonathan Wakely via
> Libstdc++ :
> >
> > Tested x86_64-linux. Pushed to trunk.
> >
> > -- >8 --
> >
> > We can use an array instead of a std::vector, and we can avoid the
> > binary search for the common case of a time point after the most recent
> > leap second. On one system where I tested this, utc_clock::now() now
> > takes about 16ns instead of 31ns.
> >
> > libstdc++-v3/ChangeLog:
> >
> > * include/std/chrono (get_leap_second_info): Optimize.
> > ---
> >  libstdc++-v3/include/std/chrono | 31 ---
> >  1 file changed, 24 insertions(+), 7 deletions(-)
> >
> > diff --git a/libstdc++-v3/include/std/chrono
> b/libstdc++-v3/include/std/chrono
> > index 90b73f8198e..2468023f6c5 100644
> > --- a/libstdc++-v3/include/std/chrono
> > +++ b/libstdc++-v3/include/std/chrono
> > @@ -2747,9 +2747,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >{
> > if constexpr (is_same_v<_Duration, seconds>)
> >   {
> > -   // TODO move this function into the library and get leaps
> from tzdb.
> > -   vector __leaps
> > -   {
> > +   const seconds::rep __leaps[] {
> > 78796800, // 1 Jul 1972
> > 94694400, // 1 Jan 1973
> >126230400, // 1 Jan 1974
> > @@ -2778,12 +2776,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >   1435708800, // 1 Jul 2015
> >   1483228800, // 1 Jan 2017
> > };
> > +   // The list above is known to be valid until 2023-06-28
> 00:00:00 UTC
> > +   const seconds::rep __expires = 1687910400;
> > +   const seconds::rep __s = __ut.time_since_epoch().count();
> >
> > -   auto __s = __ut.time_since_epoch().count();
> > -   auto __pos = std::upper_bound(__leaps.begin(),
> __leaps.end(), __s);
> > +   const seconds::rep* __first = std::begin(__leaps);
> > +   const seconds::rep* __last = std::end(__leaps);
> > +
> > +   if (__s > __expires)
> > + {
> > +   // TODO: use updated leap_seconds from tzdb
> > +#if 0
> > +   auto __db = get_tzdb_list().begin();
> > +   __first = __db->leap_seconds.data();
> > +   __last = __first + __db->leap_seconds.size();
> > +#endif
> > + }
> > +
> > +   // Don't bother searching the list if we're after the last
> one.
> > +   if (__s > __last[-1])
> > + return { false, seconds(__last - __first) };
> > +
> > +   auto __pos = std::upper_bound(__first, __last, __s);
> > return {
> > - __pos != __leaps.begin() && __pos[-1] == __s,
> > - seconds{__pos - __leaps.begin()}
> > + __pos != begin(__leaps) && __pos[-1] == __s,
>
> The inconsistency between usage of std::begin versus begin here seems
> odd and I'm wondering why instead of "begin(__leaps)" the above
> introduced "__first" variable is not used instead.
>

Because this code is going to be changed again soon, this is a partial
merge from a local branch with the TODO fixed. Yes, it's inconsistent, but
it works correctly and it's not my priority right now :-)


[PATCH] c++, v3: Implement C++23 P2647R1 - Permitting static constexpr variables in constexpr functions

2022-11-17 Thread Jakub Jelinek via Gcc-patches
On Wed, Nov 16, 2022 at 03:26:32PM -0500, Jason Merrill wrote:
> On 11/16/22 09:46, Jakub Jelinek wrote:
> > On Wed, Nov 16, 2022 at 09:33:27AM -0500, Jason Merrill wrote:
> > > > and at that point I fear decl_maybe_constant_var_p will not work
> > > > properly.  Shall this hunk be moved somewhere else (cp_finish_decl?)
> > > > where we can already call it, or do the above in start_decl for
> > > > cxx_dialect < cxx20 and add a cxx_dialect == cxx20 hunk in 
> > > > cp_finish_decl?
> > > 
> > > Hmm, I'd expect decl_maybe_constant_var_p to work fine at this point.
> > 
> > For static constexpr vars sure, but what about
> > static const where start_decl doesn't know the initializer?
> > Sure, decl_maybe_constant_var_p will not crash in that case, but
> > it will return true even if the static const var doesn't have
> > a constant initializer.  Sure, we'd catch that later on when actually
> > trying to constexpr evaluate the function and hitting there the
> > spots added for C++23 in potential_constant_expression*/cxx_eval_*,
> > but it would mean that we don't reject it when nothing calls the functions.
> > 
> > I meant something like:
> > constexpr int bar (int x) { if (x) throw 1; return 0; }
> > constexpr int foo () { static const int a = bar (1); return 0; }
> > with -std=c++20 IMHO shouldn't be accepted, while in C++23 it should.
> 
> I'd expect us to reject that in C++20 in potential_constant_expression, but
> it's a fair point; it is awkward that P2242 wasn't also accepted as a DR.
> 
> Moving the check from start_decl to cp_finish_decl makes sense to me.

So like this?  I had to outline the check from start_decl to a function
because it is needed in cp_finish_decl in two different places (the
processing_template_decl path and at the end and it can't be done before the
processing_template_decl spot, because the initializer isn't finalized at
that point for !procesing_template_decl).  Also, decl_maybe_constant_var_p
doesn't do what is needed when !processing_template_decl, but I think
we want decl_maybe_constant_var_p in templates so that we don't instantiate
anything.

Lightly tested so far, ok for trunk if it passes full bootstrap/regtest?

2022-11-17  Jakub Jelinek  

gcc/c-family/
* c-cppbuiltin.cc (c_cpp_builtins): Bump __cpp_constexpr
value from 202207L to 202211L.
gcc/cp/
* constexpr.cc (cxx_eval_constant_expression): Implement C++23
P2647R1 - Permitting static constexpr variables in constexpr functions.
Allow decl_constant_var_p static or thread_local vars for
C++20 and later.
(potential_constant_expression_1): For C++20 or later, allow
static or thread_local decl_maybe_constant_var_p vars, for
!processing_template_decl only decl_constant_var_p vars.
* decl.cc (diagnose_static_in_constexpr): New function.
(start_decl): Use it for C++17 or earlier.
(cp_finish_decl): Call it for C++20.
gcc/testsuite/
* g++.dg/cpp23/constexpr-nonlit17.C: New test.
* g++.dg/cpp23/constexpr-nonlit18.C: New test.
* g++.dg/cpp23/feat-cxx2b.C: Adjust expected __cpp_constexpr
value.
* g++.dg/ext/stmtexpr19.C: Don't expect an error for C++20 or later. 

--- gcc/c-family/c-cppbuiltin.cc.jj 2022-11-17 09:00:42.106249011 +0100
+++ gcc/c-family/c-cppbuiltin.cc2022-11-17 09:01:49.286320527 +0100
@@ -1074,7 +1074,7 @@ c_cpp_builtins (cpp_reader *pfile)
  /* Set feature test macros for C++23.  */
  cpp_define (pfile, "__cpp_size_t_suffix=202011L");
  cpp_define (pfile, "__cpp_if_consteval=202106L");
- cpp_define (pfile, "__cpp_constexpr=202207L");
+ cpp_define (pfile, "__cpp_constexpr=202211L");
  cpp_define (pfile, "__cpp_multidimensional_subscript=202211L");
  cpp_define (pfile, "__cpp_named_character_escapes=202207L");
  cpp_define (pfile, "__cpp_static_call_operator=202207L");
--- gcc/cp/constexpr.cc.jj  2022-11-17 08:48:30.530357181 +0100
+++ gcc/cp/constexpr.cc 2022-11-17 09:56:50.479522863 +0100
@@ -7098,7 +7098,8 @@ cxx_eval_constant_expression (const cons
&& (TREE_STATIC (r)
|| (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r)))
/* Allow __FUNCTION__ etc.  */
-   && !DECL_ARTIFICIAL (r))
+   && !DECL_ARTIFICIAL (r)
+   && (cxx_dialect < cxx20 || !decl_constant_var_p (r)))
  {
if (!ctx->quiet)
  {
@@ -9588,7 +9589,12 @@ potential_constant_expression_1 (tree t,
   tmp = DECL_EXPR_DECL (t);
   if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp))
{
- if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp))
+ if (CP_DECL_THREAD_LOCAL_P (tmp)
+ && !DECL_REALLY_EXTERN (tmp)
+ && (cxx_dialect < cxx20
+ || (processing_template_decl
+ ? !decl_maybe_constant_var_p (tmp)
+ : !decl_constant_var_p (tmp
  

Re: [committed] libstdc++: Improve performance of chrono::utc_clock::now()

2022-11-17 Thread Daniel Krügler via Gcc-patches
Am Do., 17. Nov. 2022 um 10:07 Uhr schrieb Jonathan Wakely
:
>
>
>
> On Thu, 17 Nov 2022, 06:30 Daniel Krügler via Libstdc++, 
>  wrote:
>>
>> Am Mi., 16. Nov. 2022 um 22:00 Uhr schrieb Jonathan Wakely via
>> Libstdc++ :
>> >
>> > Tested x86_64-linux. Pushed to trunk.
>> >
>> > -- >8 --
>> >
>> > We can use an array instead of a std::vector, and we can avoid the
>> > binary search for the common case of a time point after the most recent
>> > leap second. On one system where I tested this, utc_clock::now() now
>> > takes about 16ns instead of 31ns.
>> >
>> > libstdc++-v3/ChangeLog:
>> >
>> > * include/std/chrono (get_leap_second_info): Optimize.
>> > ---
>> >  libstdc++-v3/include/std/chrono | 31 ---
>> >  1 file changed, 24 insertions(+), 7 deletions(-)
>> >
>> > diff --git a/libstdc++-v3/include/std/chrono 
>> > b/libstdc++-v3/include/std/chrono
>> > index 90b73f8198e..2468023f6c5 100644
>> > --- a/libstdc++-v3/include/std/chrono
>> > +++ b/libstdc++-v3/include/std/chrono
>> > @@ -2747,9 +2747,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> >{
>> > if constexpr (is_same_v<_Duration, seconds>)
>> >   {
>> > -   // TODO move this function into the library and get leaps from 
>> > tzdb.
>> > -   vector __leaps
>> > -   {
>> > +   const seconds::rep __leaps[] {
>> > 78796800, // 1 Jul 1972
>> > 94694400, // 1 Jan 1973
>> >126230400, // 1 Jan 1974
>> > @@ -2778,12 +2776,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> >   1435708800, // 1 Jul 2015
>> >   1483228800, // 1 Jan 2017
>> > };
>> > +   // The list above is known to be valid until 2023-06-28 
>> > 00:00:00 UTC
>> > +   const seconds::rep __expires = 1687910400;
>> > +   const seconds::rep __s = __ut.time_since_epoch().count();
>> >
>> > -   auto __s = __ut.time_since_epoch().count();
>> > -   auto __pos = std::upper_bound(__leaps.begin(), __leaps.end(), 
>> > __s);
>> > +   const seconds::rep* __first = std::begin(__leaps);
>> > +   const seconds::rep* __last = std::end(__leaps);
>> > +
>> > +   if (__s > __expires)
>> > + {
>> > +   // TODO: use updated leap_seconds from tzdb
>> > +#if 0
>> > +   auto __db = get_tzdb_list().begin();
>> > +   __first = __db->leap_seconds.data();
>> > +   __last = __first + __db->leap_seconds.size();
>> > +#endif
>> > + }
>> > +
>> > +   // Don't bother searching the list if we're after the last one.
>> > +   if (__s > __last[-1])
>> > + return { false, seconds(__last - __first) };
>> > +
>> > +   auto __pos = std::upper_bound(__first, __last, __s);
>> > return {
>> > - __pos != __leaps.begin() && __pos[-1] == __s,
>> > - seconds{__pos - __leaps.begin()}
>> > + __pos != begin(__leaps) && __pos[-1] == __s,
>>
>> The inconsistency between usage of std::begin versus begin here seems
>> odd and I'm wondering why instead of "begin(__leaps)" the above
>> introduced "__first" variable is not used instead.
>
>
> Because this code is going to be changed again soon, this is a partial merge 
> from a local branch with the TODO fixed. Yes, it's inconsistent, but it works 
> correctly and it's not my priority right now :-)

What about the suggestion to use the already existing "__first"
variable instead of the begin call?

Thanks,

- Daniel


Re: [PATCH 3/8]middle-end: Support extractions of subvectors from arbitrary element position inside a vector

2022-11-17 Thread Richard Sandiford via Gcc-patches
Hongtao Liu  writes:
> On Wed, Nov 16, 2022 at 1:39 AM Richard Sandiford
>  wrote:
>>
>> Tamar Christina  writes:
>> >> -Original Message-
>> >> From: Hongtao Liu 
>> >> Sent: Tuesday, November 15, 2022 9:37 AM
>> >> To: Tamar Christina 
>> >> Cc: Richard Sandiford ; Tamar Christina via
>> >> Gcc-patches ; nd ;
>> >> rguent...@suse.de
>> >> Subject: Re: [PATCH 3/8]middle-end: Support extractions of subvectors from
>> >> arbitrary element position inside a vector
>> >>
>> >> On Tue, Nov 15, 2022 at 4:51 PM Tamar Christina
>> >>  wrote:
>> >> >
>> >> > > -Original Message-
>> >> > > From: Hongtao Liu 
>> >> > > Sent: Tuesday, November 15, 2022 8:36 AM
>> >> > > To: Tamar Christina 
>> >> > > Cc: Richard Sandiford ; Tamar Christina
>> >> > > via Gcc-patches ; nd ;
>> >> > > rguent...@suse.de
>> >> > > Subject: Re: [PATCH 3/8]middle-end: Support extractions of
>> >> > > subvectors from arbitrary element position inside a vector
>> >> > >
>> >> > > Hi:
>> >> > >   I'm from https://gcc.gnu.org/pipermail/gcc-patches/2022-
>> >> > > November/606040.html.
>> >> > > >  }
>> >> > > >
>> >> > > >/* See if we can get a better vector mode before extracting.
>> >> > > > */ diff --git a/gcc/optabs.cc b/gcc/optabs.cc index
>> >> > > >
>> >> > >
>> >> cff37ccb0dfc3dd79b97d0abfd872f340855dc96..f338df410265dfe55b68961600
>> >> > > 9
>> >> > > 0
>> >> > > > a453cc6a28d9 100644
>> >> > > > --- a/gcc/optabs.cc
>> >> > > > +++ b/gcc/optabs.cc
>> >> > > > @@ -6267,6 +6267,7 @@ expand_vec_perm_const (machine_mode
>> >> mode,
>> >> > > rtx v0, rtx v1,
>> >> > > >v0_qi = gen_lowpart (qimode, v0);
>> >> > > >v1_qi = gen_lowpart (qimode, v1);
>> >> > > >if (targetm.vectorize.vec_perm_const != NULL
>> >> > > > + && targetm.can_change_mode_class (mode, qimode,
>> >> > > > + ALL_REGS)
>> >> > > It looks like you want to guard gen_lowpart, shouldn't it be better
>> >> > > to use validate_subreg  or (tmp = gen_lowpart_if_possible (mode,
>> >> target_qi)).
>> >> > > IMHO, targetm.can_change_mode_class is mostly used for RA, but not
>> >> > > to guard gen_lowpart.
>> >> >
>> >> > Hmm I don't think this is quite true, there are existing usages in
>> >> > expr.cc and rtanal.cc That do this and aren't part of RA.  As I
>> >> > mentioned before for instance the canoncalization of vec_select to 
>> >> > subreg
>> >> in rtlanal for instances uses this.
>> >> In theory, we need to iterate through all reg classes that can be 
>> >> assigned for
>> >> both qimode and mode, if any regclass returns true for
>> >> targetm.can_change_mode_class, the bitcast(validate_subreg) should be ok.
>> >> Here we just passed ALL_REGS.
>> >
>> > Yes, and most targets where this transformation is valid return true here.
>> >
>> > I've checked:
>> >  * alpha
>> >  * arm
>> >  * aarch64
>> >  * rs6000
>> >  * s390
>> >  * sparc
>> >  * pa
>> >  * mips
>> >
>> > And even the default example that other targets use from the documentation
>> > would return true as the size of the modes are the same.
>> >
>> > X86 and RISCV are the only two targets that I found (but didn't check all) 
>> > that
>> > blankly return a result based on just the register classes.
>> >
>> > That is to say, there are more targets that adhere to the interpretation 
>> > that
>> > rclass here means "should be possible in some class in rclass" rather than
>> > "should be possible in ALL classes of rclass".
>>
>> Yeah, I agree.  A query "can something stored in ALL_REGS change from
>> mode M1 to mode M2?" is meaningful if at least one register R in ALL_REGS
>> can hold both M1 and M2.  It's then the target's job to answer
>> conservatively so that the result covers all such R.
>>
>> In principle it's OK for a target to err on the side of caution and forbid
>> things that are actually OK.  But that's going to risk losing performance
>> in some cases, and sometimes that loss of performance will be unacceptable.
>> IMO that's what's happening here.  The target is applying x87 rules to
>> things that (AIUI) are never stored in x87 registers, and so losing
> Yes, it can be optimized since some mode will never assigned to x87 registers.
>> performance as a result.
>>
>> Note that the RA also uses ALL_REGS for some things, so this usage
>> isn't specific to non-RA code.
> RA passes the minimal reg class(REGNO_REG_CLASS) which contains REGN
> to decide if can_change_mode_class, not ALL_REGS.
> 511/* Given a hard REGN a FROM mode and a TO mode, return true if
> 512   REGN can change from mode FROM to mode TO.  */
> 513#define REG_CAN_CHANGE_MODE_P(REGN, FROM, TO)  \
> 514  (targetm.can_change_mode_class (FROM, TO, REGNO_REG_CLASS (REGN)))
> 515
>
> So I still think using can_change_mode_class outside of RA with
> ALL_REGS passed to decide whether it's ok to generate subreg is not a
> good idea.

But if the argument is that the only valid uses of can_change_mode_class
are through this macro, the hook isn't describing a class property,

Re: [committed] libstdc++: Improve performance of chrono::utc_clock::now()

2022-11-17 Thread Jonathan Wakely via Gcc-patches
On Thu, 17 Nov 2022 at 09:25, Daniel Krügler 
wrote:

> Am Do., 17. Nov. 2022 um 10:07 Uhr schrieb Jonathan Wakely
> :
> >
> >
> >
> > On Thu, 17 Nov 2022, 06:30 Daniel Krügler via Libstdc++, <
> libstd...@gcc.gnu.org> wrote:
> >>
> >> Am Mi., 16. Nov. 2022 um 22:00 Uhr schrieb Jonathan Wakely via
> >> Libstdc++ :
> >> >
> >> > Tested x86_64-linux. Pushed to trunk.
> >> >
> >> > -- >8 --
> >> >
> >> > We can use an array instead of a std::vector, and we can avoid the
> >> > binary search for the common case of a time point after the most
> recent
> >> > leap second. On one system where I tested this, utc_clock::now() now
> >> > takes about 16ns instead of 31ns.
> >> >
> >> > libstdc++-v3/ChangeLog:
> >> >
> >> > * include/std/chrono (get_leap_second_info): Optimize.
> >> > ---
> >> >  libstdc++-v3/include/std/chrono | 31 ---
> >> >  1 file changed, 24 insertions(+), 7 deletions(-)
> >> >
> >> > diff --git a/libstdc++-v3/include/std/chrono
> b/libstdc++-v3/include/std/chrono
> >> > index 90b73f8198e..2468023f6c5 100644
> >> > --- a/libstdc++-v3/include/std/chrono
> >> > +++ b/libstdc++-v3/include/std/chrono
> >> > @@ -2747,9 +2747,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >> >{
> >> > if constexpr (is_same_v<_Duration, seconds>)
> >> >   {
> >> > -   // TODO move this function into the library and get leaps
> from tzdb.
> >> > -   vector __leaps
> >> > -   {
> >> > +   const seconds::rep __leaps[] {
> >> > 78796800, // 1 Jul 1972
> >> > 94694400, // 1 Jan 1973
> >> >126230400, // 1 Jan 1974
> >> > @@ -2778,12 +2776,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >> >   1435708800, // 1 Jul 2015
> >> >   1483228800, // 1 Jan 2017
> >> > };
> >> > +   // The list above is known to be valid until 2023-06-28
> 00:00:00 UTC
> >> > +   const seconds::rep __expires = 1687910400;
> >> > +   const seconds::rep __s = __ut.time_since_epoch().count();
> >> >
> >> > -   auto __s = __ut.time_since_epoch().count();
> >> > -   auto __pos = std::upper_bound(__leaps.begin(),
> __leaps.end(), __s);
> >> > +   const seconds::rep* __first = std::begin(__leaps);
> >> > +   const seconds::rep* __last = std::end(__leaps);
> >> > +
> >> > +   if (__s > __expires)
> >> > + {
> >> > +   // TODO: use updated leap_seconds from tzdb
> >> > +#if 0
> >> > +   auto __db = get_tzdb_list().begin();
> >> > +   __first = __db->leap_seconds.data();
> >> > +   __last = __first + __db->leap_seconds.size();
> >> > +#endif
> >> > + }
> >> > +
> >> > +   // Don't bother searching the list if we're after the
> last one.
> >> > +   if (__s > __last[-1])
> >> > + return { false, seconds(__last - __first) };
> >> > +
> >> > +   auto __pos = std::upper_bound(__first, __last, __s);
> >> > return {
> >> > - __pos != __leaps.begin() && __pos[-1] == __s,
> >> > - seconds{__pos - __leaps.begin()}
> >> > + __pos != begin(__leaps) && __pos[-1] == __s,
> >>
> >> The inconsistency between usage of std::begin versus begin here seems
> >> odd and I'm wondering why instead of "begin(__leaps)" the above
> >> introduced "__first" variable is not used instead.
> >
> >
> > Because this code is going to be changed again soon, this is a partial
> merge from a local branch with the TODO fixed. Yes, it's inconsistent, but
> it works correctly and it's not my priority right now :-)
>
> What about the suggestion to use the already existing "__first"
> variable instead of the begin call?
>

It's an array, the begin call is free.


Re: [committed] libstdc++: Improve performance of chrono::utc_clock::now()

2022-11-17 Thread Jonathan Wakely via Gcc-patches
On Thu, 17 Nov 2022 at 09:47, Jonathan Wakely  wrote:

>
>
> On Thu, 17 Nov 2022 at 09:25, Daniel Krügler 
> wrote:
>
>> Am Do., 17. Nov. 2022 um 10:07 Uhr schrieb Jonathan Wakely
>> :
>> >
>> >
>> >
>> > On Thu, 17 Nov 2022, 06:30 Daniel Krügler via Libstdc++, <
>> libstd...@gcc.gnu.org> wrote:
>> >>
>> >> Am Mi., 16. Nov. 2022 um 22:00 Uhr schrieb Jonathan Wakely via
>> >> Libstdc++ :
>> >> >
>> >> > Tested x86_64-linux. Pushed to trunk.
>> >> >
>> >> > -- >8 --
>> >> >
>> >> > We can use an array instead of a std::vector, and we can avoid the
>> >> > binary search for the common case of a time point after the most
>> recent
>> >> > leap second. On one system where I tested this, utc_clock::now() now
>> >> > takes about 16ns instead of 31ns.
>> >> >
>> >> > libstdc++-v3/ChangeLog:
>> >> >
>> >> > * include/std/chrono (get_leap_second_info): Optimize.
>> >> > ---
>> >> >  libstdc++-v3/include/std/chrono | 31 ---
>> >> >  1 file changed, 24 insertions(+), 7 deletions(-)
>> >> >
>> >> > diff --git a/libstdc++-v3/include/std/chrono
>> b/libstdc++-v3/include/std/chrono
>> >> > index 90b73f8198e..2468023f6c5 100644
>> >> > --- a/libstdc++-v3/include/std/chrono
>> >> > +++ b/libstdc++-v3/include/std/chrono
>> >> > @@ -2747,9 +2747,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> >> >{
>> >> > if constexpr (is_same_v<_Duration, seconds>)
>> >> >   {
>> >> > -   // TODO move this function into the library and get
>> leaps from tzdb.
>> >> > -   vector __leaps
>> >> > -   {
>> >> > +   const seconds::rep __leaps[] {
>> >> > 78796800, // 1 Jul 1972
>> >> > 94694400, // 1 Jan 1973
>> >> >126230400, // 1 Jan 1974
>> >> > @@ -2778,12 +2776,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> >> >   1435708800, // 1 Jul 2015
>> >> >   1483228800, // 1 Jan 2017
>> >> > };
>> >> > +   // The list above is known to be valid until 2023-06-28
>> 00:00:00 UTC
>> >> > +   const seconds::rep __expires = 1687910400;
>> >> > +   const seconds::rep __s = __ut.time_since_epoch().count();
>> >> >
>> >> > -   auto __s = __ut.time_since_epoch().count();
>> >> > -   auto __pos = std::upper_bound(__leaps.begin(),
>> __leaps.end(), __s);
>> >> > +   const seconds::rep* __first = std::begin(__leaps);
>> >> > +   const seconds::rep* __last = std::end(__leaps);
>> >> > +
>> >> > +   if (__s > __expires)
>> >> > + {
>> >> > +   // TODO: use updated leap_seconds from tzdb
>> >> > +#if 0
>> >> > +   auto __db = get_tzdb_list().begin();
>> >> > +   __first = __db->leap_seconds.data();
>> >> > +   __last = __first + __db->leap_seconds.size();
>> >> > +#endif
>> >> > + }
>> >> > +
>> >> > +   // Don't bother searching the list if we're after the
>> last one.
>> >> > +   if (__s > __last[-1])
>> >> > + return { false, seconds(__last - __first) };
>> >> > +
>> >> > +   auto __pos = std::upper_bound(__first, __last, __s);
>> >> > return {
>> >> > - __pos != __leaps.begin() && __pos[-1] == __s,
>> >> > - seconds{__pos - __leaps.begin()}
>> >> > + __pos != begin(__leaps) && __pos[-1] == __s,
>> >>
>> >> The inconsistency between usage of std::begin versus begin here seems
>> >> odd and I'm wondering why instead of "begin(__leaps)" the above
>> >> introduced "__first" variable is not used instead.
>> >
>> >
>> > Because this code is going to be changed again soon, this is a partial
>> merge from a local branch with the TODO fixed. Yes, it's inconsistent, but
>> it works correctly and it's not my priority right now :-)
>>
>> What about the suggestion to use the already existing "__first"
>> variable instead of the begin call?
>>
>
> It's an array, the begin call is free.
>

Do you really want me to stop working on the missing time zone support to
test and commit that change?


[PATCH] Ver.2: Add compile option "-msmall-data-limit=0" to avoid using .srodata section for riscv.

2022-11-17 Thread Yixuan Chen
2022-11-17  Yixuan Chen  

* gcc/testsuite/gcc.dg/pr25521.c: Add compile option 
"-msmall-data-limit=0" to avoid using .srodata section for riscv.
---
 gcc/testsuite/gcc.dg/pr25521.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/pr25521.c b/gcc/testsuite/gcc.dg/pr25521.c
index 74fe2ae6626..628ddf1a761 100644
--- a/gcc/testsuite/gcc.dg/pr25521.c
+++ b/gcc/testsuite/gcc.dg/pr25521.c
@@ -2,7 +2,8 @@
sections.
 
{ dg-require-effective-target elf }
-   { dg-do compile } */
+   { dg-do compile }
+   { dg-options "-msmall-data-limit=0" { target { riscv*-*-* } } } */
 
 const volatile int foo = 30;
 
-- 
2.37.2



Re: [committed] libstdc++: Improve performance of chrono::utc_clock::now()

2022-11-17 Thread Daniel Krügler via Gcc-patches
Am Do., 17. Nov. 2022 um 10:48 Uhr schrieb Jonathan Wakely :
>
>
>
> On Thu, 17 Nov 2022 at 09:47, Jonathan Wakely  wrote:
>>
>>
>>
>> On Thu, 17 Nov 2022 at 09:25, Daniel Krügler  
>> wrote:
>>>
>>> Am Do., 17. Nov. 2022 um 10:07 Uhr schrieb Jonathan Wakely
>>> :
>>> >
>>> >
>>> >
>>> > On Thu, 17 Nov 2022, 06:30 Daniel Krügler via Libstdc++, 
>>> >  wrote:
>>> >>
>>> >> Am Mi., 16. Nov. 2022 um 22:00 Uhr schrieb Jonathan Wakely via
>>> >> Libstdc++ :
>>> >> >
>>> >> > Tested x86_64-linux. Pushed to trunk.
>>> >> >
>>> >> > -- >8 --
>>> >> >
>>> >> > We can use an array instead of a std::vector, and we can avoid the
>>> >> > binary search for the common case of a time point after the most recent
>>> >> > leap second. On one system where I tested this, utc_clock::now() now
>>> >> > takes about 16ns instead of 31ns.
>>> >> >
>>> >> > libstdc++-v3/ChangeLog:
>>> >> >
>>> >> > * include/std/chrono (get_leap_second_info): Optimize.
>>> >> > ---
>>> >> >  libstdc++-v3/include/std/chrono | 31 ---
>>> >> >  1 file changed, 24 insertions(+), 7 deletions(-)
>>> >> >
>>> >> > diff --git a/libstdc++-v3/include/std/chrono 
>>> >> > b/libstdc++-v3/include/std/chrono
>>> >> > index 90b73f8198e..2468023f6c5 100644
>>> >> > --- a/libstdc++-v3/include/std/chrono
>>> >> > +++ b/libstdc++-v3/include/std/chrono
>>> >> > @@ -2747,9 +2747,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>> >> >{
>>> >> > if constexpr (is_same_v<_Duration, seconds>)
>>> >> >   {
>>> >> > -   // TODO move this function into the library and get leaps 
>>> >> > from tzdb.
>>> >> > -   vector __leaps
>>> >> > -   {
>>> >> > +   const seconds::rep __leaps[] {
>>> >> > 78796800, // 1 Jul 1972
>>> >> > 94694400, // 1 Jan 1973
>>> >> >126230400, // 1 Jan 1974
>>> >> > @@ -2778,12 +2776,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>> >> >   1435708800, // 1 Jul 2015
>>> >> >   1483228800, // 1 Jan 2017
>>> >> > };
>>> >> > +   // The list above is known to be valid until 2023-06-28 
>>> >> > 00:00:00 UTC
>>> >> > +   const seconds::rep __expires = 1687910400;
>>> >> > +   const seconds::rep __s = __ut.time_since_epoch().count();
>>> >> >
>>> >> > -   auto __s = __ut.time_since_epoch().count();
>>> >> > -   auto __pos = std::upper_bound(__leaps.begin(), 
>>> >> > __leaps.end(), __s);
>>> >> > +   const seconds::rep* __first = std::begin(__leaps);
>>> >> > +   const seconds::rep* __last = std::end(__leaps);
>>> >> > +
>>> >> > +   if (__s > __expires)
>>> >> > + {
>>> >> > +   // TODO: use updated leap_seconds from tzdb
>>> >> > +#if 0
>>> >> > +   auto __db = get_tzdb_list().begin();
>>> >> > +   __first = __db->leap_seconds.data();
>>> >> > +   __last = __first + __db->leap_seconds.size();
>>> >> > +#endif
>>> >> > + }
>>> >> > +
>>> >> > +   // Don't bother searching the list if we're after the last 
>>> >> > one.
>>> >> > +   if (__s > __last[-1])
>>> >> > + return { false, seconds(__last - __first) };
>>> >> > +
>>> >> > +   auto __pos = std::upper_bound(__first, __last, __s);
>>> >> > return {
>>> >> > - __pos != __leaps.begin() && __pos[-1] == __s,
>>> >> > - seconds{__pos - __leaps.begin()}
>>> >> > + __pos != begin(__leaps) && __pos[-1] == __s,
>>> >>
>>> >> The inconsistency between usage of std::begin versus begin here seems
>>> >> odd and I'm wondering why instead of "begin(__leaps)" the above
>>> >> introduced "__first" variable is not used instead.
>>> >
>>> >
>>> > Because this code is going to be changed again soon, this is a partial 
>>> > merge from a local branch with the TODO fixed. Yes, it's inconsistent, 
>>> > but it works correctly and it's not my priority right now :-)
>>>
>>> What about the suggestion to use the already existing "__first"
>>> variable instead of the begin call?
>>
>>
>> It's an array, the begin call is free.
>
> Do you really want me to stop working on the missing time zone support to 
> test and commit that change?

I do not. I was reviewing and hoping to make a useful comment.

Thanks,

- Daniel


[PATCH v4] LoongArch: Optimize immediate load.

2022-11-17 Thread Lulu Cheng
v1 -> v2:
1. Change the code format.
2. Fix bugs in the code.

v2 -> v3:
Modifying a code implementation of an undefined behavior.

v3 -> v4:
Move the part of the immediate number decomposition from expand pass to split
pass.

Both regression tests and spec2006 passed.

The problem mentioned in the link does not move the four immediate load
instructions out of the loop. It has been optimized. Now, as in the test case,
four immediate load instructions are generated outside the loop.
(https://sourceware.org/pipermail/libc-alpha/2022-September/142202.html)


Because loop2_invariant pass will extract the instructions that do not change
in the loop out of the loop, some instructions will not meet the extraction
conditions if the machine performs immediate decomposition while expand pass,
so the immediate decomposition will be transferred to the split process.

gcc/ChangeLog:

* config/loongarch/loongarch.cc (enum loongarch_load_imm_method):
Remove the member METHOD_INSV that is not currently used.
(struct loongarch_integer_op): Define a new member curr_value,
that records the value of the number stored in the destination
register immediately after the current instruction has run.
(loongarch_build_integer): Assign a value to the curr_value member 
variable.
(loongarch_move_integer): Adds information for the immediate load 
instruction.
* config/loongarch/loongarch.md (*movdi_32bit): Redefine as 
define_insn_and_split.
(*movdi_64bit): Likewise.
(*movsi_internal): Likewise.
(*movhi_internal): Likewise.
* config/loongarch/predicates.md: Return true as long as it is 
CONST_INT, ensure
that the immediate number is not optimized by decomposition during 
expand
optimization loop.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/imm-load.c: New test.
* gcc.target/loongarch/imm-load1.c: New test.
---
 gcc/config/loongarch/loongarch.cc | 62 ++-
 gcc/config/loongarch/loongarch.md | 44 +++--
 gcc/config/loongarch/predicates.md|  2 +-
 gcc/testsuite/gcc.target/loongarch/imm-load.c | 10 +++
 .../gcc.target/loongarch/imm-load1.c  | 26 
 5 files changed, 110 insertions(+), 34 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/imm-load.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/imm-load1.c

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index 8ee32c90573..9e0d6c7c3ea 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -139,22 +139,21 @@ struct loongarch_address_info
 
METHOD_LU52I:
  Load 52-63 bit of the immediate number.
-
-   METHOD_INSV:
- immediate like 0xfff0fxxx
-   */
+*/
 enum loongarch_load_imm_method
 {
   METHOD_NORMAL,
   METHOD_LU32I,
-  METHOD_LU52I,
-  METHOD_INSV
+  METHOD_LU52I
 };
 
 struct loongarch_integer_op
 {
   enum rtx_code code;
   HOST_WIDE_INT value;
+  /* Represent the result of the immediate count of the load instruction at
+ each step.  */
+  HOST_WIDE_INT curr_value;
   enum loongarch_load_imm_method method;
 };
 
@@ -1475,24 +1474,27 @@ loongarch_build_integer (struct loongarch_integer_op 
*codes,
 {
   /* The value of the lower 32 bit be loaded with one instruction.
 lu12i.w.  */
-  codes[0].code = UNKNOWN;
-  codes[0].method = METHOD_NORMAL;
-  codes[0].value = low_part;
+  codes[cost].code = UNKNOWN;
+  codes[cost].method = METHOD_NORMAL;
+  codes[cost].value = low_part;
+  codes[cost].curr_value = low_part;
   cost++;
 }
   else
 {
   /* lu12i.w + ior.  */
-  codes[0].code = UNKNOWN;
-  codes[0].method = METHOD_NORMAL;
-  codes[0].value = low_part & ~(IMM_REACH - 1);
+  codes[cost].code = UNKNOWN;
+  codes[cost].method = METHOD_NORMAL;
+  codes[cost].value = low_part & ~(IMM_REACH - 1);
+  codes[cost].curr_value = codes[cost].value;
   cost++;
   HOST_WIDE_INT iorv = low_part & (IMM_REACH - 1);
   if (iorv != 0)
{
- codes[1].code = IOR;
- codes[1].method = METHOD_NORMAL;
- codes[1].value = iorv;
+ codes[cost].code = IOR;
+ codes[cost].method = METHOD_NORMAL;
+ codes[cost].value = iorv;
+ codes[cost].curr_value = low_part;
  cost++;
}
 }
@@ -1515,11 +1517,14 @@ loongarch_build_integer (struct loongarch_integer_op 
*codes,
{
  codes[cost].method = METHOD_LU52I;
  codes[cost].value = value & LU52I_B;
+ codes[cost].curr_value = value;
  return cost + 1;
}
 
   codes[cost].method = METHOD_LU32I;
   codes[cost].value = (value & LU32I_B) | (sign51 ? LU52I_B : 0);
+  codes[cost].curr_value = (value & 0xf)
+   | (sign51 ? LU52I_B : 0);
   cost++;

Re: [committed] libstdc++: Improve performance of chrono::utc_clock::now()

2022-11-17 Thread Ville Voutilainen via Gcc-patches
On Thu, 17 Nov 2022 at 11:57, Daniel Krügler via Libstdc++
 wrote:

> > Do you really want me to stop working on the missing time zone support to 
> > test and commit that change?
>
> I do not. I was reviewing and hoping to make a useful comment.

Looks like someone's crunching to make a stage3 deadline, he gets a
bit testy during those times. :) He'll
return to his normal jolly self soon, don't worry, Daniel. :)


Re: [PATCH 3/8]middle-end: Support extractions of subvectors from arbitrary element position inside a vector

2022-11-17 Thread Hongtao Liu via Gcc-patches
On Thu, Nov 17, 2022 at 5:39 PM Richard Sandiford
 wrote:
>
> Hongtao Liu  writes:
> > On Wed, Nov 16, 2022 at 1:39 AM Richard Sandiford
> >  wrote:
> >>
> >> Tamar Christina  writes:
> >> >> -Original Message-
> >> >> From: Hongtao Liu 
> >> >> Sent: Tuesday, November 15, 2022 9:37 AM
> >> >> To: Tamar Christina 
> >> >> Cc: Richard Sandiford ; Tamar Christina via
> >> >> Gcc-patches ; nd ;
> >> >> rguent...@suse.de
> >> >> Subject: Re: [PATCH 3/8]middle-end: Support extractions of subvectors 
> >> >> from
> >> >> arbitrary element position inside a vector
> >> >>
> >> >> On Tue, Nov 15, 2022 at 4:51 PM Tamar Christina
> >> >>  wrote:
> >> >> >
> >> >> > > -Original Message-
> >> >> > > From: Hongtao Liu 
> >> >> > > Sent: Tuesday, November 15, 2022 8:36 AM
> >> >> > > To: Tamar Christina 
> >> >> > > Cc: Richard Sandiford ; Tamar Christina
> >> >> > > via Gcc-patches ; nd ;
> >> >> > > rguent...@suse.de
> >> >> > > Subject: Re: [PATCH 3/8]middle-end: Support extractions of
> >> >> > > subvectors from arbitrary element position inside a vector
> >> >> > >
> >> >> > > Hi:
> >> >> > >   I'm from https://gcc.gnu.org/pipermail/gcc-patches/2022-
> >> >> > > November/606040.html.
> >> >> > > >  }
> >> >> > > >
> >> >> > > >/* See if we can get a better vector mode before extracting.
> >> >> > > > */ diff --git a/gcc/optabs.cc b/gcc/optabs.cc index
> >> >> > > >
> >> >> > >
> >> >> cff37ccb0dfc3dd79b97d0abfd872f340855dc96..f338df410265dfe55b68961600
> >> >> > > 9
> >> >> > > 0
> >> >> > > > a453cc6a28d9 100644
> >> >> > > > --- a/gcc/optabs.cc
> >> >> > > > +++ b/gcc/optabs.cc
> >> >> > > > @@ -6267,6 +6267,7 @@ expand_vec_perm_const (machine_mode
> >> >> mode,
> >> >> > > rtx v0, rtx v1,
> >> >> > > >v0_qi = gen_lowpart (qimode, v0);
> >> >> > > >v1_qi = gen_lowpart (qimode, v1);
> >> >> > > >if (targetm.vectorize.vec_perm_const != NULL
> >> >> > > > + && targetm.can_change_mode_class (mode, qimode,
> >> >> > > > + ALL_REGS)
> >> >> > > It looks like you want to guard gen_lowpart, shouldn't it be better
> >> >> > > to use validate_subreg  or (tmp = gen_lowpart_if_possible (mode,
> >> >> target_qi)).
> >> >> > > IMHO, targetm.can_change_mode_class is mostly used for RA, but not
> >> >> > > to guard gen_lowpart.
> >> >> >
> >> >> > Hmm I don't think this is quite true, there are existing usages in
> >> >> > expr.cc and rtanal.cc That do this and aren't part of RA.  As I
> >> >> > mentioned before for instance the canoncalization of vec_select to 
> >> >> > subreg
> >> >> in rtlanal for instances uses this.
> >> >> In theory, we need to iterate through all reg classes that can be 
> >> >> assigned for
> >> >> both qimode and mode, if any regclass returns true for
> >> >> targetm.can_change_mode_class, the bitcast(validate_subreg) should be 
> >> >> ok.
> >> >> Here we just passed ALL_REGS.
> >> >
> >> > Yes, and most targets where this transformation is valid return true 
> >> > here.
> >> >
> >> > I've checked:
> >> >  * alpha
> >> >  * arm
> >> >  * aarch64
> >> >  * rs6000
> >> >  * s390
> >> >  * sparc
> >> >  * pa
> >> >  * mips
> >> >
> >> > And even the default example that other targets use from the 
> >> > documentation
> >> > would return true as the size of the modes are the same.
> >> >
> >> > X86 and RISCV are the only two targets that I found (but didn't check 
> >> > all) that
> >> > blankly return a result based on just the register classes.
> >> >
> >> > That is to say, there are more targets that adhere to the interpretation 
> >> > that
> >> > rclass here means "should be possible in some class in rclass" rather 
> >> > than
> >> > "should be possible in ALL classes of rclass".
> >>
> >> Yeah, I agree.  A query "can something stored in ALL_REGS change from
> >> mode M1 to mode M2?" is meaningful if at least one register R in ALL_REGS
> >> can hold both M1 and M2.  It's then the target's job to answer
> >> conservatively so that the result covers all such R.
> >>
> >> In principle it's OK for a target to err on the side of caution and forbid
> >> things that are actually OK.  But that's going to risk losing performance
> >> in some cases, and sometimes that loss of performance will be unacceptable.
> >> IMO that's what's happening here.  The target is applying x87 rules to
> >> things that (AIUI) are never stored in x87 registers, and so losing
> > Yes, it can be optimized since some mode will never assigned to x87 
> > registers.
> >> performance as a result.
> >>
> >> Note that the RA also uses ALL_REGS for some things, so this usage
> >> isn't specific to non-RA code.
> > RA passes the minimal reg class(REGNO_REG_CLASS) which contains REGN
> > to decide if can_change_mode_class, not ALL_REGS.
> > 511/* Given a hard REGN a FROM mode and a TO mode, return true if
> > 512   REGN can change from mode FROM to mode TO.  */
> > 513#define REG_CAN_CHANGE_MODE_P(REGN, FROM, TO)  \
> > 514  (targetm.can_change_mode_class (FR

Re: [committed] libstdc++: Improve performance of chrono::utc_clock::now()

2022-11-17 Thread Jonathan Wakely via Gcc-patches
On Thu, 17 Nov 2022 at 09:57, Daniel Krügler 
wrote:

> Am Do., 17. Nov. 2022 um 10:48 Uhr schrieb Jonathan Wakely <
> jwak...@redhat.com>:
> >
> >
> >
> > On Thu, 17 Nov 2022 at 09:47, Jonathan Wakely 
> wrote:
> >>
> >>
> >>
> >> On Thu, 17 Nov 2022 at 09:25, Daniel Krügler 
> wrote:
> >>>
> >>> Am Do., 17. Nov. 2022 um 10:07 Uhr schrieb Jonathan Wakely
> >>> :
> >>> >
> >>> >
> >>> >
> >>> > On Thu, 17 Nov 2022, 06:30 Daniel Krügler via Libstdc++, <
> libstd...@gcc.gnu.org> wrote:
> >>> >>
> >>> >> Am Mi., 16. Nov. 2022 um 22:00 Uhr schrieb Jonathan Wakely via
> >>> >> Libstdc++ :
> >>> >> >
> >>> >> > Tested x86_64-linux. Pushed to trunk.
> >>> >> >
> >>> >> > -- >8 --
> >>> >> >
> >>> >> > We can use an array instead of a std::vector, and we can avoid the
> >>> >> > binary search for the common case of a time point after the most
> recent
> >>> >> > leap second. On one system where I tested this, utc_clock::now()
> now
> >>> >> > takes about 16ns instead of 31ns.
> >>> >> >
> >>> >> > libstdc++-v3/ChangeLog:
> >>> >> >
> >>> >> > * include/std/chrono (get_leap_second_info): Optimize.
> >>> >> > ---
> >>> >> >  libstdc++-v3/include/std/chrono | 31
> ---
> >>> >> >  1 file changed, 24 insertions(+), 7 deletions(-)
> >>> >> >
> >>> >> > diff --git a/libstdc++-v3/include/std/chrono
> b/libstdc++-v3/include/std/chrono
> >>> >> > index 90b73f8198e..2468023f6c5 100644
> >>> >> > --- a/libstdc++-v3/include/std/chrono
> >>> >> > +++ b/libstdc++-v3/include/std/chrono
> >>> >> > @@ -2747,9 +2747,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >>> >> >{
> >>> >> > if constexpr (is_same_v<_Duration, seconds>)
> >>> >> >   {
> >>> >> > -   // TODO move this function into the library and get
> leaps from tzdb.
> >>> >> > -   vector __leaps
> >>> >> > -   {
> >>> >> > +   const seconds::rep __leaps[] {
> >>> >> > 78796800, // 1 Jul 1972
> >>> >> > 94694400, // 1 Jan 1973
> >>> >> >126230400, // 1 Jan 1974
> >>> >> > @@ -2778,12 +2776,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >>> >> >   1435708800, // 1 Jul 2015
> >>> >> >   1483228800, // 1 Jan 2017
> >>> >> > };
> >>> >> > +   // The list above is known to be valid until
> 2023-06-28 00:00:00 UTC
> >>> >> > +   const seconds::rep __expires = 1687910400;
> >>> >> > +   const seconds::rep __s =
> __ut.time_since_epoch().count();
> >>> >> >
> >>> >> > -   auto __s = __ut.time_since_epoch().count();
> >>> >> > -   auto __pos = std::upper_bound(__leaps.begin(),
> __leaps.end(), __s);
> >>> >> > +   const seconds::rep* __first = std::begin(__leaps);
> >>> >> > +   const seconds::rep* __last = std::end(__leaps);
> >>> >> > +
> >>> >> > +   if (__s > __expires)
> >>> >> > + {
> >>> >> > +   // TODO: use updated leap_seconds from tzdb
> >>> >> > +#if 0
> >>> >> > +   auto __db = get_tzdb_list().begin();
> >>> >> > +   __first = __db->leap_seconds.data();
> >>> >> > +   __last = __first + __db->leap_seconds.size();
> >>> >> > +#endif
> >>> >> > + }
> >>> >> > +
> >>> >> > +   // Don't bother searching the list if we're after the
> last one.
> >>> >> > +   if (__s > __last[-1])
> >>> >> > + return { false, seconds(__last - __first) };
> >>> >> > +
> >>> >> > +   auto __pos = std::upper_bound(__first, __last, __s);
> >>> >> > return {
> >>> >> > - __pos != __leaps.begin() && __pos[-1] == __s,
> >>> >> > - seconds{__pos - __leaps.begin()}
> >>> >> > + __pos != begin(__leaps) && __pos[-1] == __s,
> >>> >>
> >>> >> The inconsistency between usage of std::begin versus begin here
> seems
> >>> >> odd and I'm wondering why instead of "begin(__leaps)" the above
> >>> >> introduced "__first" variable is not used instead.
> >>> >
> >>> >
> >>> > Because this code is going to be changed again soon, this is a
> partial merge from a local branch with the TODO fixed. Yes, it's
> inconsistent, but it works correctly and it's not my priority right now :-)
> >>>
> >>> What about the suggestion to use the already existing "__first"
> >>> variable instead of the begin call?
> >>
> >>
> >> It's an array, the begin call is free.
> >
> > Do you really want me to stop working on the missing time zone support
> to test and commit that change?
>
> I do not. I was reviewing and hoping to make a useful comment.
>
>
It is useful and I do appreciate the review, but like I said, the code is
going to change soon anyway, so I don't see any point making tiny stylistic
changes now (there's no problem with ADL here, as the array contains
int64_t values, and calling begin on an array is cheap).

This is what I have in my local branch:

template
  leap_second_info
  get_leap_second_info(const utc_time<_Duration>& __ut)
  

[PATCH v3] Enable shrink wrapping for the RISC-V target.

2022-11-17 Thread Manolis Tsamis
This commit implements the target macros (TARGET_SHRINK_WRAP_*) that
enable separate shrink wrapping for function prologues/epilogues in
RISC-V.

Tested against SPEC CPU 2017, this change always has a net-positive
effect on the dynamic instruction count.  See the following table for
the breakdown on how this reduces the number of dynamic instructions
per workload on a like-for-like (i.e., same config file; suppressing
shrink-wrapping with -fno-shrink-wrap):

 # dynamic instructions
w/o shrink-wrap   w/ shrink-wrap  reduction
500.perlbench_r   12657167865931262156218578 3560568015   0.28%
500.perlbench_r779224795689 76533700902513887786664   1.78%
500.perlbench_r724087331471 71130715252212780178949   1.77%
502.gcc_r  204259864844 194517006339 9742858505   4.77%
502.gcc_r  244047794302 23155583472212491959580   5.12%
502.gcc_r  230896069400 221877703011 9018366389   3.91%
502.gcc_r  192130616624 183856450605 8274166019   4.31%
502.gcc_r  258875074079 2477562032268870853   4.30%
505.mcf_r  662653430325 660678680547 1974749778   0.30%
520.omnetpp_r  985114167068 93419131015450922856914   5.17%
523.xalancbmk_r927037633578 921688937650 5348695928   0.58%
525.x264_r 490953958454 490565583447  388375007   0.08%
525.x264_r19946622944211993171932425 1490361996   0.07%
525.x264_r18976171204501896062750609 1554369841   0.08%
531.deepsjeng_r   1695189878907166930413041125885748496   1.53%
541.leela_r   192594122189790086119828040361024   1.46%
548.exchange2_r   20738162279442073816226729   1215   0.00%
557.xz_r   379572090003 379057409041  514680962   0.14%
557.xz_r   953117469352 952680431430  437037922   0.05%
557.xz_r   536859579650 536456690164  402889486   0.08%
 18421773405376   18223938521833   197834883543   1.07%  totals

Signed-off-by: Manolis Tsamis 

gcc/ChangeLog:

* config/riscv/riscv.cc (struct machine_function): Add array to store
register wrapping information.
(riscv_for_each_saved_reg): Skip registers that are wrapped separetely.
(riscv_get_separate_components): New function.
(riscv_components_for_bb): Likewise.
(riscv_disqualify_components): Likewise.
(riscv_process_components): Likewise.
(riscv_emit_prologue_components): Likewise.
(riscv_emit_epilogue_components): Likewise.
(riscv_set_handled_components): Likewise.
(TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS): Define.
(TARGET_SHRINK_WRAP_COMPONENTS_FOR_BB): Likewise.
(TARGET_SHRINK_WRAP_DISQUALIFY_COMPONENTS): Likewise.
(TARGET_SHRINK_WRAP_EMIT_PROLOGUE_COMPONENTS): Likewise.
(TARGET_SHRINK_WRAP_EMIT_EPILOGUE_COMPONENTS): Likewise.
(TARGET_SHRINK_WRAP_SET_HANDLED_COMPONENTS): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/shrink-wrap-1.c: New test.

---

Changes in v3:
- Fixed code and comment formatting for testcase.
- Rebased code and resolved compile issues due to
  gp_sp_offset and GET_MODE_SIZE being poly_int.
- Add comments in riscv_get_separate_components
  that clarifies usage of SMALL_OPERAND for offsets.

 gcc/config/riscv/riscv.cc | 193 +-
 .../gcc.target/riscv/shrink-wrap-1.c  |  24 +++
 2 files changed, 215 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/shrink-wrap-1.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index ad57b995e7b..61a7d93dd3b 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "target.h"
+#include "backend.h"
 #include "tm.h"
 #include "rtl.h"
 #include "regs.h"
@@ -51,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "optabs.h"
 #include "bitmap.h"
 #include "df.h"
+#include "function-abi.h"
 #include "diagnostic.h"
 #include "builtins.h"
 #include "predict.h"
@@ -154,6 +156,11 @@ struct GTY(())  machine_function {
 
   /* The current frame information, calculated by riscv_compute_frame_info.  */
   struct riscv_frame_info frame;
+
+  /* The components already handled by separate shrink-wrapping, which should
+ not be considered by the prologue and epilogue.  */
+  bool reg_is_wrapped_separately[FIRST_PSEUDO_REGISTER];
+
 };
 
 /* Information about a single argument.  */
@@ -4681,7 +4688,7 @@ riscv_for_each_saved_reg (poly_int64 sp_offset, 
riscv_save_restore_fn fn,
   for (unsigned int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
 if (BITSET_P (cfun->machine->frame.mask, regno - GP_REG_FIRST))
   {
-   boo

Re: [PATCH] Enable shrink wrapping for the RISC-V target.

2022-11-17 Thread Manolis Tsamis
On Thu, Nov 17, 2022 at 4:09 AM Jeff Law  wrote:
>
>
> On 11/16/22 03:26, Manolis Tsamis wrote:
> > On Sun, Nov 13, 2022 at 3:33 AM Jeff Law via Gcc-patches
> >  wrote:
> >>
> >> On 11/7/22 15:07, Palmer Dabbelt wrote:
> >>> On Thu, 03 Nov 2022 15:23:28 PDT (-0700), j...@ventanamicro.com wrote:
>  On 11/2/22 18:26, Palmer Dabbelt wrote:
> >>> I also tried to remove that restriction but it looks like it can't
> >>> work because we can't create
> >>> pseudo-registers during shrink wrapping and shrink wrapping can't
> >>> work either.
> >>>
> >>> I believe this means that shrink wrapping cannot interfere with a
> >>> long
> >>> stack frame
> >>> so there is nothing to test against in this case?
> >> It'd be marginally better to have such a test case to ensure we don't
> >> shrink wrap it -- that would ensure that someone doesn't accidentally
> >> introduce shrink wrapping with large offsets.   Just a bit of future
> >> proofing.
> > If there's passing test cases that fail with that check removed then
> > it's probably good enough, though I think in this case just having a
> > comment there saying why the short-stack check is necessary should be
> > fine.
>  I can live with this.
> >>> Which one (or either)?  I'm fine with either option, just trying to
> >>> avoid another re-spin as this one is a bit vague.
> >> Sorry I wasn't clear.  Either is fine with me.
> >>
> > Since all issues/concerns around this are resolved, is the v2 of this patch
> > good for merging?
> >
> > Link for v2 patch is
> > https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603822.html
>
> You just need to add a comment to get_separate_components indicating
> that the SMALL_OPERAND_P check is required as we do not support
> shrink-wrapping with large stack frames.
>
>
> OK with that comment.  Just post the final version and commit, no need
> to wait for another review.
>
Final version (v3) for commiting is here
https://gcc.gnu.org/pipermail/gcc-patches/2022-November/606523.html

Thanks
>
> jeff
>


RE: [PATCH 2/2] aarch64: Add support for widening LDAPR instructions

2022-11-17 Thread Kyrylo Tkachov via Gcc-patches


> -Original Message-
> From: Richard Sandiford 
> Sent: Tuesday, November 15, 2022 6:05 PM
> To: Andre Simoes Dias Vieira 
> Cc: gcc-patches@gcc.gnu.org; Kyrylo Tkachov ;
> Richard Earnshaw 
> Subject: Re: [PATCH 2/2] aarch64: Add support for widening LDAPR
> instructions
> 
> "Andre Vieira (lists)"  writes:
> > Updated version of the patch to account for the testsuite changes in the
> > first patch.
> >
> > On 10/11/2022 11:20, Andre Vieira (lists) via Gcc-patches wrote:
> >> Hi,
> >>
> >> This patch adds support for the widening LDAPR instructions.
> >>
> >> Bootstrapped and regression tested on aarch64-none-linux-gnu.
> >>
> >> OK for trunk?
> >>
> >> 2022-11-09  Andre Vieira  
> >>     Kyrylo Tkachov  
> >>
> >> gcc/ChangeLog:
> >>
> >>     * config/aarch64/atomics.md
> >> (*aarch64_atomic_load_rcpc_zext): New pattern.
> >>     (*aarch64_atomic_load_rcpc_zext): Likewise.
> >>
> >> gcc/testsuite/ChangeLog:
> >>
> >>     * gcc.target/aarch64/ldapr-ext.c: New test.
> >
> > diff --git a/gcc/config/aarch64/atomics.md
> b/gcc/config/aarch64/atomics.md
> > index
> dc5f52ee8a4b349c0d8466a16196f83604893cbb..9670bef7d8cb2b32c5146536
> d806a7e8bdffb2e3 100644
> > --- a/gcc/config/aarch64/atomics.md
> > +++ b/gcc/config/aarch64/atomics.md
> > @@ -704,6 +704,28 @@
> >}
> >  )
> >
> > +(define_insn "*aarch64_atomic_load_rcpc_zext"
> > +  [(set (match_operand:GPI 0 "register_operand" "=r")
> > +(zero_extend:GPI
> > +  (unspec_volatile:ALLX
> > +[(match_operand:ALLX 1 "aarch64_sync_memory_operand" "Q")
> > + (match_operand:SI 2 "const_int_operand")] ;;
> model
> > +   UNSPECV_LDAP)))]
> > +  "TARGET_RCPC"
> > +  "ldapr\t%0, %1"
> 
> It would be good to add:
> 
>> 
> 
> to the condition, so that we don't provide bogus SI->SI and DI->DI
> extensions.  (They shouldn't be generated, but it's better not to provide
> them anyway.)
> 

I agree. I'm pushing the attached patch to trunk.

gcc/ChangeLog:

* config/aarch64/atomics.md (*aarch64_atomic_load_rcpc_zext):
Add mode size check to condition.
(*aarch64_atomic_load_rcpc_sext): Likewise.

> Thanks,
> Richard
> 
> > +)
> > +
> > +(define_insn "*aarch64_atomic_load_rcpc_sext"
> > +  [(set (match_operand:GPI  0 "register_operand" "=r")
> > +(sign_extend:GPI
> > +  (unspec_volatile:ALLX
> > +[(match_operand:ALLX 1 "aarch64_sync_memory_operand" "Q")
> > + (match_operand:SI 2 "const_int_operand")] ;;
> model
> > +   UNSPECV_LDAP)))]
> > +  "TARGET_RCPC"
> > +  "ldaprs\t%0, %1"
> > +)
> > +
> >  (define_insn "atomic_store"
> >[(set (match_operand:ALLI 0 "aarch64_rcpc_memory_operand" "=Q,Ust")
> >  (unspec_volatile:ALLI
> > diff --git a/gcc/testsuite/gcc.target/aarch64/ldapr-ext.c
> b/gcc/testsuite/gcc.target/aarch64/ldapr-ext.c
> > new file mode 100644
> > index
> ..aed27e06235b1d266decf11
> 745dacf94cc59e76d
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/aarch64/ldapr-ext.c
> > @@ -0,0 +1,94 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -std=c99" } */
> > +/* { dg-final { check-function-bodies "**" "" "" } } */
> > +#include 
> > +
> > +#pragma GCC target "+rcpc"
> > +
> > +atomic_ullong u64;
> > +atomic_llong s64;
> > +atomic_uint u32;
> > +atomic_int s32;
> > +atomic_ushort u16;
> > +atomic_short s16;
> > +atomic_uchar u8;
> > +atomic_schar s8;
> > +
> > +#define TEST(name, ldsize, rettype)\
> > +rettype\
> > +test_##name (void) \
> > +{  \
> > +  return atomic_load_explicit (&ldsize, memory_order_acquire); \
> > +}
> > +
> > +/*
> > +**test_u8_u64:
> > +**...
> > +** ldaprb  x0, \[x[0-9]+\]
> > +** ret
> > +*/
> > +
> > +TEST(u8_u64, u8, unsigned long long)
> > +
> > +/*
> > +**test_s8_s64:
> > +**...
> > +** ldaprsb x0, \[x[0-9]+\]
> > +** ret
> > +*/
> > +
> > +TEST(s8_s64, s8, long long)
> > +
> > +/*
> > +**test_u16_u64:
> > +**...
> > +** ldaprh  x0, \[x[0-9]+\]
> > +** ret
> > +*/
> > +
> > +TEST(u16_u64, u16, unsigned long long)
> > +
> > +/*
> > +**test_s16_s64:
> > +**...
> > +** ldaprsh x0, \[x[0-9]+\]
> > +** ret
> > +*/
> > +
> > +TEST(s16_s64, s16, long long)
> > +
> > +/*
> > +**test_u8_u32:
> > +**...
> > +** ldaprb  w0, \[x[0-9]+\]
> > +** ret
> > +*/
> > +
> > +TEST(u8_u32, u8, unsigned)
> > +
> > +/*
> > +**test_s8_s32:
> > +**...
> > +** ldaprsb w0, \[x[0-9]+\]
> > +** ret
> > +*/
> > +
> > +TEST(s8_s32, s8, int)
> > +
> > +/*
> > +**test_u16_u32:
> > +**...
> > +** ldaprh  w0, \[x[0-9]+\]
> > +** ret
> > +*/
> > +
> > +TEST(u16_u32, u16, unsigned)
> > +
> > +/*
> > +**test_s16_s32:
> > +**...
> > +** ldaprsh w0, \[x[0-9]+\]
> > +** ret
> > +*/
> > +
> > +TEST(s16_s32, s16, int)


ldapr-ext.patch
Description: ldapr-ext.patch


Re: [PATCH] Enable shrink wrapping for the RISC-V target.

2022-11-17 Thread Philipp Tomsich
v3 committed to master. Thanks!
Philipp.

On Thu, 17 Nov 2022 at 11:55, Manolis Tsamis 
wrote:

> On Thu, Nov 17, 2022 at 4:09 AM Jeff Law  wrote:
> >
> >
> > On 11/16/22 03:26, Manolis Tsamis wrote:
> > > On Sun, Nov 13, 2022 at 3:33 AM Jeff Law via Gcc-patches
> > >  wrote:
> > >>
> > >> On 11/7/22 15:07, Palmer Dabbelt wrote:
> > >>> On Thu, 03 Nov 2022 15:23:28 PDT (-0700), j...@ventanamicro.com
> wrote:
> >  On 11/2/22 18:26, Palmer Dabbelt wrote:
> > >>> I also tried to remove that restriction but it looks like it
> can't
> > >>> work because we can't create
> > >>> pseudo-registers during shrink wrapping and shrink wrapping can't
> > >>> work either.
> > >>>
> > >>> I believe this means that shrink wrapping cannot interfere with a
> > >>> long
> > >>> stack frame
> > >>> so there is nothing to test against in this case?
> > >> It'd be marginally better to have such a test case to ensure we
> don't
> > >> shrink wrap it -- that would ensure that someone doesn't
> accidentally
> > >> introduce shrink wrapping with large offsets.   Just a bit of
> future
> > >> proofing.
> > > If there's passing test cases that fail with that check removed
> then
> > > it's probably good enough, though I think in this case just having
> a
> > > comment there saying why the short-stack check is necessary should
> be
> > > fine.
> >  I can live with this.
> > >>> Which one (or either)?  I'm fine with either option, just trying to
> > >>> avoid another re-spin as this one is a bit vague.
> > >> Sorry I wasn't clear.  Either is fine with me.
> > >>
> > > Since all issues/concerns around this are resolved, is the v2 of this
> patch
> > > good for merging?
> > >
> > > Link for v2 patch is
> > > https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603822.html
> >
> > You just need to add a comment to get_separate_components indicating
> > that the SMALL_OPERAND_P check is required as we do not support
> > shrink-wrapping with large stack frames.
> >
> >
> > OK with that comment.  Just post the final version and commit, no need
> > to wait for another review.
> >
> Final version (v3) for commiting is here
> https://gcc.gnu.org/pipermail/gcc-patches/2022-November/606523.html
>
> Thanks
> >
> > jeff
> >
>


Re: [PATCHv2, rs6000] Enable have_cbranchcc4 on rs6000

2022-11-17 Thread David Edelsohn via Gcc-patches
On Thu, Nov 17, 2022 at 1:39 AM HAO CHEN GUI  wrote:

> Hi,
>   The patch enables have_cbrnachcc4 which is a flag in ifcvt.cc to
> indicate if branch by CC bits is invalid or not. The new expand pattern
> "cbranchcc4" is created which intend to match the pattern defined in
> "*cbranch", "*cbranch_2insn" and "*creturn". The operand sequence in
> "cbranchcc4" is inline with the definition in gccint. And the operand
> sequence doesn't matter in pattern matching. So I think it should work.
>
>   Compared to last version, one new predicate and one new expander are
> created.
>
>   Bootstrapped and tested on powerpc64-linux BE and LE with no regressions.
> Is this okay for trunk? Any recommendations? Thanks a lot.
>
> ChangeLog
> 2022-11-17  Haochen Gui 
>
> gcc/
> * config/rs6000/predicates.md (all_branch_comparison_operator):
> New,
> and includes operators in branch_comparison_operator and
> extra_insn_branch_comparison_operator.
> * config/rs6000/rs6000.md (cbranchcc4): New expand pattern.
>
> gcc/testsuite/
> * gcc.target/powerpc/cbranchcc4.c: New.
>
>
> patch.diff
> diff --git a/gcc/config/rs6000/predicates.md
> b/gcc/config/rs6000/predicates.md
> index b1fcc69bb60..843b6f39b84 100644
> --- a/gcc/config/rs6000/predicates.md
> +++ b/gcc/config/rs6000/predicates.md
> @@ -1308,6 +1308,7 @@ (define_special_predicate "equality_operator"
>
>  ;; Return 1 if OP is a comparison operation that is valid for a branch
>  ;; instruction.  We check the opcode against the mode of the CC value.
> +
>  ;; validate_condition_mode is an assertion.
>  (define_predicate "branch_comparison_operator"
> (and (match_operand 0 "comparison_operator")
> @@ -1331,6 +1332,11 @@ (define_predicate
> "extra_insn_branch_comparison_operator"
>   GET_MODE (XEXP (op, 0))),
>  1")))
>
> +;; Return 1 if OP is a comparison operation that is valid for a branch.
> +(define_predicate "all_branch_comparison_operator"
> +   (ior (match_operand 0 "branch_comparison_operator")
> +   (match_operand 0 "extra_insn_branch_comparison_operator")))
> +
>  ;; Return 1 if OP is an unsigned comparison operator.
>  (define_predicate "unsigned_comparison_operator"
>(match_code "ltu,gtu,leu,geu"))
> diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
> index e9e5cd1e54d..7b7d747a85d 100644
> --- a/gcc/config/rs6000/rs6000.md
> +++ b/gcc/config/rs6000/rs6000.md
> @@ -13067,6 +13067,16 @@ (define_insn_and_split "*_cc"
>  ;; Conditional branches.
>  ;; These either are a single bc insn, or a bc around a b.
>
> +(define_expand "cbranchcc4"
> +  [(set (pc)
> +   (if_then_else (match_operator 0 "all_branch_comparison_operator"
> +   [(match_operand 1 "cc_reg_operand")
> +(match_operand 2 "zero_constant")])
> + (label_ref (match_operand 3))
> + (pc)))]
> +  ""
> +  "")
> +
>

This is better, but the pattern should be near and after the existing
cbranch4 patterns earlier in the file, not the *cbranch pattern.  It
doesn't match the comment.

Why are you using zero_constant predicate instead of matching (const_int 0)
for operand 2?

Why does this need the new all_branch_comparison_operator?  Can the ifcvt
optimization correctly elide the 2 insn sequence?

Thanks, David


>  (define_insn "*cbranch"
>[(set (pc)
> (if_then_else (match_operator 1 "branch_comparison_operator"
> diff --git a/gcc/testsuite/gcc.target/powerpc/cbranchcc4.c
> b/gcc/testsuite/gcc.target/powerpc/cbranchcc4.c
> new file mode 100644
> index 000..528ba1a878d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/cbranchcc4.c
> @@ -0,0 +1,11 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-rtl-ce1" } */
> +/* { dg-final { scan-rtl-dump "noce_try_store_flag_constants" "ce1" } } */
> +
> +/* The inner branch should be detected by ifcvt then be converted to a
> setcc
> +   with a plus by noce_try_store_flag_constants.  */
> +
> +int test (unsigned int a, unsigned int b)
> +{
> +return (a < b ? 0 : (a > b ? 2 : 1));
> +}
>


[PATCH v3] c++: Allow module name to be a single letter on Windows

2022-11-17 Thread Torbjörn SVENSSON via Gcc-patches
v1 -> v2:
Paths without "C:" part can still be absolute if they start with / or
\ on Windows.

v2 -> v3:
Use alternative approach by having platform specific code in module.cc.

Truth table for the new expression:
c:\foo -> true
c:/foo -> true
/foo   -> true
\foo   -> true
c:foo  -> false
foo-> false
./foo  -> true
.\foo  -> true


Ok for trunk?

---

On Windows, the ':' character is special and when the module name is
a single character, like 'A', then the flatname would be (for
example) 'A:Foo'. On Windows, 'A:Foo' is treated as an absolute
path by the module loader and is likely not found.

Without this patch, the test case pr98944_c.C fails with:

In module imported at /src/gcc/testsuite/g++.dg/modules/pr98944_b.C:7:1,
of module A:Foo, imported at /src/gcc/testsuite/g++.dg/modules/pr98944_c.C:7:
A:Internals: error: header module expected, module 'A:Internals' found
A:Internals: error: failed to read compiled module: Bad file data
A:Internals: note: compiled module file is 'gcm.cache/A-Internals.gcm'
In module imported at /src/gcc/testsuite/g++.dg/modules/pr98944_c.C:7:8:
A:Foo: error: failed to read compiled module: Bad import dependency
A:Foo: note: compiled module file is 'gcm.cache/A-Foo.gcm'
A:Foo: fatal error: returning to the gate for a mechanical issue
compilation terminated.

gcc/cp/ChangeLog:

* module.cc: On Windows, 'A:Foo' is supposed to be a module
and not a path.

Tested on Windows with arm-none-eabi for Cortex-M3 in gcc-11 tree.

Co-Authored-By: Yvan ROUX 
Signed-off-by: Torbjörn SVENSSON 
---
 gcc/cp/module.cc | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 0e9af318ba4..fa41a86213f 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -13960,7 +13960,15 @@ get_module (tree name, module_state *parent, bool 
partition)
 static module_state *
 get_module (const char *ptr)
 {
-  if (ptr[0] == '.' ? IS_DIR_SEPARATOR (ptr[1]) : IS_ABSOLUTE_PATH (ptr))
+  /* On DOS based file systems, there is an ambiguity with A:B which can be
+ interpreted as a module Module:Partition or Drive:PATH.  Interpret strings
+ which clearly starts as pathnames as header-names and everything else is
+ treated as a (possibly malformed) named moduled.  */
+  if (IS_DIR_SEPARATOR (ptr[ptr[0] == '.']) // ./FOO or /FOO
+#if HAVE_DOS_BASED_FILE_SYSTEM
+  || (HAS_DRIVE_SPEC (ptr) && IS_DIR_SEPARATOR (ptr[2])) // A:/FOO
+#endif
+  || false)
 /* A header name.  */
 return get_module (build_string (strlen (ptr), ptr));
 
-- 
2.25.1



Re: [PATCH 3/8]middle-end: Support extractions of subvectors from arbitrary element position inside a vector

2022-11-17 Thread Richard Sandiford via Gcc-patches
Hongtao Liu  writes:
> On Thu, Nov 17, 2022 at 5:39 PM Richard Sandiford
>  wrote:
>>
>> Hongtao Liu  writes:
>> > On Wed, Nov 16, 2022 at 1:39 AM Richard Sandiford
>> >  wrote:
>> >>
>> >> Tamar Christina  writes:
>> >> >> -Original Message-
>> >> >> From: Hongtao Liu 
>> >> >> Sent: Tuesday, November 15, 2022 9:37 AM
>> >> >> To: Tamar Christina 
>> >> >> Cc: Richard Sandiford ; Tamar Christina via
>> >> >> Gcc-patches ; nd ;
>> >> >> rguent...@suse.de
>> >> >> Subject: Re: [PATCH 3/8]middle-end: Support extractions of subvectors 
>> >> >> from
>> >> >> arbitrary element position inside a vector
>> >> >>
>> >> >> On Tue, Nov 15, 2022 at 4:51 PM Tamar Christina
>> >> >>  wrote:
>> >> >> >
>> >> >> > > -Original Message-
>> >> >> > > From: Hongtao Liu 
>> >> >> > > Sent: Tuesday, November 15, 2022 8:36 AM
>> >> >> > > To: Tamar Christina 
>> >> >> > > Cc: Richard Sandiford ; Tamar Christina
>> >> >> > > via Gcc-patches ; nd ;
>> >> >> > > rguent...@suse.de
>> >> >> > > Subject: Re: [PATCH 3/8]middle-end: Support extractions of
>> >> >> > > subvectors from arbitrary element position inside a vector
>> >> >> > >
>> >> >> > > Hi:
>> >> >> > >   I'm from https://gcc.gnu.org/pipermail/gcc-patches/2022-
>> >> >> > > November/606040.html.
>> >> >> > > >  }
>> >> >> > > >
>> >> >> > > >/* See if we can get a better vector mode before extracting.
>> >> >> > > > */ diff --git a/gcc/optabs.cc b/gcc/optabs.cc index
>> >> >> > > >
>> >> >> > >
>> >> >> cff37ccb0dfc3dd79b97d0abfd872f340855dc96..f338df410265dfe55b68961600
>> >> >> > > 9
>> >> >> > > 0
>> >> >> > > > a453cc6a28d9 100644
>> >> >> > > > --- a/gcc/optabs.cc
>> >> >> > > > +++ b/gcc/optabs.cc
>> >> >> > > > @@ -6267,6 +6267,7 @@ expand_vec_perm_const (machine_mode
>> >> >> mode,
>> >> >> > > rtx v0, rtx v1,
>> >> >> > > >v0_qi = gen_lowpart (qimode, v0);
>> >> >> > > >v1_qi = gen_lowpart (qimode, v1);
>> >> >> > > >if (targetm.vectorize.vec_perm_const != NULL
>> >> >> > > > + && targetm.can_change_mode_class (mode, qimode,
>> >> >> > > > + ALL_REGS)
>> >> >> > > It looks like you want to guard gen_lowpart, shouldn't it be better
>> >> >> > > to use validate_subreg  or (tmp = gen_lowpart_if_possible (mode,
>> >> >> target_qi)).
>> >> >> > > IMHO, targetm.can_change_mode_class is mostly used for RA, but not
>> >> >> > > to guard gen_lowpart.
>> >> >> >
>> >> >> > Hmm I don't think this is quite true, there are existing usages in
>> >> >> > expr.cc and rtanal.cc That do this and aren't part of RA.  As I
>> >> >> > mentioned before for instance the canoncalization of vec_select to 
>> >> >> > subreg
>> >> >> in rtlanal for instances uses this.
>> >> >> In theory, we need to iterate through all reg classes that can be 
>> >> >> assigned for
>> >> >> both qimode and mode, if any regclass returns true for
>> >> >> targetm.can_change_mode_class, the bitcast(validate_subreg) should be 
>> >> >> ok.
>> >> >> Here we just passed ALL_REGS.
>> >> >
>> >> > Yes, and most targets where this transformation is valid return true 
>> >> > here.
>> >> >
>> >> > I've checked:
>> >> >  * alpha
>> >> >  * arm
>> >> >  * aarch64
>> >> >  * rs6000
>> >> >  * s390
>> >> >  * sparc
>> >> >  * pa
>> >> >  * mips
>> >> >
>> >> > And even the default example that other targets use from the 
>> >> > documentation
>> >> > would return true as the size of the modes are the same.
>> >> >
>> >> > X86 and RISCV are the only two targets that I found (but didn't check 
>> >> > all) that
>> >> > blankly return a result based on just the register classes.
>> >> >
>> >> > That is to say, there are more targets that adhere to the 
>> >> > interpretation that
>> >> > rclass here means "should be possible in some class in rclass" rather 
>> >> > than
>> >> > "should be possible in ALL classes of rclass".
>> >>
>> >> Yeah, I agree.  A query "can something stored in ALL_REGS change from
>> >> mode M1 to mode M2?" is meaningful if at least one register R in ALL_REGS
>> >> can hold both M1 and M2.  It's then the target's job to answer
>> >> conservatively so that the result covers all such R.
>> >>
>> >> In principle it's OK for a target to err on the side of caution and forbid
>> >> things that are actually OK.  But that's going to risk losing performance
>> >> in some cases, and sometimes that loss of performance will be 
>> >> unacceptable.
>> >> IMO that's what's happening here.  The target is applying x87 rules to
>> >> things that (AIUI) are never stored in x87 registers, and so losing
>> > Yes, it can be optimized since some mode will never assigned to x87 
>> > registers.
>> >> performance as a result.
>> >>
>> >> Note that the RA also uses ALL_REGS for some things, so this usage
>> >> isn't specific to non-RA code.
>> > RA passes the minimal reg class(REGNO_REG_CLASS) which contains REGN
>> > to decide if can_change_mode_class, not ALL_REGS.
>> > 511/* Given a hard REGN a FROM mode and a TO mode, return true if
>> > 512   REGN can change from

Re: [PATCH] RISC-V: Optimize masking with two clear bits not a SMALL_OPERAND

2022-11-17 Thread Jeff Law via Gcc-patches



On 11/10/22 14:36, Philipp Tomsich wrote:

Add a split for cases where we can use two bclri (or one bclri and an
andi) to clear two bits.

gcc/ChangeLog:

* config/riscv/bitmanip.md (*bclri_nottwobits): New pattern.
(*bclridisi_nottwobits): New pattern, handling the sign-bit.
* config/riscv/predicates.md (const_nottwobits_operand):
New predicate.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zbs-bclri.c: New test.


Don't we only have to worry about (subreg:DI (reg:SI )) to preserve the 
extension constraints?  Not that I think there's any value in allowing 
HI/QI, mostly wanting to double check my understanding of the extension 
constraints.



OK

jeff



Re: [PATCH v2] match.pd: rewrite select to branchless expression

2022-11-17 Thread Jeff Law via Gcc-patches



On 11/11/22 06:00, Michael Collison wrote:

Hi Prathamesh,

It is my understanding that INTEGRAL_TYPE_P applies to the other 
integer types you mentioned (chart, short, long). In fact the test 
function that motivated this match has a mixture of char and short and 
does not restrict matching.


What I think Prathamesh is asking is whether or not we want to have 
tests  with different types.   It's less about correctness I think and 
more about ensuring that the testsuite covers those tests in case they 
regress in the future.



jeff





Re: [PATCH] c++, v3: Implement C++23 P2647R1 - Permitting static constexpr variables in constexpr functions

2022-11-17 Thread Jason Merrill via Gcc-patches

On 11/17/22 04:13, Jakub Jelinek wrote:

On Wed, Nov 16, 2022 at 03:26:32PM -0500, Jason Merrill wrote:

On 11/16/22 09:46, Jakub Jelinek wrote:

On Wed, Nov 16, 2022 at 09:33:27AM -0500, Jason Merrill wrote:

and at that point I fear decl_maybe_constant_var_p will not work
properly.  Shall this hunk be moved somewhere else (cp_finish_decl?)
where we can already call it, or do the above in start_decl for
cxx_dialect < cxx20 and add a cxx_dialect == cxx20 hunk in cp_finish_decl?


Hmm, I'd expect decl_maybe_constant_var_p to work fine at this point.


For static constexpr vars sure, but what about
static const where start_decl doesn't know the initializer?
Sure, decl_maybe_constant_var_p will not crash in that case, but
it will return true even if the static const var doesn't have
a constant initializer.  Sure, we'd catch that later on when actually
trying to constexpr evaluate the function and hitting there the
spots added for C++23 in potential_constant_expression*/cxx_eval_*,
but it would mean that we don't reject it when nothing calls the functions.

I meant something like:
constexpr int bar (int x) { if (x) throw 1; return 0; }
constexpr int foo () { static const int a = bar (1); return 0; }
with -std=c++20 IMHO shouldn't be accepted, while in C++23 it should.


I'd expect us to reject that in C++20 in potential_constant_expression, but
it's a fair point; it is awkward that P2242 wasn't also accepted as a DR.


I pointed out that inconsistency on the reflectors, and it seems that 
EWG didn't actually intend P2647 to be a DR, either; it was a CWG error 
to propose it as such.  But let's go ahead and build on the work you've 
done.



Moving the check from start_decl to cp_finish_decl makes sense to me.


So like this?  I had to outline the check from start_decl to a function
because it is needed in cp_finish_decl in two different places (the
processing_template_decl path and at the end and it can't be done before the
processing_template_decl spot, because the initializer isn't finalized at
that point for !procesing_template_decl).  Also, decl_maybe_constant_var_p
doesn't do what is needed when !processing_template_decl, but I think
we want decl_maybe_constant_var_p in templates so that we don't instantiate
anything.

Lightly tested so far, ok for trunk if it passes full bootstrap/regtest?

2022-11-17  Jakub Jelinek  

gcc/c-family/
* c-cppbuiltin.cc (c_cpp_builtins): Bump __cpp_constexpr
value from 202207L to 202211L.
gcc/cp/
* constexpr.cc (cxx_eval_constant_expression): Implement C++23
P2647R1 - Permitting static constexpr variables in constexpr functions.
Allow decl_constant_var_p static or thread_local vars for
C++20 and later.
(potential_constant_expression_1): For C++20 or later, allow
static or thread_local decl_maybe_constant_var_p vars, for
!processing_template_decl only decl_constant_var_p vars.
* decl.cc (diagnose_static_in_constexpr): New function.
(start_decl): Use it for C++17 or earlier.
(cp_finish_decl): Call it for C++20.
gcc/testsuite/
* g++.dg/cpp23/constexpr-nonlit17.C: New test.
* g++.dg/cpp23/constexpr-nonlit18.C: New test.
* g++.dg/cpp23/feat-cxx2b.C: Adjust expected __cpp_constexpr
value.
* g++.dg/ext/stmtexpr19.C: Don't expect an error for C++20 or later.

--- gcc/c-family/c-cppbuiltin.cc.jj 2022-11-17 09:00:42.106249011 +0100
+++ gcc/c-family/c-cppbuiltin.cc2022-11-17 09:01:49.286320527 +0100
@@ -1074,7 +1074,7 @@ c_cpp_builtins (cpp_reader *pfile)
  /* Set feature test macros for C++23.  */
  cpp_define (pfile, "__cpp_size_t_suffix=202011L");
  cpp_define (pfile, "__cpp_if_consteval=202106L");
- cpp_define (pfile, "__cpp_constexpr=202207L");
+ cpp_define (pfile, "__cpp_constexpr=202211L");
  cpp_define (pfile, "__cpp_multidimensional_subscript=202211L");
  cpp_define (pfile, "__cpp_named_character_escapes=202207L");
  cpp_define (pfile, "__cpp_static_call_operator=202207L");
--- gcc/cp/constexpr.cc.jj  2022-11-17 08:48:30.530357181 +0100
+++ gcc/cp/constexpr.cc 2022-11-17 09:56:50.479522863 +0100
@@ -7098,7 +7098,8 @@ cxx_eval_constant_expression (const cons
&& (TREE_STATIC (r)
|| (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r)))
/* Allow __FUNCTION__ etc.  */
-   && !DECL_ARTIFICIAL (r))
+   && !DECL_ARTIFICIAL (r)
+   && (cxx_dialect < cxx20 || !decl_constant_var_p (r)))


I don't think we need to check cxx_dialect here since 
diagnose_static_in_constexpr will have already complained.



  {
if (!ctx->quiet)
  {
@@ -9588,7 +9589,12 @@ potential_constant_expression_1 (tree t,
tmp = DECL_EXPR_DECL (t);
if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp))
{
- if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp))
+ if (CP_DECL

Re: [PATCH] RISC-V: Optimize masking with two clear bits not a SMALL_OPERAND

2022-11-17 Thread Philipp Tomsich
On Thu, 17 Nov 2022 at 15:30, Jeff Law  wrote:
>
>
> On 11/10/22 14:36, Philipp Tomsich wrote:
> > Add a split for cases where we can use two bclri (or one bclri and an
> > andi) to clear two bits.
> >
> > gcc/ChangeLog:
> >
> >   * config/riscv/bitmanip.md (*bclri_nottwobits): New pattern.
> >   (*bclridisi_nottwobits): New pattern, handling the sign-bit.
> >   * config/riscv/predicates.md (const_nottwobits_operand):
> >   New predicate.
> >
> > gcc/testsuite/ChangeLog:
> >
> >   * gcc.target/riscv/zbs-bclri.c: New test.
>
> Don't we only have to worry about (subreg:DI (reg:SI )) to preserve the
> extension constraints?  Not that I think there's any value in allowing

That is the reason for the !paradoxical_subreg_p(...) check in
"bclri_nottwobits"... so at pattern will always be safe.

Do you see a risk on the "*bclridisi_nottwobits"?

> HI/QI, mostly wanting to double check my understanding of the extension
> constraints.

QI will be fully covered by simm12 (e.g., using the andi instruction).

For HI, we might in fact want to have a special case (similar to
"*bclridisi_nottwobits") — but the reach of the simm12 seems to cover
enough of 16-bit space that this hasn't shown up (yet) as enough of a
problem to warrant a special case.

Philipp.


Re: [PATCH] RISC-V: bitmanip: use bexti for "(a & (1 << BIT_NO)) ? 0 : -1"

2022-11-17 Thread Jeff Law via Gcc-patches



On 11/8/22 12:55, Philipp Tomsich wrote:

Consider creating a polarity-reversed mask from a set-bit (i.e., if
the bit is set, produce all-ones; otherwise: all-zeros).  Using Zbb,
this can be expressed as bexti, followed by an addi of minus-one.  To
enable the combiner to discover this opportunity, we need to split the
canonical expression for "(a & (1 << BIT_NO)) ? 0 : -1" into a form
combinable into bexti.

Consider the function:
 long f(long a)
 {
   return (a & (1 << BIT_NO)) ? 0 : -1;
 }
This produces the following sequence prior to this change:
andia0,a0,16
seqza0,a0
neg a0,a0
ret
Following this change, it results in:
bexti   a0,a0,4
addia0,a0,-1
ret

gcc/ChangeLog:

* config/riscv/bitmanip.md: Add a splitter to generate
   polarity-reversed masks from a set bit using bexti + addi.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zbs-bexti.c: New test.


OK


Jeff




Re: [PATCH] RISC-V: Optimize masking with two clear bits not a SMALL_OPERAND

2022-11-17 Thread Jeff Law via Gcc-patches



On 11/17/22 07:43, Philipp Tomsich wrote:

On Thu, 17 Nov 2022 at 15:30, Jeff Law  wrote:


On 11/10/22 14:36, Philipp Tomsich wrote:

Add a split for cases where we can use two bclri (or one bclri and an
andi) to clear two bits.

gcc/ChangeLog:

   * config/riscv/bitmanip.md (*bclri_nottwobits): New pattern.
   (*bclridisi_nottwobits): New pattern, handling the sign-bit.
   * config/riscv/predicates.md (const_nottwobits_operand):
   New predicate.

gcc/testsuite/ChangeLog:

   * gcc.target/riscv/zbs-bclri.c: New test.

Don't we only have to worry about (subreg:DI (reg:SI )) to preserve the
extension constraints?  Not that I think there's any value in allowing

That is the reason for the !paradoxical_subreg_p(...) check in
"bclri_nottwobits"... so at pattern will always be safe.

Do you see a risk on the "*bclridisi_nottwobits"?


It's jut a sanity check for me, I don't have any concerns since you're 
avoiding this when working on a paradoxical.  But it does make me wonder 
if we need a paradoxical check on the other bit twiddles patterns to 
prevent them from changing the SImode sign bit in a paradoxical.



Jeff




Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-17 Thread Jason Merrill via Gcc-patches

On 11/17/22 03:56, Bernhard Reutner-Fischer wrote:

On Tue, 15 Nov 2022 18:52:41 -0500
Jason Merrill  wrote:


On 11/12/22 13:45, Bernhard Reutner-Fischer wrote:

gcc/cp/ChangeLog:

* decl.cc (start_function): Set the result decl source location to
the location of the typespec.

---
Bootstrapped and regtested on x86_86-unknown-linux with no regressions.
Ok for trunk?

Cc: Nathan Sidwell 
Cc: Jason Merrill 
---
   gcc/cp/decl.cc | 15 ++-
   1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 6e98ea35a39..ed40815e645 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17449,6 +17449,8 @@ start_function (cp_decl_specifier_seq *declspecs,
tree attrs)
   {
 tree decl1;
+  tree result;
+  bool ret;


We now prefer to declare new variables as late as possible, usually when
they are initialized.


Moved. Ok like attached? Bootstrapped and regtested fine.


 decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
 invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1);
@@ -17461,7 +17463,18 @@ start_function (cp_decl_specifier_seq *declspecs,
   gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
 integer_type_node));
   
-  return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);

+  ret = start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
+
+  /* decl1 might be ggc_freed here.  */
+  decl1 = current_function_decl;
+
+  /* Set the result decl source location to the location of the typespec.  */
+  if (TREE_CODE (decl1) == FUNCTION_DECL
+  && declspecs->locations[ds_type_spec] != UNKNOWN_LOCATION
+  && (result = DECL_RESULT (decl1)) != NULL_TREE
+  && DECL_SOURCE_LOCATION (result) == input_location)
+DECL_SOURCE_LOCATION (result) = declspecs->locations[ds_type_spec];


One way to handle the template case would be for the code in
start_preparsed_function that sets DECL_RESULT to check whether decl1 is
a template instantiation, and in that case copy the location from the
template's DECL_RESULT, i.e.

DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1)))


Well, that would probably work if something would set the location of
that template result decl properly, which nothing does out of the box.


Hmm, it should get set by your patch, since templates go through 
start_function like normal functions.



diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index ed7226b82f0..65d78c82a2d 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -17230,6 +17231,17 @@ start_preparsed_function (tree decl1, tree attrs, int 
flags)
cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
  }
  
+  /* Set the result decl source location to the location of the typespec.  */

+  if (DECL_RESULT (decl1)
+  && !DECL_USE_TEMPLATE (decl1)
+  && DECL_TEMPLATE_INFO (decl1)
+  && DECL_TI_TEMPLATE (decl1)
+  && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1))
+  && DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1


This condition is true only for the template definition, for which you 
haven't gotten to your start_function change yet.


Instead, you want to copy the location for instantiations, i.e. check 
DECL_TEMPLATE_INSTANTIATION instead of !DECL_USE_TEMPLATE.



+  DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
+   = DECL_SOURCE_LOCATION (


Open paren goes on the new line.


+   DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1; >   
  /* Record the decl so that the function name is defined.
   If we already have a decl for this name, and it is a FUNCTION_DECL,
   use the old decl.  */

(gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result locus 
before")
../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus before
 7 |   { return _M_finish != 0; }
   |   ^
(gdb) n
(gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result locus 
from TI")
../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus from TI
(gdb) p DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
$1 = 267168

I'm leaving the template case alone for now, maybe i'm motivated later
on to again look at grokfndecl and/or grokmethod to fill in the proper
location. For starters i only need normal functions.
But many thanks for the hint on where the template stuff is, i thought
i would not need it at all but had hoped that there is a spot where
both declspec are at hand and something is "derived" from the templates.




+  return ret;
   }
   
   /* Returns true iff an EH_SPEC_BLOCK should be created in the body of








Re: [PATCH] RISC-V: Handle "(a & twobits) == singlebit" in branches using Zbs

2022-11-17 Thread Jeff Law via Gcc-patches



On 11/13/22 13:48, Philipp Tomsich wrote:

Use Zbs when generating a sequence for "if ((a & twobits) == singlebit) ..."
that can be expressed as bexti + bexti + andn.

gcc/ChangeLog:

* config/riscv/bitmanip.md 
(*branch_mask_twobits_equals_singlebit):
Handle "if ((a & T) == C)" using Zbs, when T has 2 bits set and C has 
one
of these tow bits set.
* config/riscv/predicates.md (const_twobits_operand): New predicate.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/zbs-if_then_else-01.c: New test.


s/tow/two/ in the ChangeLog.







Signed-off-by: Philipp Tomsich 
---

  gcc/config/riscv/bitmanip.md  | 42 +++
  gcc/config/riscv/predicates.md|  5 +++
  .../gcc.target/riscv/zbs-if_then_else-01.c| 20 +
  3 files changed, 67 insertions(+)
  create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 7a8f4e35880..2cea394671f 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -690,3 +690,45 @@
"TARGET_ZBS"
[(set (match_dup 0) (zero_extract:X (match_dup 1) (const_int 1) (match_dup 
2)))
 (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
+
+;; IF_THEN_ELSE: test for 2 bits of opposite polarity
+(define_insn_and_split "*branch_mask_twobits_equals_singlebit"
+  [(set (pc)
+   (if_then_else (match_operator 1 "equality_operator"
+  [(and:X (match_operand:X 2 "register_operand" "r")
+  (match_operand:X 3 "const_twobits_operand" "i"))
+   (match_operand:X 4 "single_bit_mask_operand" "i")])
+(label_ref (match_operand 0 "" ""))
+(pc)))
+   (clobber (match_scratch:X 5 "=&r"))
+   (clobber (match_scratch:X 6 "=&r"))]
+  "TARGET_ZBS && TARGET_ZBB && !SMALL_OPERAND (INTVAL (operands[3]))"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 5) (zero_extract:X (match_dup 2)
+ (const_int 1)
+ (match_dup 8)))
+   (set (match_dup 6) (zero_extract:X (match_dup 2)
+ (const_int 1)
+ (match_dup 9)))
+   (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
+   (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
+  (label_ref (match_dup 0))
+  (pc)))]
+{
+   unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
+   unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
+
+   /* Make sure that the reference value has one of the bits of the mask set */
+   if ((twobits_mask & singlebit_mask) == 0)
+  FAIL;


This fails the split, but in the event this scenario occurs we still 
would up with an ICE as the output template requires splitting.  Don't 
we need to have this be part of the pattern's condition instead so that 
it never matches in that case?



ISTM we should probably have a test to cover this scenario.



jeff




Re: [PATCH] RISC-V: Handle "(a & twobits) == singlebit" in branches using Zbs

2022-11-17 Thread Philipp Tomsich
On Thu, 17 Nov 2022 at 15:58, Jeff Law  wrote:
>
>
> On 11/13/22 13:48, Philipp Tomsich wrote:
> > Use Zbs when generating a sequence for "if ((a & twobits) == singlebit) ..."
> > that can be expressed as bexti + bexti + andn.
> >
> > gcc/ChangeLog:
> >
> >   * config/riscv/bitmanip.md 
> > (*branch_mask_twobits_equals_singlebit):
> >   Handle "if ((a & T) == C)" using Zbs, when T has 2 bits set and C has 
> > one
> >   of these tow bits set.
> >   * config/riscv/predicates.md (const_twobits_operand): New predicate.
> >
> > gcc/testsuite/ChangeLog:
> >
> >   * gcc.target/riscv/zbs-if_then_else-01.c: New test.
>
> s/tow/two/ in the ChangeLog.
>
>
>
>
>
> >
> > Signed-off-by: Philipp Tomsich 
> > ---
> >
> >   gcc/config/riscv/bitmanip.md  | 42 +++
> >   gcc/config/riscv/predicates.md|  5 +++
> >   .../gcc.target/riscv/zbs-if_then_else-01.c| 20 +
> >   3 files changed, 67 insertions(+)
> >   create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> >
> > diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> > index 7a8f4e35880..2cea394671f 100644
> > --- a/gcc/config/riscv/bitmanip.md
> > +++ b/gcc/config/riscv/bitmanip.md
> > @@ -690,3 +690,45 @@
> > "TARGET_ZBS"
> > [(set (match_dup 0) (zero_extract:X (match_dup 1) (const_int 1) 
> > (match_dup 2)))
> >  (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
> > +
> > +;; IF_THEN_ELSE: test for 2 bits of opposite polarity
> > +(define_insn_and_split "*branch_mask_twobits_equals_singlebit"
> > +  [(set (pc)
> > + (if_then_else (match_operator 1 "equality_operator"
> > +[(and:X (match_operand:X 2 "register_operand" "r")
> > +(match_operand:X 3 "const_twobits_operand" 
> > "i"))
> > + (match_operand:X 4 "single_bit_mask_operand" "i")])
> > +  (label_ref (match_operand 0 "" ""))
> > +  (pc)))
> > +   (clobber (match_scratch:X 5 "=&r"))
> > +   (clobber (match_scratch:X 6 "=&r"))]
> > +  "TARGET_ZBS && TARGET_ZBB && !SMALL_OPERAND (INTVAL (operands[3]))"
> > +  "#"
> > +  "&& reload_completed"
> > +  [(set (match_dup 5) (zero_extract:X (match_dup 2)
> > +   (const_int 1)
> > +   (match_dup 8)))
> > +   (set (match_dup 6) (zero_extract:X (match_dup 2)
> > +   (const_int 1)
> > +   (match_dup 9)))
> > +   (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
> > +   (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
> > +(label_ref (match_dup 0))
> > +(pc)))]
> > +{
> > +   unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
> > +   unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
> > +
> > +   /* Make sure that the reference value has one of the bits of the mask 
> > set */
> > +   if ((twobits_mask & singlebit_mask) == 0)
> > +  FAIL;
>
> This fails the split, but in the event this scenario occurs we still
> would up with an ICE as the output template requires splitting.  Don't
> we need to have this be part of the pattern's condition instead so that
> it never matches in that case?

This serves as an assertion only, as that case is non-sensical and
will be optimized away by earlier passes (as "a & C == T" with C and T
sharing no bits will always be false).
IFAIK the preceding transforms should always clean such a check up,
but we can't exclude the possibility that with enough command line
overrides and params we might see such a non-sensical test making it
all the way to the backend.

What would you recommend? Adding this to the pattern's condition feels
a bit redundant.
In fact, I am leaning towards hiding the !SMALL_OPERAND check in yet
another predicate that combines const_twobits_operand with a
match_test for !SMALL_OPERAND.

> ISTM we should probably have a test to cover this scenario.
>
>
>
> jeff
>
>


Re: [PATCH] RISC-V: bitmanip: use bexti for "(a & (1 << BIT_NO)) ? 0 : -1"

2022-11-17 Thread Philipp Tomsich
Committed to master. Thanks!
Philipp.

On Thu, 17 Nov 2022 at 15:43, Jeff Law  wrote:
>
>
> On 11/8/22 12:55, Philipp Tomsich wrote:
> > Consider creating a polarity-reversed mask from a set-bit (i.e., if
> > the bit is set, produce all-ones; otherwise: all-zeros).  Using Zbb,
> > this can be expressed as bexti, followed by an addi of minus-one.  To
> > enable the combiner to discover this opportunity, we need to split the
> > canonical expression for "(a & (1 << BIT_NO)) ? 0 : -1" into a form
> > combinable into bexti.
> >
> > Consider the function:
> >  long f(long a)
> >  {
> >return (a & (1 << BIT_NO)) ? 0 : -1;
> >  }
> > This produces the following sequence prior to this change:
> >   andia0,a0,16
> >   seqza0,a0
> >   neg a0,a0
> >   ret
> > Following this change, it results in:
> >   bexti   a0,a0,4
> >   addia0,a0,-1
> >   ret
> >
> > gcc/ChangeLog:
> >
> >   * config/riscv/bitmanip.md: Add a splitter to generate
> >polarity-reversed masks from a set bit using bexti + addi.
> >
> > gcc/testsuite/ChangeLog:
> >
> >   * gcc.target/riscv/zbs-bexti.c: New test.
>
> OK
>
>
> Jeff
>
>


Re: [PATCH] c: fix ICE with -fanalyzer and -Wunused-macros [PR107711]

2022-11-17 Thread Marek Polacek via Gcc-patches
On Wed, Nov 16, 2022 at 10:05:30PM -0500, David Malcolm wrote:
> PR analyzer/107711 reports an ICE since r13-4073-gd8aba860b34203 with
> the combination of -fanalyzer and -Wunused-macros.
> 
> The issue is that in c_translation_unit::consider_macro's call to
> cpp_create_reader I was passing "ident_hash" for use by the the new
> reader, but that takes ownership of that hash_table, so that ident_hash
> erroneously gets freed when c_translation_unit::consider_macro calls
> cpp_destroy, leading to a use-after-free in -Wunused-macros, where:
> 
> (gdb) p pfile->hash_table->pfile == pfile
> $23 = false
> 
> and it's instead pointing at the freed reader from consider_macro,
> leading to a use-after-free ICE.

Ah, sneaky.

> Fixed thusly.
> 
> Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
> 
> OK for trunk?
 
OK.

> Thanks
> Dave
> 
> 
> gcc/c/ChangeLog:
>   PR analyzer/107711
>   * c-parser.cc (ana::c_translation_unit::consider_macro): Pass NULL
>   to cpp_create_reader, rather than ident_hash, so that the new
>   reader gets its own hash table.
> 
> gcc/testsuite/ChangeLog:
>   PR analyzer/107711
>   * gcc.dg/analyzer/named-constants-Wunused-macros.c: New test.
> 
> Signed-off-by: David Malcolm 
> ---
>  gcc/c/c-parser.cc |  2 +-
>  .../analyzer/named-constants-Wunused-macros.c | 19 +++
>  2 files changed, 20 insertions(+), 1 deletion(-)
>  create mode 100644 
> gcc/testsuite/gcc.dg/analyzer/named-constants-Wunused-macros.c
> 
> diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc
> index f3c79996fb0..1bbb39f9b08 100644
> --- a/gcc/c/c-parser.cc
> +++ b/gcc/c/c-parser.cc
> @@ -1717,7 +1717,7 @@ private:
>return NULL_TREE;
>  
>  cpp_reader *old_parse_in = parse_in;
> -parse_in = cpp_create_reader (CLK_GNUC89, ident_hash, line_table);
> +parse_in = cpp_create_reader (CLK_GNUC89, NULL, line_table);
>  
>  pretty_printer pp;
>  pp_string (&pp, (const char *) tok.val.str.text);
> diff --git a/gcc/testsuite/gcc.dg/analyzer/named-constants-Wunused-macros.c 
> b/gcc/testsuite/gcc.dg/analyzer/named-constants-Wunused-macros.c
> new file mode 100644
> index 000..0b31cc42d78
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/analyzer/named-constants-Wunused-macros.c
> @@ -0,0 +1,19 @@
> +/* Regression test for interaction of named constants in -fanalyzer with
> +   -Wunused-macros (PR analyzer/107711).  */
> +
> +/* { dg-additional-options "-Wunused-macros" } */
> +
> +#include "analyzer-decls.h"
> +
> +/* Various constants used by the fd state machine.  */
> +
> +#define O_ACCMODE 42   /* { dg-warning "-: macro \"O_ACCMODE\" is not used" 
> } */
> +#define O_RDONLY  0x1  /* { dg-warning "-: macro \"O_RDONLY\" is not used" } 
> */
> +#define O_WRONLY  010  /* { dg-warning "-: macro \"O_WRONLY\" is not used" } 
> */
> +
> +void test_sm_fd_constants (void)
> +{
> +  __analyzer_dump_named_constant ("O_ACCMODE"); /* { dg-warning "named 
> constant 'O_ACCMODE' has value '42'" } */
> +  __analyzer_dump_named_constant ("O_RDONLY"); /* { dg-warning "named 
> constant 'O_RDONLY' has value '1'" } */
> +  __analyzer_dump_named_constant ("O_WRONLY"); /* { dg-warning "named 
> constant 'O_WRONLY' has value '8'" } */
> +}
> -- 
> 2.26.3
> 

Marek



Re: [PATCH] RISC-V: Optimize masking with two clear bits not a SMALL_OPERAND

2022-11-17 Thread Philipp Tomsich
Applied to master. Thanks!
Philipp.

On Thu, 17 Nov 2022 at 15:30, Jeff Law  wrote:
>
>
> On 11/10/22 14:36, Philipp Tomsich wrote:
> > Add a split for cases where we can use two bclri (or one bclri and an
> > andi) to clear two bits.
> >
> > gcc/ChangeLog:
> >
> >   * config/riscv/bitmanip.md (*bclri_nottwobits): New pattern.
> >   (*bclridisi_nottwobits): New pattern, handling the sign-bit.
> >   * config/riscv/predicates.md (const_nottwobits_operand):
> >   New predicate.
> >
> > gcc/testsuite/ChangeLog:
> >
> >   * gcc.target/riscv/zbs-bclri.c: New test.
>
> Don't we only have to worry about (subreg:DI (reg:SI )) to preserve the
> extension constraints?  Not that I think there's any value in allowing
> HI/QI, mostly wanting to double check my understanding of the extension
> constraints.
>
>
> OK
>
> jeff
>


[PATCH 02/35] arm: fix 'vmsr' spacing and register capitalization

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/ChangeLog:

* config/arm/vfp.md (*thumb2_movhi_vfp, *thumb2_movhi_fp16): Fix
'vmsr' spacing and reg capitalization.

gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c:
Update test.
* gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c:
Likewise.
* gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c:
Likewise.
---
 gcc/config/arm/vfp.md | 8 
 .../arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c  | 2 +-
 .../arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c  | 2 +-
 .../arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c  | 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index d0f423cc3c5..932e4b7447e 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -105,9 +105,9 @@ (define_insn "*thumb2_movhi_vfp"
 case 8:
   return "vmov%?.f32\t%0, %1\t%@ int";
 case 9:
-  return "vmsr%?\t P0, %1\t@ movhi";
+  return "vmsr%?\tp0, %1\t@ movhi";
 case 10:
-  return "vmrs%?\t %0, P0\t@ movhi";
+  return "vmrs%?\t%0, p0\t@ movhi";
 default:
   gcc_unreachable ();
 }
@@ -209,9 +209,9 @@ (define_insn "*thumb2_movhi_fp16"
 case 8:
   return "vmov%?.f32\t%0, %1\t%@ int";
 case 9:
-  return "vmsr%?\t P0, %1\t%@ movhi";
+  return "vmsr%?\tp0, %1\t%@ movhi";
 case 10:
-  return "vmrs%?\t%0, P0\t%@ movhi";
+  return "vmrs%?\t%0, p0\t%@ movhi";
 default:
   gcc_unreachable ();
 }
diff --git 
a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c
index f3219e2e825..1e57ca40739 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_f32.c
@@ -11,7 +11,7 @@ foo (uint32x4_t * addr, mve_pred16_t p)
 }
 
 /* { dg-final { scan-assembler "vldrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
-/* { dg-final { scan-assembler "vmsr\t P0, r\[0-9\]+.*" } } */
+/* { dg-final { scan-assembler "vmsr\tp0, r\[0-9\]+.*" } } */
 /* { dg-final { scan-assembler "vpst" } } */
 /* { dg-final { scan-assembler "vldrwt.u32\tq\[0-9\]+, \\\[q\[0-9\]+, 
#\[0-9\]+\\\]!" } } */
 /* { dg-final { scan-assembler "vstrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
diff --git 
a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c
index 4d093d243fe..f8d77fdfd5b 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_s32.c
@@ -11,7 +11,7 @@ foo (uint32x4_t * addr, mve_pred16_t p)
 }
 
 /* { dg-final { scan-assembler "vldrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
-/* { dg-final { scan-assembler "vmsr\t P0, r\[0-9\]+.*" } } */
+/* { dg-final { scan-assembler "vmsr\tp0, r\[0-9\]+.*" } } */
 /* { dg-final { scan-assembler "vpst" } } */
 /* { dg-final { scan-assembler "vldrwt.u32\tq\[0-9\]+, \\\[q\[0-9\]+, 
#\[0-9\]+\\\]!" } } */
 /* { dg-final { scan-assembler "vstrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
diff --git 
a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c
index e796522a49c..8a0e109c70c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vldrwq_gather_base_wb_z_u32.c
@@ -11,7 +11,7 @@ foo (uint32x4_t * addr, mve_pred16_t p)
 }
 
 /* { dg-final { scan-assembler "vldrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
-/* { dg-final { scan-assembler "vmsr\t P0, r\[0-9\]+.*" } } */
+/* { dg-final { scan-assembler "vmsr\tp0, r\[0-9\]+.*" } } */
 /* { dg-final { scan-assembler "vpst" } } */
 /* { dg-final { scan-assembler "vldrwt.u32\tq\[0-9\]+, \\\[q\[0-9\]+, 
#\[0-9\]+\\\]!" } } */
 /* { dg-final { scan-assembler "vstrw.32\tq\[0-9\]+, \\\[r\[0-9\]+\\\]" } } */
-- 
2.25.1



[PATCH 03/35] arm: improve tests and fix vddupq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/ChangeLog:

* config/arm/mve.md (mve_vddupq_u_insn): Fix 'vddup.u'
spacing.
(mve_vddupq_m_wb_u_insn): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vddupq_m_n_u32.c : Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_m_n_u8.c : Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_m_wb_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_m_wb_u32.c : Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_m_wb_u8.c : Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_n_u16.c : Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_wb_u16.c : Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_wb_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_wb_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_x_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_x_n_u32.c : Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_x_n_u8.c : Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_x_wb_u16.c : Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_x_wb_u32.c : Likewise.
* gcc.target/arm/mve/intrinsics/vddupq_x_wb_u8.c : Likewise.
---
 gcc/config/arm/mve.md |  4 +-
 .../arm/mve/intrinsics/vddupq_m_n_u16.c   | 42 +--
 .../arm/mve/intrinsics/vddupq_m_n_u32.c   | 46 +---
 .../arm/mve/intrinsics/vddupq_m_n_u8.c| 46 +---
 .../arm/mve/intrinsics/vddupq_m_wb_u16.c  | 42 +--
 .../arm/mve/intrinsics/vddupq_m_wb_u32.c  | 46 +---
 .../arm/mve/intrinsics/vddupq_m_wb_u8.c   | 46 +---
 .../arm/mve/intrinsics/vddupq_n_u16.c | 32 ++--
 .../arm/mve/intrinsics/vddupq_n_u32.c | 28 +-
 .../arm/mve/intrinsics/vddupq_n_u8.c  | 28 +-
 .../arm/mve/intrinsics/vddupq_wb_u16.c| 32 ++--
 .../arm/mve/intrinsics/vddupq_wb_u32.c| 28 +-
 .../arm/mve/intrinsics/vddupq_wb_u8.c | 28 +-
 .../arm/mve/intrinsics/vddupq_x_n_u16.c   | 42 +--
 .../arm/mve/intrinsics/vddupq_x_n_u32.c   | 46 +---
 .../arm/mve/intrinsics/vddupq_x_n_u8.c| 46 +---
 .../arm/mve/intrinsics/vddupq_x_wb_u16.c  | 52 +++
 .../arm/mve/intrinsics/vddupq_x_wb_u32.c  | 52 +++
 .../arm/mve/intrinsics/vddupq_x_wb_u8.c   | 52 +++
 19 files changed, 642 insertions(+), 96 deletions(-)

diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 62186f124da..1215f845388 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -9043,7 +9043,7 @@ (define_insn "mve_vddupq_u_insn"
(minus:SI (match_dup 2)
 (match_operand:SI 4 "immediate_operand" "i")))]
  "TARGET_HAVE_MVE"
- "vddup.u%#  %q0, %1, %3")
+ "vddup.u%#\t%q0, %1, %3")
 
 ;;
 ;; [vddupq_m_n_u])
@@ -9079,7 +9079,7 @@ (define_insn "mve_vddupq_m_wb_u_insn"
(minus:SI (match_dup 3)
 (match_operand:SI 6 "immediate_operand" "i")))]
  "TARGET_HAVE_MVE"
- "vpst\;\tvddupt.u%#\t%q0, %2, %4"
+ "vpst\;vddupt.u%#\t%q0, %2, %4"
  [(set_attr "length""8")])
 
 ;;
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c
index 7332711f6a7..7c8b0152763 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vddupq_m_n_u16.c
@@ -1,23 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16  q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?:  @.*|)
+** ...
+*/
 uint16x8_t
 foo (uint16x8_t inactive, uint32_t a, mve_pred16_t p)
 {
   return vddupq_m_n_u16 (inactive, a, 1, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16  q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?:  @.*|)
+** ...
+*/
 uint16x8_t
 foo1 (uint16x8_t inactive, uint32_t a, mve_pred16_t p)
 {
   return vddupq_m (inactive, a, 1, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vddupt.u16"  }  } */
+/*
+**foo2:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vddupt.u16  q[0-9]+, (?:ip|fp|r[0-9]+), #[0-

[PATCH 04/35] arm: improve tests and fix vdwdupq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/ChangeLog:

* config/arm/mve.md (mve_vdwdupq_m_wb_u_insn): Fix spacing.

gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c : Improve test.
* gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u32.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u8.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u16.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u32.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_m_wb_u8.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_n_u16.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_n_u32.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_n_u8.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_wb_u16.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_wb_u32.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_wb_u8.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u32.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_x_n_u8.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u16.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u32.c : Likewise.
* gcc.target/arm/mve/intrinsics/vdwdupq_x_wb_u8.c : Likewise.
---
 gcc/config/arm/mve.md |  2 +-
 .../arm/mve/intrinsics/vdwdupq_m_n_u16.c  | 44 ++--
 .../arm/mve/intrinsics/vdwdupq_m_n_u32.c  | 46 ++---
 .../arm/mve/intrinsics/vdwdupq_m_n_u8.c   | 46 ++---
 .../arm/mve/intrinsics/vdwdupq_m_wb_u16.c | 50 ---
 .../arm/mve/intrinsics/vdwdupq_m_wb_u32.c | 48 +++---
 .../arm/mve/intrinsics/vdwdupq_m_wb_u8.c  | 50 ---
 .../arm/mve/intrinsics/vdwdupq_n_u16.c| 32 ++--
 .../arm/mve/intrinsics/vdwdupq_n_u32.c| 32 ++--
 .../arm/mve/intrinsics/vdwdupq_n_u8.c | 32 ++--
 .../arm/mve/intrinsics/vdwdupq_wb_u16.c   | 32 ++--
 .../arm/mve/intrinsics/vdwdupq_wb_u32.c   | 32 ++--
 .../arm/mve/intrinsics/vdwdupq_wb_u8.c| 32 ++--
 .../arm/mve/intrinsics/vdwdupq_x_n_u16.c  | 42 ++--
 .../arm/mve/intrinsics/vdwdupq_x_n_u32.c  | 46 ++---
 .../arm/mve/intrinsics/vdwdupq_x_n_u8.c   | 46 ++---
 .../arm/mve/intrinsics/vdwdupq_x_wb_u16.c | 50 ---
 .../arm/mve/intrinsics/vdwdupq_x_wb_u32.c | 46 ++---
 .../arm/mve/intrinsics/vdwdupq_x_wb_u8.c  | 50 ---
 19 files changed, 655 insertions(+), 103 deletions(-)

diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 1215f845388..58ffe03c499 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -9195,7 +9195,7 @@ (define_insn "mve_vdwdupq_m_wb_u_insn"
 VDWDUPQ_M))
   ]
   "TARGET_HAVE_MVE"
-  "vpst\;\tvdwdupt.u%#\t%q2, %3, %R4, %5"
+  "vpst\;vdwdupt.u%#\t%q2, %3, %R4, %5"
   [(set_attr "type" "mve_move")
(set_attr "length""8")])
 
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c
index 5303fd7d361..8f53f5ef0cb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdwdupq_m_n_u16.c
@@ -1,23 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), 
#[0-9]+(?:   @.*|)
+** ...
+*/
 uint16x8_t
 foo (uint16x8_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
 {
-  return vdwdupq_m (inactive, a, b, 1, p);
+  return vdwdupq_m_n_u16 (inactive, a, b, 1, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), 
#[0-9]+(?:   @.*|)
+** ...
+*/
 uint16x8_t
 foo1 (uint16x8_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
 {
   return vdwdupq_m (inactive, a, b, 1, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vdwdupt.u16"  }  } */
+/*
+**foo2:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vdwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), 
#[0-9]+(?:   @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+  return vdwdupq_m (inactive, 1, 1, 1, p);

[PATCH 10/35] arm: improve tests for vabavq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vabavq_p_s16.c:
* gcc.target/arm/mve/intrinsics/vabavq_p_s32.c:
* gcc.target/arm/mve/intrinsics/vabavq_p_s8.c:
* gcc.target/arm/mve/intrinsics/vabavq_p_u16.c:
* gcc.target/arm/mve/intrinsics/vabavq_p_u32.c:
* gcc.target/arm/mve/intrinsics/vabavq_p_u8.c:
* gcc.target/arm/mve/intrinsics/vabavq_s16.c:
* gcc.target/arm/mve/intrinsics/vabavq_s32.c:
* gcc.target/arm/mve/intrinsics/vabavq_s8.c:
* gcc.target/arm/mve/intrinsics/vabavq_u16.c:
* gcc.target/arm/mve/intrinsics/vabavq_u32.c:
* gcc.target/arm/mve/intrinsics/vabavq_u8.c:
---
 .../arm/mve/intrinsics/vabavq_p_s16.c | 40 ++-
 .../arm/mve/intrinsics/vabavq_p_s32.c | 40 ++-
 .../arm/mve/intrinsics/vabavq_p_s8.c  | 40 ++-
 .../arm/mve/intrinsics/vabavq_p_u16.c | 40 ++-
 .../arm/mve/intrinsics/vabavq_p_u32.c | 40 ++-
 .../arm/mve/intrinsics/vabavq_p_u8.c  | 40 ++-
 .../arm/mve/intrinsics/vabavq_s16.c   | 28 -
 .../arm/mve/intrinsics/vabavq_s32.c   | 28 -
 .../gcc.target/arm/mve/intrinsics/vabavq_s8.c | 28 -
 .../arm/mve/intrinsics/vabavq_u16.c   | 28 -
 .../arm/mve/intrinsics/vabavq_u32.c   | 28 -
 .../gcc.target/arm/mve/intrinsics/vabavq_u8.c | 28 -
 12 files changed, 384 insertions(+), 24 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s16.c
index 78ac801fa3c..843d022c418 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s16.c
@@ -1,21 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s16  (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?:  @.*|)
+** ...
+*/
 uint32_t
 foo (uint32_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
 {
   return vabavq_p_s16 (a, b, c, p);
 }
 
-/* { dg-final { scan-assembler "vabavt.s16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s16  (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?:  @.*|)
+** ...
+*/
 uint32_t
 foo1 (uint32_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
 {
   return vabavq_p (a, b, c, p);
 }
 
-/* { dg-final { scan-assembler "vabavt.s16"  }  } */
+/*
+**foo2:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s16  (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?:  @.*|)
+** ...
+*/
+uint32_t
+foo2 (int16x8_t b, int16x8_t c, mve_pred16_t p)
+{
+  return vabavq_p (1, b, c, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s32.c
index af4e30b6127..6ed9b9ac1c4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabavq_p_s32.c
@@ -1,21 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s32  (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?:  @.*|)
+** ...
+*/
 uint32_t
 foo (uint32_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
 {
   return vabavq_p_s32 (a, b, c, p);
 }
 
-/* { dg-final { scan-assembler "vabavt.s32"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s32  (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?:  @.*|)
+** ...
+*/
 uint32_t
 foo1 (uint32_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
 {
   return vabavq_p (a, b, c, p);
 }
 
-/* { dg-final { scan-assembler "vabavt.s32"  }  } */
+/*
+**foo2:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vabavt.s32  (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?:  @.*|)
+** ...
+*/
+uint32_t
+foo2 (int32x4_t b, int32x4_t c, mve_pred16_t p)
+{
+  return vabavq_p (1, b, c, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrin

[PATCH 05/35] arm: improve vidupq* tests

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c: Improve tests.
* gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_m_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_m_wb_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_m_wb_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_m_wb_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_wb_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_wb_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_wb_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_x_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_x_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_x_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_x_wb_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_x_wb_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vidupq_x_wb_u8.c: Likewise.
---
 .../arm/mve/intrinsics/vidupq_m_n_u16.c   | 46 +---
 .../arm/mve/intrinsics/vidupq_m_n_u32.c   | 42 +--
 .../arm/mve/intrinsics/vidupq_m_n_u8.c| 42 +--
 .../arm/mve/intrinsics/vidupq_m_wb_u16.c  | 46 +---
 .../arm/mve/intrinsics/vidupq_m_wb_u32.c  | 42 +--
 .../arm/mve/intrinsics/vidupq_m_wb_u8.c   | 42 +--
 .../arm/mve/intrinsics/vidupq_n_u16.c | 32 ++--
 .../arm/mve/intrinsics/vidupq_n_u32.c | 28 +-
 .../arm/mve/intrinsics/vidupq_n_u8.c  | 28 +-
 .../arm/mve/intrinsics/vidupq_wb_u16.c| 32 ++--
 .../arm/mve/intrinsics/vidupq_wb_u32.c| 28 +-
 .../arm/mve/intrinsics/vidupq_wb_u8.c | 28 +-
 .../arm/mve/intrinsics/vidupq_x_n_u16.c   | 46 +---
 .../arm/mve/intrinsics/vidupq_x_n_u32.c   | 42 +--
 .../arm/mve/intrinsics/vidupq_x_n_u8.c| 42 +--
 .../arm/mve/intrinsics/vidupq_x_wb_u16.c  | 52 +++
 .../arm/mve/intrinsics/vidupq_x_wb_u32.c  | 52 +++
 .../arm/mve/intrinsics/vidupq_x_wb_u8.c   | 52 +++
 18 files changed, 634 insertions(+), 88 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c
index 822d41197e6..b4ee7af36e3 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u16.c
@@ -1,23 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16  q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?:  @.*|)
+** ...
+*/
 uint16x8_t
 foo (uint16x8_t inactive, uint32_t a, mve_pred16_t p)
 {
-  return vidupq_m_n_u16 (inactive, a, 4, p);
+  return vidupq_m_n_u16 (inactive, a, 1, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16  q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?:  @.*|)
+** ...
+*/
 uint16x8_t
 foo1 (uint16x8_t inactive, uint32_t a, mve_pred16_t p)
 {
-  return vidupq_m (inactive, a, 4, p);
+  return vidupq_m (inactive, a, 1, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vidupt.u16"  }  } */
+/*
+**foo2:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vidupt.u16  q[0-9]+, (?:ip|fp|r[0-9]+), #[0-9]+(?:  @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+  return vidupq_m (inactive, 1, 1, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c
index c01826e15dc..b13a7a80dcb 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vidupq_m_n_u32.c
@@ -1,23 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip

[PATCH 06/35] arm: improve tests and fix vdupq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/ChangeLog:

* config/arm/mve.md (mve_vdupq_n_f)
(mve_vdupq_n_, mve_vdupq_m_n_)
(mve_vdupq_m_n_f): Fix spacing.

gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vdupq_m_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_m_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_m_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_m_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_m_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_x_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_x_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_x_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_x_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_x_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_x_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_x_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vdupq_x_n_u8.c: Likewise.
---
 gcc/config/arm/mve.md |  8 ++--
 .../arm/mve/intrinsics/vdupq_m_n_f16.c| 41 +--
 .../arm/mve/intrinsics/vdupq_m_n_f32.c| 41 +--
 .../arm/mve/intrinsics/vdupq_m_n_s16.c| 25 +--
 .../arm/mve/intrinsics/vdupq_m_n_s32.c| 25 +--
 .../arm/mve/intrinsics/vdupq_m_n_s8.c | 25 +--
 .../arm/mve/intrinsics/vdupq_m_n_u16.c| 41 +--
 .../arm/mve/intrinsics/vdupq_m_n_u32.c| 41 +--
 .../arm/mve/intrinsics/vdupq_m_n_u8.c | 41 +--
 .../arm/mve/intrinsics/vdupq_n_f16.c  | 21 +-
 .../arm/mve/intrinsics/vdupq_n_f32.c  | 21 +-
 .../arm/mve/intrinsics/vdupq_n_s16.c  | 13 --
 .../arm/mve/intrinsics/vdupq_n_s32.c  | 13 --
 .../arm/mve/intrinsics/vdupq_n_s8.c   |  9 +++-
 .../arm/mve/intrinsics/vdupq_n_u16.c  | 23 ++-
 .../arm/mve/intrinsics/vdupq_n_u32.c  | 23 ++-
 .../arm/mve/intrinsics/vdupq_n_u8.c   | 23 ++-
 .../arm/mve/intrinsics/vdupq_x_n_f16.c| 30 +-
 .../arm/mve/intrinsics/vdupq_x_n_f32.c| 30 +-
 .../arm/mve/intrinsics/vdupq_x_n_s16.c| 14 ++-
 .../arm/mve/intrinsics/vdupq_x_n_s32.c| 14 ++-
 .../arm/mve/intrinsics/vdupq_x_n_s8.c | 14 ++-
 .../arm/mve/intrinsics/vdupq_x_n_u16.c| 30 +-
 .../arm/mve/intrinsics/vdupq_x_n_u32.c| 30 +-
 .../arm/mve/intrinsics/vdupq_x_n_u8.c | 30 +-
 25 files changed, 567 insertions(+), 59 deletions(-)

diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 58ffe03c499..6d5270281ec 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -266,7 +266,7 @@ (define_insn "mve_vdupq_n_f"
 VDUPQ_N_F))
   ]
   "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
-  "vdup.%#   %q0, %1"
+  "vdup.%#\t%q0, %1"
   [(set_attr "type" "mve_move")
 ])
 
@@ -435,7 +435,7 @@ (define_insn "mve_vdupq_n_"
 VDUPQ_N))
   ]
   "TARGET_HAVE_MVE"
-  "vdup.%#   %q0, %1"
+  "vdup.%#\t%q0, %1"
   [(set_attr "type" "mve_move")
 ])
 
@@ -3046,7 +3046,7 @@ (define_insn "mve_vdupq_m_n_"
 VDUPQ_M_N))
   ]
   "TARGET_HAVE_MVE"
-  "vpst\;vdupt.%#   %q0, %2"
+  "vpst\;vdupt.%#\t%q0, %2"
   [(set_attr "type" "mve_move")
(set_attr "length""8")])
 
@@ -3991,7 +3991,7 @@ (define_insn "mve_vdupq_m_n_f"
 VDUPQ_M_N_F))
   ]
   "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
-  "vpst\;vdupt.%#   %q0, %2"
+  "vpst\;vdupt.%#\t%q0, %2"
   [(set_attr "type" "mve_move")
(set_attr "length""8")])
 
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c
index 0b749be3527..bfa471bcb31 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vdupq_m_n_f16.c
@@ -1,22 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /* { dg-add-options arm_v8_1m_mve_fp } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+**

[PATCH 35/35] arm: improve tests for vsetq_lane*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vsetq_lane_f16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vsetq_lane_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsetq_lane_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsetq_lane_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsetq_lane_s64.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsetq_lane_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsetq_lane_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsetq_lane_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsetq_lane_u64.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsetq_lane_u8.c: Likewise.
---
 .../arm/mve/intrinsics/vsetq_lane_f16.c   | 36 +++--
 .../arm/mve/intrinsics/vsetq_lane_f32.c   | 36 +++--
 .../arm/mve/intrinsics/vsetq_lane_s16.c   | 24 ++--
 .../arm/mve/intrinsics/vsetq_lane_s32.c   | 24 ++--
 .../arm/mve/intrinsics/vsetq_lane_s64.c   | 27 ++---
 .../arm/mve/intrinsics/vsetq_lane_s8.c| 24 ++--
 .../arm/mve/intrinsics/vsetq_lane_u16.c   | 36 +++--
 .../arm/mve/intrinsics/vsetq_lane_u32.c   | 36 +++--
 .../arm/mve/intrinsics/vsetq_lane_u64.c   | 39 ---
 .../arm/mve/intrinsics/vsetq_lane_u8.c| 36 +++--
 10 files changed, 284 insertions(+), 34 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f16.c
index e03e9620528..b5c9f4d5eb8 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f16.c
@@ -1,15 +1,45 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} 
} */
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /* { dg-add-options arm_v8_1m_mve_fp } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmov.16 q[0-9]+\[[0-9]+\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
 float16x8_t
 foo (float16_t a, float16x8_t b)
 {
-return vsetq_lane_f16 (a, b, 0);
+  return vsetq_lane_f16 (a, b, 1);
 }
 
-/* { dg-final { scan-assembler "vmov.16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmov.16 q[0-9]+\[[0-9]+\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo1 (float16_t a, float16x8_t b)
+{
+  return vsetq_lane (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vmov.16 q[0-9]+\[[0-9]+\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t b)
+{
+  return vsetq_lane (1.1, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f32.c
index 2b9f1a7e627..211083ce5d4 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_f32.c
@@ -1,15 +1,45 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} 
} */
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /* { dg-add-options arm_v8_1m_mve_fp } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmov.32 q[0-9]+\[[0-9]+\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
 float32x4_t
 foo (float32_t a, float32x4_t b)
 {
-return vsetq_lane_f32 (a, b, 0);
+  return vsetq_lane_f32 (a, b, 1);
 }
 
-/* { dg-final { scan-assembler "vmov.32"  }  } */
 
+/*
+**foo1:
+** ...
+** vmov.32 q[0-9]+\[[0-9]+\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo1 (float32_t a, float32x4_t b)
+{
+  return vsetq_lane (a, b, 1);
+}
+
+/*
+**foo2:
+** ...
+** vmov.32 q[0-9]+\[[0-9]+\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t b)
+{
+  return vsetq_lane (1.1, b, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s16.c
index 92ad0dd16a8..9cdaeae1e74 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vsetq_lane_s16.c
@@ -1,15 +1,33 @@
-/* { dg-skip-if "Incompatible float ABI" { *-*-* } { "-mfloat-abi=soft" } {""} 
} */
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmov.16 q[0-9]+\[[0-9]+\], (?:ip|fp|r[0-9]+)(?: @.*|)
+** ...
+*/
 int16x8_t
 foo (int16_t a, int16x8_t b)
 {
-return vsetq_lane_s

[PATCH 00/35] arm: rework MVE testsuite and rework backend where necessary (1st chunk)

2022-11-17 Thread Andrea Corallo via Gcc-patches
Hi all,

this is the first patch series about improving the current MVE
implementation and testsuite for:

- Complete intrinsic implementation and coverage (the list of intrinsics is
  specified by [1])
- Verifying all instructions supposedly emitted by each intrinsic
- Verifying register usage
- Fixing the current scan assemblers to really match the wanted mnemonics
- Verifying no external calls are emitted

This series fixes the backend where necessary.

Best Regards

  Andrea

Andrea Corallo (31):
  arm: improve vcreateq* tests
  arm: fix 'vmsr' spacing and register capitalization
  arm: improve tests and fix vddupq*
  arm: improve tests and fix vdwdupq*
  arm: improve vidupq* tests
  arm: improve tests and fix vdupq*
  arm: improve tests and fix vcmp*
  arm: improve tests for vmin*
  arm: improve tests for vmax*
  arm: improve tests for vabavq*
  arm: improve tests for vabdq*
  arm: improve tests and fix vabsq*
  arm: improve tests and fix vadd*
  arm: improve tests for vmulq*
  arm: improve tests and fix vsubq*
  arm: improve tests for vfmasq_m*
  arm: improve tests for vhaddq_m*
  arm: improve tests for vhsubq_m*
  arm: improve tests for viwdupq*
  arm: improve tests for vmladavaq*
  arm: improve tests and fix vmlaldavaxq*
  arm: improve tests for vmlasq*
  arm: improve tests for vqaddq_m*
  arm: improve tests for vqdmlahq_m*
  arm: improve tests for vqdmul*
  arm: improve tests for vqrdmlahq*
  arm: improve tests for vqrdmlashq_m*
  arm: improve tests for vqsubq*
  arm: improve tests and fix vrmlaldavhaq*
  arm: improve tests for vrshlq*
  arm: improve tests for vsetq_lane*

Stam Markianos-Wright (4):
  arm: further fix overloading of MVE vaddq[_m]_n intrinsic
  arm: propagate fixed overloading of MVE intrinsic scalar parameters
  arm: Explicitly specify other float types for _Generic overloading
[PR107515]
  arm: Add integer vector overloading of vsubq_x instrinsic

 gcc/config/arm/arm_mve.h  | 1232 +
 gcc/config/arm/mve.md |   48 +-
 gcc/config/arm/vfp.md |8 +-
 .../arm/mve/intrinsics/vabavq_p_s16.c |   40 +-
 .../arm/mve/intrinsics/vabavq_p_s32.c |   40 +-
 .../arm/mve/intrinsics/vabavq_p_s8.c  |   40 +-
 .../arm/mve/intrinsics/vabavq_p_u16.c |   40 +-
 .../arm/mve/intrinsics/vabavq_p_u32.c |   40 +-
 .../arm/mve/intrinsics/vabavq_p_u8.c  |   40 +-
 .../arm/mve/intrinsics/vabavq_s16.c   |   28 +-
 .../arm/mve/intrinsics/vabavq_s32.c   |   28 +-
 .../gcc.target/arm/mve/intrinsics/vabavq_s8.c |   28 +-
 .../arm/mve/intrinsics/vabavq_u16.c   |   28 +-
 .../arm/mve/intrinsics/vabavq_u32.c   |   28 +-
 .../gcc.target/arm/mve/intrinsics/vabavq_u8.c |   28 +-
 .../gcc.target/arm/mve/intrinsics/vabdq_f16.c |   16 +-
 .../gcc.target/arm/mve/intrinsics/vabdq_f32.c |   16 +-
 .../arm/mve/intrinsics/vabdq_m_f16.c  |   26 +-
 .../arm/mve/intrinsics/vabdq_m_f32.c  |   26 +-
 .../arm/mve/intrinsics/vabdq_m_s16.c  |   26 +-
 .../arm/mve/intrinsics/vabdq_m_s32.c  |   26 +-
 .../arm/mve/intrinsics/vabdq_m_s8.c   |   26 +-
 .../arm/mve/intrinsics/vabdq_m_u16.c  |   26 +-
 .../arm/mve/intrinsics/vabdq_m_u32.c  |   26 +-
 .../arm/mve/intrinsics/vabdq_m_u8.c   |   26 +-
 .../gcc.target/arm/mve/intrinsics/vabdq_s16.c |   16 +-
 .../gcc.target/arm/mve/intrinsics/vabdq_s32.c |   16 +-
 .../gcc.target/arm/mve/intrinsics/vabdq_s8.c  |   16 +-
 .../gcc.target/arm/mve/intrinsics/vabdq_u16.c |   16 +-
 .../gcc.target/arm/mve/intrinsics/vabdq_u32.c |   16 +-
 .../gcc.target/arm/mve/intrinsics/vabdq_u8.c  |   16 +-
 .../arm/mve/intrinsics/vabdq_x_f16.c  |   25 +-
 .../arm/mve/intrinsics/vabdq_x_f32.c  |   25 +-
 .../arm/mve/intrinsics/vabdq_x_s16.c  |   26 +-
 .../arm/mve/intrinsics/vabdq_x_s32.c  |   25 +-
 .../arm/mve/intrinsics/vabdq_x_s8.c   |   25 +-
 .../arm/mve/intrinsics/vabdq_x_u16.c  |   25 +-
 .../arm/mve/intrinsics/vabdq_x_u32.c  |   25 +-
 .../arm/mve/intrinsics/vabdq_x_u8.c   |   25 +-
 .../gcc.target/arm/mve/intrinsics/vabsq_f16.c |   22 +-
 .../gcc.target/arm/mve/intrinsics/vabsq_f32.c |   22 +-
 .../arm/mve/intrinsics/vabsq_m_f16.c  |   25 +-
 .../arm/mve/intrinsics/vabsq_m_f32.c  |   25 +-
 .../arm/mve/intrinsics/vabsq_m_s16.c  |   25 +-
 .../arm/mve/intrinsics/vabsq_m_s32.c  |   25 +-
 .../arm/mve/intrinsics/vabsq_m_s8.c   |   25 +-
 .../gcc.target/arm/mve/intrinsics/vabsq_s16.c |   20 +-
 .../gcc.target/arm/mve/intrinsics/vabsq_s32.c |   20 +-
 .../gcc.target/arm/mve/intrinsics/vabsq_s8.c  |   16 +-
 .../arm/mve/intrinsics/vabsq_x_f16.c  |   25 +-
 .../arm/mve/intrinsics/vabsq_x_f32.c  |   25 +-
 .../arm/mve/intrinsics/vabsq_x_s16.c  |   25 +-
 .../arm/mve/intrinsics/vabsq_x_s32.c  |   25 +-
 .../arm/mve/intrinsics/vabsq_x_s8.c   |   2

[PATCH 31/35] arm: improve tests for vqrdmlashq_m*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c:
* gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c:
* gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c:
---
 .../arm/mve/intrinsics/vqrdmlashq_m_n_s16.c   | 34 ++-
 .../arm/mve/intrinsics/vqrdmlashq_m_n_s32.c   | 34 ++-
 .../arm/mve/intrinsics/vqrdmlashq_m_n_s8.c| 34 ++-
 3 files changed, 78 insertions(+), 24 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c
index 35b9618ca47..da4d724bb46 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s16.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlasht.s16  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo (int16x8_t m1, int16x8_t m2, int16_t add, mve_pred16_t p)
 {
-  return vqrdmlashq_m_n_s16 (a, b, c, p);
+  return vqrdmlashq_m_n_s16 (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlasht.s16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlasht.s16  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo1 (int16x8_t m1, int16x8_t m2, int16_t add, mve_pred16_t p)
 {
-  return vqrdmlashq_m (a, b, c, p);
+  return vqrdmlashq_m (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlasht.s16"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c
index 8517835eb61..2430f1cb102 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s32.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlasht.s32  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo (int32x4_t m1, int32x4_t m2, int32_t add, mve_pred16_t p)
 {
-  return vqrdmlashq_m_n_s32 (a, b, c, p);
+  return vqrdmlashq_m_n_s32 (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlasht.s32"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlasht.s32  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo1 (int32x4_t m1, int32x4_t m2, int32_t add, mve_pred16_t p)
 {
-  return vqrdmlashq_m (a, b, c, p);
+  return vqrdmlashq_m (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlasht.s32"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c
index e42cc63fa74..30915b24e5e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlashq_m_n_s8.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlasht.s8   q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int8x16_t
-foo (int8x16_t a, int8x16_t b, int8_t c, mve_pred16_t p)
+foo (int8x16_t m1, int8x16_t m2, int8_t add, mve_pred16_t p)
 {
-  return vqrdmlashq_m_n_s8 (a, b, c, p);
+  return vqrdmlashq_m_n_s8 (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-a

[PATCH 20/35] arm: improve tests for vfmasq_m*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c: Likewise.
---
 .../arm/mve/intrinsics/vfmasq_m_n_f16.c   | 50 ---
 .../arm/mve/intrinsics/vfmasq_m_n_f32.c   | 50 ---
 2 files changed, 84 insertions(+), 16 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c
index 06d2d114e46..03b376c9bbe 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f16.c
@@ -1,23 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /* { dg-add-options arm_v8_1m_mve_fp } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f16  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 float16x8_t
-foo (float16x8_t a, float16x8_t b, float16_t c, mve_pred16_t p)
+foo (float16x8_t m1, float16x8_t m2, float16_t add, mve_pred16_t p)
 {
-  return vfmasq_m_n_f16 (a, b, c, p);
+  return vfmasq_m_n_f16 (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vfmast.f16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f16  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 float16x8_t
-foo1 (float16x8_t a, float16x8_t b, float16_t c, mve_pred16_t p)
+foo1 (float16x8_t m1, float16x8_t m2, float16_t add, mve_pred16_t p)
 {
-  return vfmasq_m (a, b, c, p);
+  return vfmasq_m (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vfmast.f16"  }  } */
+/*
+**foo2:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f16  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
+float16x8_t
+foo2 (float16x8_t m1, float16x8_t m2, mve_pred16_t p)
+{
+  return vfmasq_m (m1, m2, 1.1, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c
index bf1773d0eeb..ecf30ba9826 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vfmasq_m_n_f32.c
@@ -1,23 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /* { dg-add-options arm_v8_1m_mve_fp } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f32  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 float32x4_t
-foo (float32x4_t a, float32x4_t b, float32_t c, mve_pred16_t p)
+foo (float32x4_t m1, float32x4_t m2, float32_t add, mve_pred16_t p)
 {
-  return vfmasq_m_n_f32 (a, b, c, p);
+  return vfmasq_m_n_f32 (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vfmast.f32"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f32  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 float32x4_t
-foo1 (float32x4_t a, float32x4_t b, float32_t c, mve_pred16_t p)
+foo1 (float32x4_t m1, float32x4_t m2, float32_t add, mve_pred16_t p)
 {
-  return vfmasq_m (a, b, c, p);
+  return vfmasq_m (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vfmast.f32"  }  } */
+/*
+**foo2:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vfmast.f32  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
+float32x4_t
+foo2 (float32x4_t m1, float32x4_t m2, mve_pred16_t p)
+{
+  return vfmasq_m (m1, m2, 1.1, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
-- 
2.25.1



[PATCH 12/35] arm: improve tests and fix vabsq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/ChangeLog:

* config/arm/mve.md (mve_vabsq_f): Fix spacing.

gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vabsq_f16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vabsq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_m_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_m_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_x_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_x_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_x_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_x_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabsq_x_s8.c: Likewise.
---
 gcc/config/arm/mve.md |  2 +-
 .../gcc.target/arm/mve/intrinsics/vabsq_f16.c | 22 +++-
 .../gcc.target/arm/mve/intrinsics/vabsq_f32.c | 22 +++-
 .../arm/mve/intrinsics/vabsq_m_f16.c  | 25 ---
 .../arm/mve/intrinsics/vabsq_m_f32.c  | 25 ---
 .../arm/mve/intrinsics/vabsq_m_s16.c  | 25 ---
 .../arm/mve/intrinsics/vabsq_m_s32.c  | 25 ---
 .../arm/mve/intrinsics/vabsq_m_s8.c   | 25 ---
 .../gcc.target/arm/mve/intrinsics/vabsq_s16.c | 20 ---
 .../gcc.target/arm/mve/intrinsics/vabsq_s32.c | 20 ---
 .../gcc.target/arm/mve/intrinsics/vabsq_s8.c  | 16 ++--
 .../arm/mve/intrinsics/vabsq_x_f16.c  | 25 ---
 .../arm/mve/intrinsics/vabsq_x_f32.c  | 25 ---
 .../arm/mve/intrinsics/vabsq_x_s16.c  | 25 ---
 .../arm/mve/intrinsics/vabsq_x_s32.c  | 25 ---
 .../arm/mve/intrinsics/vabsq_x_s8.c   | 25 ---
 16 files changed, 309 insertions(+), 43 deletions(-)

diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 3330a220aea..bc4e2f2ac21 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -279,7 +279,7 @@ (define_insn "mve_vabsq_f"
(abs:MVE_0 (match_operand:MVE_0 1 "s_register_operand" "w")))
   ]
   "TARGET_HAVE_MVE && TARGET_HAVE_MVE_FLOAT"
-  "vabs.f%#  %q0, %q1"
+  "vabs.f%#\t%q0, %q1"
   [(set_attr "type" "mve_move")
 ])
 
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f16.c
index 08e141baedc..f29ada8c058 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f16.c
@@ -1,13 +1,33 @@
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /* { dg-add-options arm_v8_1m_mve_fp } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vabs.f16q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
 float16x8_t
 foo (float16x8_t a)
 {
   return vabsq_f16 (a);
 }
 
-/* { dg-final { scan-assembler "vabs.f16"  }  } */
+
+/*
+**foo1:
+** ...
+** vabs.f16q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+float16x8_t
+foo1 (float16x8_t a)
+{
+  return vabsq (a);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f32.c
index 3614a44fbdc..cc24744fb26 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_f32.c
@@ -1,13 +1,33 @@
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /* { dg-add-options arm_v8_1m_mve_fp } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vabs.f32q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
 float32x4_t
 foo (float32x4_t a)
 {
   return vabsq_f32 (a);
 }
 
-/* { dg-final { scan-assembler "vabs.f32"  }  } */
+
+/*
+**foo1:
+** ...
+** vabs.f32q[0-9]+, q[0-9]+(?: @.*|)
+** ...
+*/
+float32x4_t
+foo1 (float32x4_t a)
+{
+  return vabsq (a);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f16.c
index 30c14a151af..21cf284d045 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabsq_m_f16.c
@@ -1,22 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /

[PATCH 11/35] arm: improve tests for vabdq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vabdq_f16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vabdq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_m_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_m_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_m_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_m_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_m_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_x_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_x_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_x_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_x_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_x_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_x_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_x_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vabdq_x_u8.c: Likewise.
---
 .../gcc.target/arm/mve/intrinsics/vabdq_f16.c | 16 ++--
 .../gcc.target/arm/mve/intrinsics/vabdq_f32.c | 16 ++--
 .../arm/mve/intrinsics/vabdq_m_f16.c  | 26 ---
 .../arm/mve/intrinsics/vabdq_m_f32.c  | 26 ---
 .../arm/mve/intrinsics/vabdq_m_s16.c  | 26 ---
 .../arm/mve/intrinsics/vabdq_m_s32.c  | 26 ---
 .../arm/mve/intrinsics/vabdq_m_s8.c   | 26 ---
 .../arm/mve/intrinsics/vabdq_m_u16.c  | 26 ---
 .../arm/mve/intrinsics/vabdq_m_u32.c  | 26 ---
 .../arm/mve/intrinsics/vabdq_m_u8.c   | 26 ---
 .../gcc.target/arm/mve/intrinsics/vabdq_s16.c | 16 ++--
 .../gcc.target/arm/mve/intrinsics/vabdq_s32.c | 16 ++--
 .../gcc.target/arm/mve/intrinsics/vabdq_s8.c  | 16 ++--
 .../gcc.target/arm/mve/intrinsics/vabdq_u16.c | 16 ++--
 .../gcc.target/arm/mve/intrinsics/vabdq_u32.c | 16 ++--
 .../gcc.target/arm/mve/intrinsics/vabdq_u8.c  | 16 ++--
 .../arm/mve/intrinsics/vabdq_x_f16.c  | 25 +++---
 .../arm/mve/intrinsics/vabdq_x_f32.c  | 25 +++---
 .../arm/mve/intrinsics/vabdq_x_s16.c  | 26 ---
 .../arm/mve/intrinsics/vabdq_x_s32.c  | 25 +++---
 .../arm/mve/intrinsics/vabdq_x_s8.c   | 25 +++---
 .../arm/mve/intrinsics/vabdq_x_u16.c  | 25 +++---
 .../arm/mve/intrinsics/vabdq_x_u32.c  | 25 +++---
 .../arm/mve/intrinsics/vabdq_x_u8.c   | 25 +++---
 24 files changed, 464 insertions(+), 73 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f16.c
index b55e826e4b6..f379b25c49e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f16.c
@@ -1,21 +1,33 @@
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /* { dg-add-options arm_v8_1m_mve_fp } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vabd.f16q[0-9]+, q[0-9]+, q[0-9]+(?:@.*|)
+** ...
+*/
 float16x8_t
 foo (float16x8_t a, float16x8_t b)
 {
   return vabdq_f16 (a, b);
 }
 
-/* { dg-final { scan-assembler "vabd.f16"  }  } */
 
+/*
+**foo1:
+** ...
+** vabd.f16q[0-9]+, q[0-9]+, q[0-9]+(?:@.*|)
+** ...
+*/
 float16x8_t
 foo1 (float16x8_t a, float16x8_t b)
 {
   return vabdq (a, b);
 }
 
-/* { dg-final { scan-assembler "vabd.f16"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f32.c
index f1a95b14e03..3ba808e0b4d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vabdq_f32.c
@@ -1,21 +1,33 @@
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /* { dg-add-options arm_v8_1m_mve_fp } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vabd.f32q[0-9]+, q[0-9]+, q[0-9]+(?:@.*|)

[PATCH 16/35] arm: Add integer vector overloading of vsubq_x instrinsic

2022-11-17 Thread Andrea Corallo via Gcc-patches
From: Stam Markianos-Wright 

In the past we had only defined the vsubq_x generic overload of the
vsubq_x_* intrinsics for float vector types.  This would cause them
to fall back to the `__ARM_undef` failure state if they was called
through the generic version.
This patch simply adds these overloads.

gcc/ChangeLog:

* config/arm/arm_mve.h (__arm_vsubq_x FP): New overloads.
 (__arm_vsubq_x Integer): New.
---
 gcc/config/arm/arm_mve.h | 28 
 1 file changed, 28 insertions(+)

diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h
index f6b42dc3fab..09167ec118e 100644
--- a/gcc/config/arm/arm_mve.h
+++ b/gcc/config/arm/arm_mve.h
@@ -38259,6 +38259,18 @@ extern void *__ARM_undef;
 #define __arm_vsubq_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \
   __typeof(p2) __p2 = (p2); \
   _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
+  int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: 
__arm_vsubq_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, 
int8x16_t), p3), \
+  int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: 
__arm_vsubq_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, 
int16x8_t), p3), \
+  int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: 
__arm_vsubq_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, 
int32x4_t), p3), \
+  int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s8 
(__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+  int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s16 
(__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+  int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s32 
(__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+  int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: 
__arm_vsubq_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, 
uint8x16_t), p3), \
+  int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: 
__arm_vsubq_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, 
uint16x8_t), p3), \
+  int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_uint32x4_t]: 
__arm_vsubq_x_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce(__p2, 
uint32x4_t), p3), \
+  int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_u8 
(__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+  int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_int_n]: 
__arm_vsubq_x_n_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce3(p2, 
int), p3), \
+  int (*)[__ARM_mve_type_uint32x4_t][__ARM_mve_type_int_n]: 
__arm_vsubq_x_n_u32 (__ARM_mve_coerce(__p1, uint32x4_t), __ARM_mve_coerce3(p2, 
int), p3), \
   int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_float16x8_t]: 
__arm_vsubq_x_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce(__p2, 
float16x8_t), p3), \
   int (*)[__ARM_mve_type_float32x4_t][__ARM_mve_type_float32x4_t]: 
__arm_vsubq_x_f32 (__ARM_mve_coerce(__p1, float32x4_t), __ARM_mve_coerce(__p2, 
float32x4_t), p3), \
   int (*)[__ARM_mve_type_float16x8_t][__ARM_mve_type_fp_n]: 
__arm_vsubq_x_n_f16 (__ARM_mve_coerce(__p1, float16x8_t), __ARM_mve_coerce2(p2, 
double), p3), \
@@ -40223,6 +40235,22 @@ extern void *__ARM_undef;
   int (*)[__ARM_mve_type_uint16_t_ptr]: __arm_vld4q_u16 (__ARM_mve_coerce1(p0, 
uint16_t *)), \
   int (*)[__ARM_mve_type_uint32_t_ptr]: __arm_vld4q_u32 (__ARM_mve_coerce1(p0, 
uint32_t *
 
+#define __arm_vsubq_x(p1,p2,p3) ({ __typeof(p1) __p1 = (p1); \
+  __typeof(p2) __p2 = (p2); \
+  _Generic( (int (*)[__ARM_mve_typeid(__p1)][__ARM_mve_typeid(__p2)])0, \
+  int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int8x16_t]: 
__arm_vsubq_x_s8 (__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce(__p2, 
int8x16_t), p3), \
+  int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int16x8_t]: 
__arm_vsubq_x_s16 (__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce(__p2, 
int16x8_t), p3), \
+  int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int32x4_t]: 
__arm_vsubq_x_s32 (__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce(__p2, 
int32x4_t), p3), \
+  int (*)[__ARM_mve_type_int8x16_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s8 
(__ARM_mve_coerce(__p1, int8x16_t), __ARM_mve_coerce3(p2, int), p3), \
+  int (*)[__ARM_mve_type_int16x8_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s16 
(__ARM_mve_coerce(__p1, int16x8_t), __ARM_mve_coerce3(p2, int), p3), \
+  int (*)[__ARM_mve_type_int32x4_t][__ARM_mve_type_int_n]: __arm_vsubq_x_n_s32 
(__ARM_mve_coerce(__p1, int32x4_t), __ARM_mve_coerce3(p2, int), p3), \
+  int (*)[__ARM_mve_type_uint8x16_t][__ARM_mve_type_uint8x16_t]: 
__arm_vsubq_x_u8 (__ARM_mve_coerce(__p1, uint8x16_t), __ARM_mve_coerce(__p2, 
uint8x16_t), p3), \
+  int (*)[__ARM_mve_type_uint16x8_t][__ARM_mve_type_uint16x8_t]: 
__arm_vsubq_x_u16 (__ARM_mve_coerce(__p1, uint16x8_t), __ARM_mve_coerce(__p2, 
uint16x8_t), p3), \
+  i

[PATCH 27/35] arm: improve tests for vqaddq_m*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vqaddq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_m_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_m_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_m_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_m_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_m_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_m_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqaddq_u8.c: Likewise.
---
 .../arm/mve/intrinsics/vqaddq_m_n_s16.c   | 26 ++--
 .../arm/mve/intrinsics/vqaddq_m_n_s32.c   | 26 ++--
 .../arm/mve/intrinsics/vqaddq_m_n_s8.c| 26 ++--
 .../arm/mve/intrinsics/vqaddq_m_n_u16.c   | 42 +--
 .../arm/mve/intrinsics/vqaddq_m_n_u32.c   | 42 +--
 .../arm/mve/intrinsics/vqaddq_m_n_u8.c| 42 +--
 .../arm/mve/intrinsics/vqaddq_m_s16.c | 26 ++--
 .../arm/mve/intrinsics/vqaddq_m_s32.c | 26 ++--
 .../arm/mve/intrinsics/vqaddq_m_s8.c  | 26 ++--
 .../arm/mve/intrinsics/vqaddq_m_u16.c | 26 ++--
 .../arm/mve/intrinsics/vqaddq_m_u32.c | 26 ++--
 .../arm/mve/intrinsics/vqaddq_m_u8.c  | 26 ++--
 .../arm/mve/intrinsics/vqaddq_n_s16.c | 16 ++-
 .../arm/mve/intrinsics/vqaddq_n_s32.c | 16 ++-
 .../arm/mve/intrinsics/vqaddq_n_s8.c  | 16 ++-
 .../arm/mve/intrinsics/vqaddq_n_u16.c | 28 -
 .../arm/mve/intrinsics/vqaddq_n_u32.c | 28 -
 .../arm/mve/intrinsics/vqaddq_n_u8.c  | 28 -
 .../arm/mve/intrinsics/vqaddq_s16.c   | 16 ++-
 .../arm/mve/intrinsics/vqaddq_s32.c   | 16 ++-
 .../gcc.target/arm/mve/intrinsics/vqaddq_s8.c | 16 ++-
 .../arm/mve/intrinsics/vqaddq_u16.c   | 16 ++-
 .../arm/mve/intrinsics/vqaddq_u32.c   | 16 ++-
 .../gcc.target/arm/mve/intrinsics/vqaddq_u8.c | 16 ++-
 24 files changed, 516 insertions(+), 72 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c
index 65d3f770fe2..a659373d441 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s16.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s16  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
 foo (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
 {
   return vqaddq_m_n_s16 (inactive, a, b, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqaddt.s16  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
 foo1 (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
 {
   return vqaddq_m (inactive, a, b, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqaddt.s16"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s32.c
index 4499a0eaa41..8ffc6a67762 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqaddq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intri

[PATCH 33/35] arm: improve tests and fix vrmlaldavhaq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/ChangeLog:

* config/arm/mve.md (mve_vrmlaldavhq_v4si,
mve_vrmlaldavhaq_v4si): Fix spacing vs tabs.

gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c: Improve test.
* gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c: Likewise.
---
 gcc/config/arm/mve.md |  4 +-
 .../arm/mve/intrinsics/vrmlaldavhaq_p_s32.c   | 24 ++-
 .../arm/mve/intrinsics/vrmlaldavhaq_p_u32.c   | 40 ++-
 3 files changed, 62 insertions(+), 6 deletions(-)

diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index d2ffae6a425..b5e6da4b133 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -2543,7 +2543,7 @@ (define_insn "mve_vrmlaldavhq_v4si"
 VRMLALDAVHQ))
   ]
   "TARGET_HAVE_MVE"
-  "vrmlaldavh.32 %Q0, %R0, %q1, %q2"
+  "vrmlaldavh.32\t%Q0, %R0, %q1, %q2"
   [(set_attr "type" "mve_move")
 ])
 
@@ -2649,7 +2649,7 @@ (define_insn "mve_vrmlaldavhaq_v4si"
 VRMLALDAVHAQ))
   ]
   "TARGET_HAVE_MVE"
-  "vrmlaldavha.32 %Q0, %R0, %q2, %q3"
+  "vrmlaldavha.32\t%Q0, %R0, %q2, %q3"
   [(set_attr "type" "mve_move")
 ])
 
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c
index 263d3509771..dec4a969dfe 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_s32.c
@@ -1,21 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrmlaldavhat.s32(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, 
q[0-9]+(?:   @.*|)
+** ...
+*/
 int64_t
 foo (int64_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
 {
   return vrmlaldavhaq_p_s32 (a, b, c, p);
 }
 
-/* { dg-final { scan-assembler "vrmlaldavhat.s32"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrmlaldavhat.s32(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, 
q[0-9]+(?:   @.*|)
+** ...
+*/
 int64_t
 foo1 (int64_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
 {
   return vrmlaldavhaq_p (a, b, c, p);
 }
 
-/* { dg-final { scan-assembler "vrmlaldavhat.s32"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c
index 83ab68c001b..f3c8bfd121c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrmlaldavhaq_p_u32.c
@@ -1,21 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrmlaldavhat.u32(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, 
q[0-9]+(?:   @.*|)
+** ...
+*/
 uint64_t
 foo (uint64_t a, uint32x4_t b, uint32x4_t c, mve_pred16_t p)
 {
   return vrmlaldavhaq_p_u32 (a, b, c, p);
 }
 
-/* { dg-final { scan-assembler "vrmlaldavhat.u32"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrmlaldavhat.u32(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, 
q[0-9]+(?:   @.*|)
+** ...
+*/
 uint64_t
 foo1 (uint64_t a, uint32x4_t b, uint32x4_t c, mve_pred16_t p)
 {
   return vrmlaldavhaq_p (a, b, c, p);
 }
 
-/* { dg-final { scan-assembler "vrmlaldavhat.u32"  }  } */
+/*
+**foo2:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrmlaldavhat.u32(?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, 
q[0-9]+(?:   @.*|)
+** ...
+*/
+uint64_t
+foo2 (uint32x4_t b, uint32x4_t c, mve_pred16_t p)
+{
+  return vrmlaldavhaq_p (1, b, c, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
-- 
2.25.1



[PATCH 24/35] arm: improve tests for vmladavaq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c: Improve tests.
* gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmladavaq_p_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmladavaq_p_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmladavaq_p_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmladavaq_p_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmladavaxq_p_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmladavaxq_p_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmladavaxq_p_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmladavaxq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmladavaxq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmladavaxq_s8.c: Likewise.
---
 .../arm/mve/intrinsics/vmladavaq_p_s16.c  | 33 ++---
 .../arm/mve/intrinsics/vmladavaq_p_s32.c  | 33 ++---
 .../arm/mve/intrinsics/vmladavaq_p_s8.c   | 33 ++---
 .../arm/mve/intrinsics/vmladavaq_p_u16.c  | 49 ---
 .../arm/mve/intrinsics/vmladavaq_p_u32.c  | 49 ---
 .../arm/mve/intrinsics/vmladavaq_p_u8.c   | 49 ---
 .../arm/mve/intrinsics/vmladavaxq_p_s16.c | 33 ++---
 .../arm/mve/intrinsics/vmladavaxq_p_s32.c | 33 ++---
 .../arm/mve/intrinsics/vmladavaxq_p_s8.c  | 33 ++---
 .../arm/mve/intrinsics/vmladavaxq_s16.c   | 24 ++---
 .../arm/mve/intrinsics/vmladavaxq_s32.c   | 24 ++---
 .../arm/mve/intrinsics/vmladavaxq_s8.c| 24 ++---
 12 files changed, 336 insertions(+), 81 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c
index e458204c41b..f3e5eba3b08 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s16.c
@@ -1,22 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.s16   (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?:  @.*|)
+** ...
+*/
 int32_t
-foo (int32_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
+foo (int32_t add, int16x8_t m1, int16x8_t m2, mve_pred16_t p)
 {
-  return vmladavaq_p_s16 (a, b, c, p);
+  return vmladavaq_p_s16 (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vmladavat.s16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.s16   (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?:  @.*|)
+** ...
+*/
 int32_t
-foo1 (int32_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
+foo1 (int32_t add, int16x8_t m1, int16x8_t m2, mve_pred16_t p)
 {
-  return vmladavaq_p (a, b, c, p);
+  return vmladavaq_p (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vmladavat.s16"  }  } */
-/* { dg-final { scan-assembler "vmladavat.s16"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c
index e3544787adb..71f6957bfc5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmladavaq_p_s32.c
@@ -1,22 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.s32   (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?:  @.*|)
+** ...
+*/
 int32_t
-foo (int32_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
+foo (int32_t add, int32x4_t m1, int32x4_t m2, mve_pred16_t p)
 {
-  return vmladavaq_p_s32 (a, b, c, p);
+  return vmladavaq_p_s32 (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vmladavat.s32"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmladavat.s32   (?:ip|fp|r[0-9]+), q[0-9]+, q[0-9]+(?:  @.*|)
+** ...
+*/
 int32_t
-foo1 (int32_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
+foo1 (int32_t add, int32x4_t m1, int32x4_t m2, mve_pred16_t p)
 {
-  return vmladavaq_p (a, b, c, p);
+  return vmladavaq_p (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vmladavat.s32"  }  } */
-/* { dg-final { scan-assembler "vmladavat.s32"  }  } */
+/* { dg-final { scan-assembler-not "__A

[PATCH 23/35] arm: improve tests for viwdupq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c: Improve tests.
* gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_m_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_m_wb_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_wb_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_wb_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_wb_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_x_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_x_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_x_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/viwdupq_x_wb_u8.c: Likewise.
---
 .../arm/mve/intrinsics/viwdupq_m_n_u16.c  | 46 ++---
 .../arm/mve/intrinsics/viwdupq_m_n_u32.c  | 46 ++---
 .../arm/mve/intrinsics/viwdupq_m_n_u8.c   | 46 ++---
 .../arm/mve/intrinsics/viwdupq_m_wb_u16.c | 46 ++---
 .../arm/mve/intrinsics/viwdupq_m_wb_u32.c | 46 ++---
 .../arm/mve/intrinsics/viwdupq_m_wb_u8.c  | 46 ++---
 .../arm/mve/intrinsics/viwdupq_n_u16.c| 32 ++--
 .../arm/mve/intrinsics/viwdupq_n_u32.c| 32 ++--
 .../arm/mve/intrinsics/viwdupq_n_u8.c | 28 ++-
 .../arm/mve/intrinsics/viwdupq_wb_u16.c   | 36 ++---
 .../arm/mve/intrinsics/viwdupq_wb_u32.c   | 36 ++---
 .../arm/mve/intrinsics/viwdupq_wb_u8.c| 36 ++---
 .../arm/mve/intrinsics/viwdupq_x_n_u16.c  | 46 ++---
 .../arm/mve/intrinsics/viwdupq_x_n_u32.c  | 46 ++---
 .../arm/mve/intrinsics/viwdupq_x_n_u8.c   | 46 ++---
 .../arm/mve/intrinsics/viwdupq_x_wb_u16.c | 50 ---
 .../arm/mve/intrinsics/viwdupq_x_wb_u32.c | 50 ---
 .../arm/mve/intrinsics/viwdupq_x_wb_u8.c  | 50 ---
 18 files changed, 658 insertions(+), 106 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c
index 0f999cc672b..67a2465f435 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u16.c
@@ -1,23 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), 
#[0-9]+(?:   @.*|)
+** ...
+*/
 uint16x8_t
 foo (uint16x8_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
 {
-  return viwdupq_m_n_u16 (inactive, a, b, 2, p);
+  return viwdupq_m_n_u16 (inactive, a, b, 1, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), 
#[0-9]+(?:   @.*|)
+** ...
+*/
 uint16x8_t
 foo1 (uint16x8_t inactive, uint32_t a, uint32_t b, mve_pred16_t p)
 {
-  return viwdupq_m (inactive, a, b, 2, p);
+  return viwdupq_m (inactive, a, b, 1, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "viwdupt.u16"  }  } */
+/*
+**foo2:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** viwdupt.u16 q[0-9]+, (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), 
#[0-9]+(?:   @.*|)
+** ...
+*/
+uint16x8_t
+foo2 (uint16x8_t inactive, mve_pred16_t p)
+{
+  return viwdupq_m (inactive, 1, 1, 1, p);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c
index f79c91eaf4c..9fc2518acc5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/viwdupq_m_n_u32.c
@@ -1,23 +1,57 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve 

[PATCH 19/35] arm: improve tests and fix vsubq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/ChangeLog:

* config/arm/mve.md (mve_vsubq_n_f): Fix spacing.

gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vsubq_f16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vsubq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_m_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vsubq_x_u8.c: Likewise.
---
 gcc/config/arm/mve.md |  2 +-
 .../gcc.target/arm/mve/intrinsics/vsubq_f16.c | 16 ++-
 .../gcc.target/arm/mve/intrinsics/vsubq_f32.c | 16 ++-
 .../arm/mve/intrinsics/vsubq_m_f16.c  | 26 --
 .../arm/mve/intrinsics/vsubq_m_f32.c  | 26 --
 .../arm/mve/intrinsics/vsubq_m_n_f16.c| 42 ++--
 .../arm/mve/intrinsics/vsubq_m_n_f32.c| 42 ++--
 .../arm/mve/intrinsics/vsubq_m_n_s16.c| 26 --
 .../arm/mve/intrinsics/vsubq_m_n_s32.c| 26 --
 .../arm/mve/intrinsics/vsubq_m_n_s8.c | 26 --
 .../arm/mve/intrinsics/vsubq_m_n_u16.c| 42 ++--
 .../arm/mve/intrinsics/vsubq_m_n_u32.c| 42 ++--
 .../arm/mve/intrinsics/vsubq_m_n_u8.c | 42 ++--
 .../arm/mve/intrinsics/vsubq_m_s16.c  | 25 --
 .../arm/mve/intrinsics/vsubq_m_s32.c  | 25 --
 .../arm/mve/intrinsics/vsubq_m_s8.c   | 25 --
 .../arm/mve/intrinsics/vsubq_m_u16.c  | 25 --
 .../arm/mve/intrinsics/vsubq_m_u32.c  | 25 --
 .../arm/mve/intrinsics/vsubq_m_u8.c   | 25 --
 .../arm/mve/intrinsics/vsubq_n_f16.c  | 28 ++-
 .../arm/mve/intrinsics/vsubq_n_f32.c  | 28 ++-
 .../arm/mve/intrinsics/vsubq_n_s16.c  | 17 +--
 .../arm/mve/intrinsics/vsubq_n_s32.c  | 17 +--
 .../arm/mve/intrinsics/vsubq_n_s8.c   | 17 +--
 .../arm/mve/intrinsics/vsubq_n_u16.c  | 29 +--
 .../arm/mve/intrinsics/vsubq_n_u32.c  | 29 +--
 .../arm/mve/intrinsics/vsubq_n_u8.c   | 29 +--
 .../gcc.target/arm/mve/intrinsics/vsubq_s16.c | 16 +

[PATCH 30/35] arm: improve tests for vqrdmlahq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqrdmlahq_n_s8.c: Likewise.
---
 .../arm/mve/intrinsics/vqrdmlahq_m_n_s16.c| 34 ++-
 .../arm/mve/intrinsics/vqrdmlahq_m_n_s32.c| 34 ++-
 .../arm/mve/intrinsics/vqrdmlahq_m_n_s8.c | 34 ++-
 .../arm/mve/intrinsics/vqrdmlahq_n_s16.c  | 24 +
 .../arm/mve/intrinsics/vqrdmlahq_n_s32.c  | 24 +
 .../arm/mve/intrinsics/vqrdmlahq_n_s8.c   | 24 +
 6 files changed, 132 insertions(+), 42 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c
index 70c3fa0e9b1..07d689279ac 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s16.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlaht.s16   q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo (int16x8_t add, int16x8_t m1, int16_t m2, mve_pred16_t p)
 {
-  return vqrdmlahq_m_n_s16 (a, b, c, p);
+  return vqrdmlahq_m_n_s16 (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlaht.s16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlaht.s16   q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo1 (int16x8_t add, int16x8_t m1, int16_t m2, mve_pred16_t p)
 {
-  return vqrdmlahq_m (a, b, c, p);
+  return vqrdmlahq_m (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlaht.s16"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c
index 75ed9911276..3b02ca16038 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s32.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlaht.s32   q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo (int32x4_t add, int32x4_t m1, int32_t m2, mve_pred16_t p)
 {
-  return vqrdmlahq_m_n_s32 (a, b, c, p);
+  return vqrdmlahq_m_n_s32 (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlaht.s32"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqrdmlaht.s32   q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo1 (int32x4_t add, int32x4_t m1, int32_t m2, mve_pred16_t p)
 {
-  return vqrdmlahq_m (a, b, c, p);
+  return vqrdmlahq_m (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqrdmlaht.s32"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c
index ddaea545f40..b661bdcb4cf 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqrdmlahq_m_n_s8.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** 

[PATCH 08/35] arm: improve tests for vmin*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vminaq_m_s16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vminaq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminaq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminaq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminaq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminaq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminavq_p_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminavq_p_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminavq_p_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminavq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminavq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminavq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmaq_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmaq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmaq_m_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmaq_m_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmavq_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmavq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmavq_p_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmavq_p_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmq_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmq_m_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmq_m_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmq_x_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmq_x_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmvq_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmvq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmvq_p_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminnmvq_p_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_m_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_m_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_m_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_x_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_x_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_x_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_x_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_x_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminq_x_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_p_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_p_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_p_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_p_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_p_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_p_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vminvq_u8.c: Likewise.
---
 .../arm/mve/intrinsics/vminaq_m_s16.c | 25 +--
 .../arm/mve/intrinsics/vminaq_m_s32.c | 25 +--
 .../arm/mve/intrinsics/vminaq_m_s8.c  | 25 +--
 .../arm/mve/intrinsics/vminaq_s16.c   | 16 +++-
 .../arm/mve/intrinsics/vminaq_s32.c   | 16 +++-
 .../gcc.target/arm/mve/intrinsics/vminaq_s8.c | 16 +++-
 .../arm/mve/intrinsics/vminavq_p_s16.c| 41 ---
 .../arm/mve/intrinsics/vminavq_p_s32.c| 41 ---
 .../arm/mve/intrinsics/vminavq_p_s8.c | 41 ---
 .../arm/mve/intrinsics/vminavq_s16.c  | 29 ++---
 .../arm/mve/intrinsics/vminavq_s32.c  | 29 ++---
 .../arm/mve/intrinsics/vminavq_s8.c   | 29 ++---
 .../arm/mve/intrinsics/vminnmaq_f16.c | 16 +++-
 .../arm/mve/intrinsics/vminnmaq_f32.c | 16 +++-
 .../arm/mve/intrinsics/vminnmaq_m_f16.c   | 25 +--
 .../arm/mve/intrinsics/vminnmaq_m_f32.c   | 25 +--
 .../arm/m

[PATCH 22/35] arm: improve tests for vhsubq_m*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vhsubq_m_n_s16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vhsubq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_m_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_m_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_m_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_m_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_m_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_m_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhsubq_x_u8.c: Likewise.
---
 .../arm/mve/intrinsics/vhsubq_m_n_s16.c   | 26 ++--
 .../arm/mve/intrinsics/vhsubq_m_n_s32.c   | 26 ++--
 .../arm/mve/intrinsics/vhsubq_m_n_s8.c| 26 ++--
 .../arm/mve/intrinsics/vhsubq_m_n_u16.c   | 42 +--
 .../arm/mve/intrinsics/vhsubq_m_n_u32.c   | 42 +--
 .../arm/mve/intrinsics/vhsubq_m_n_u8.c| 42 +--
 .../arm/mve/intrinsics/vhsubq_m_s16.c | 26 ++--
 .../arm/mve/intrinsics/vhsubq_m_s32.c | 26 ++--
 .../arm/mve/intrinsics/vhsubq_m_s8.c  | 26 ++--
 .../arm/mve/intrinsics/vhsubq_m_u16.c | 26 ++--
 .../arm/mve/intrinsics/vhsubq_m_u32.c | 26 ++--
 .../arm/mve/intrinsics/vhsubq_m_u8.c  | 26 ++--
 .../arm/mve/intrinsics/vhsubq_n_s16.c | 16 ++-
 .../arm/mve/intrinsics/vhsubq_n_s32.c | 16 ++-
 .../arm/mve/intrinsics/vhsubq_n_s8.c  | 16 ++-
 .../arm/mve/intrinsics/vhsubq_n_u16.c | 28 -
 .../arm/mve/intrinsics/vhsubq_n_u32.c | 28 -
 .../arm/mve/intrinsics/vhsubq_n_u8.c  | 28 -
 .../arm/mve/intrinsics/vhsubq_s16.c   | 16 ++-
 .../arm/mve/intrinsics/vhsubq_s32.c   | 16 ++-
 .../gcc.target/arm/mve/intrinsics/vhsubq_s8.c | 16 ++-
 .../arm/mve/intrinsics/vhsubq_u16.c   | 16 ++-
 .../arm/mve/intrinsics/vhsubq_u32.c   | 16 ++-
 .../gcc.target/arm/mve/intrinsics/vhsubq_u8.c | 16 ++-
 .../arm/mve/intrinsics/vhsubq_x_n_s16.c   | 26 ++--
 .../arm/mve/intrinsics/vhsubq_x_n_s32.c   | 26 ++--
 .../arm/mve/intrinsics/vhsubq_x_n_s8.c| 26 ++--
 .../arm/mve/intrinsics/vhsubq_x_n_u16.c   | 42 +--
 .../arm/mve/intrinsics/vhsubq_x_n_u32.c   | 42 +--
 .../arm/mve/intrinsics/vhsubq_x_n_u8.c| 42 +--
 .../arm/mve/intrinsics/vhsubq_x_s16.c | 25 +--
 .../arm/mve/intrinsics/vhsubq_x_s32.c | 25 +--
 .../arm/mve/intrinsics/vhsubq_x_s8.c  | 25 +--
 .../arm/mve/intrinsics/vhsubq_x_u16.c | 25 +--
 .../arm/mve/intrinsics/vhsubq_x_u32.c | 25 +--
 .../arm/mve/intrinsics/vhsubq_x_u8.c  | 25 +--
 36 files changed, 828 insertions(+), 114 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhsubq_m_n_s16.c
index 27dcb7be957..6390589808f 100644
--- a/gcc/testsuite/gcc

[PATCH 25/35] arm: improve tests and fix vmlaldavaxq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/ChangeLog:

* config/arm/mve.md (mve_vmlaldavaq_)
(mve_vmlaldavaxq_s, mve_vmlaldavaxq_p_): Fix
spacing vs tabs.

gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c: Improve tests.
* gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlaldavaxq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlaldavaxq_s32.c: Likewise.
---
 gcc/config/arm/mve.md |  6 ++--
 .../arm/mve/intrinsics/vmlaldavaxq_p_s16.c| 32 +++
 .../arm/mve/intrinsics/vmlaldavaxq_p_s32.c| 32 +++
 .../arm/mve/intrinsics/vmlaldavaxq_s16.c  | 24 ++
 .../arm/mve/intrinsics/vmlaldavaxq_s32.c  | 24 ++
 5 files changed, 91 insertions(+), 27 deletions(-)

diff --git a/gcc/config/arm/mve.md b/gcc/config/arm/mve.md
index 714dc6fc7ce..d2ffae6a425 100644
--- a/gcc/config/arm/mve.md
+++ b/gcc/config/arm/mve.md
@@ -4163,7 +4163,7 @@ (define_insn "mve_vmlaldavaq_"
 VMLALDAVAQ))
   ]
   "TARGET_HAVE_MVE"
-  "vmlaldava.%# %Q0, %R0, %q2, %q3"
+  "vmlaldava.%#\t%Q0, %R0, %q2, %q3"
   [(set_attr "type" "mve_move")
 ])
 
@@ -4179,7 +4179,7 @@ (define_insn "mve_vmlaldavaxq_s"
 VMLALDAVAXQ_S))
   ]
   "TARGET_HAVE_MVE"
-  "vmlaldavax.s%# %Q0, %R0, %q2, %q3"
+  "vmlaldavax.s%#\t%Q0, %R0, %q2, %q3"
   [(set_attr "type" "mve_move")
 ])
 
@@ -6126,7 +6126,7 @@ (define_insn "mve_vmlaldavaxq_p_"
 VMLALDAVAXQ_P))
   ]
   "TARGET_HAVE_MVE"
-  "vpst\;vmlaldavaxt.%# %Q0, %R0, %q2, %q3"
+  "vpst\;vmlaldavaxt.%#\t%Q0, %R0, %q2, %q3"
   [(set_attr "type" "mve_move")
(set_attr "length""8")])
 
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c
index f33d3880236..87f0354a636 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s16.c
@@ -1,21 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlaldavaxt.s16 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, 
q[0-9]+(?:   @.*|)
+** ...
+*/
 int64_t
-foo (int64_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
+foo (int64_t add, int16x8_t m1, int16x8_t m2, mve_pred16_t p)
 {
-  return vmlaldavaxq_p_s16 (a, b, c, p);
+  return vmlaldavaxq_p_s16 (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vmlaldavaxt.s16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlaldavaxt.s16 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, 
q[0-9]+(?:   @.*|)
+** ...
+*/
 int64_t
-foo1 (int64_t a, int16x8_t b, int16x8_t c, mve_pred16_t p)
+foo1 (int64_t add, int16x8_t m1, int16x8_t m2, mve_pred16_t p)
 {
-  return vmlaldavaxq_p (a, b, c, p);
+  return vmlaldavaxq_p (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vmlaldavaxt.s16"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c
index ab072a9850e..d26bf5b90af 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlaldavaxq_p_s32.c
@@ -1,21 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlaldavaxt.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, 
q[0-9]+(?:   @.*|)
+** ...
+*/
 int64_t
-foo (int64_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
+foo (int64_t add, int32x4_t m1, int32x4_t m2, mve_pred16_t p)
 {
-  return vmlaldavaxq_p_s32 (a, b, c, p);
+  return vmlaldavaxq_p_s32 (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vmlaldavaxt.s32"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlaldavaxt.s32 (?:ip|fp|r[0-9]+), (?:ip|fp|r[0-9]+), q[0-9]+, 
q[0-9]+(?:   @.*|)
+** ...
+*/
 int64_t
-foo1 (int64_t a, int32x4_t b, int32x4_t c, mve_pred16_t p)
+foo1 (int64_t add, int32x4_t m1, int32x4_t m2, mve_pred16_t p)
 {
-  return vmlaldavaxq_p (a, b, c, p);
+  return vmlaldavaxq_p (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vmlaldavaxt.s32"  }  } */
+/* { dg-final { scan-assemb

[PATCH 28/35] arm: improve tests for vqdmlahq_m*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmlahq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmlahq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmlahq_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmlashq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmlashq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmlashq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmlashq_n_s8.c: Likewise.
---
 .../arm/mve/intrinsics/vqdmlahq_m_n_s16.c | 34 ++-
 .../arm/mve/intrinsics/vqdmlahq_m_n_s32.c | 34 ++-
 .../arm/mve/intrinsics/vqdmlahq_m_n_s8.c  | 34 ++-
 .../arm/mve/intrinsics/vqdmlahq_n_s16.c   | 24 +
 .../arm/mve/intrinsics/vqdmlahq_n_s32.c   | 24 +
 .../arm/mve/intrinsics/vqdmlahq_n_s8.c| 24 +
 .../arm/mve/intrinsics/vqdmlashq_m_n_s16.c| 34 ++-
 .../arm/mve/intrinsics/vqdmlashq_m_n_s32.c| 34 ++-
 .../arm/mve/intrinsics/vqdmlashq_m_n_s8.c | 34 ++-
 .../arm/mve/intrinsics/vqdmlashq_n_s16.c  | 24 +
 .../arm/mve/intrinsics/vqdmlashq_n_s32.c  | 24 +
 .../arm/mve/intrinsics/vqdmlashq_n_s8.c   | 24 +
 12 files changed, 264 insertions(+), 84 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c
index d8c4f4bab8e..94d93874542 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s16.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlaht.s16q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo (int16x8_t add, int16x8_t m1, int16_t m2, mve_pred16_t p)
 {
-  return vqdmlahq_m_n_s16 (a, b, c, p);
+  return vqdmlahq_m_n_s16 (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlaht.s16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlaht.s16q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo1 (int16x8_t add, int16x8_t m1, int16_t m2, mve_pred16_t p)
 {
-  return vqdmlahq_m (a, b, c, p);
+  return vqdmlahq_m (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlaht.s16"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c
index 361f5d00bdf..a3dab7fa02e 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmlahq_m_n_s32.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlaht.s32q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo (int32x4_t add, int32x4_t m1, int32_t m2, mve_pred16_t p)
 {
-  return vqdmlahq_m_n_s32 (a, b, c, p);
+  return vqdmlahq_m_n_s32 (add, m1, m2, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmlaht.s32"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmlaht.s32q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo1 (int32x4_t add, int32x4_t m1, int32_t m2, mve_pred16_t p)
 {
-  return vqdmlahq_m (a, b, c, p);
+  return vqdmlahq_m (add, m1, m2, p);
 }
 
-/* { dg-final { scan-ass

[PATCH 18/35] arm: improve tests for vmulq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vmulq_f16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vmulq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_m_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmulq_x_u8.c: Likewise.
---
 .../gcc.target/arm/mve/intrinsics/vmulq_f16.c | 16 ++-
 .../gcc.target/arm/mve/intrinsics/vmulq_f32.c | 16 ++-
 .../arm/mve/intrinsics/vmulq_m_f16.c  | 26 ++--
 .../arm/mve/intrinsics/vmulq_m_f32.c  | 26 ++--
 .../arm/mve/intrinsics/vmulq_m_n_f16.c| 42 +--
 .../arm/mve/intrinsics/vmulq_m_n_f32.c| 42 +--
 .../arm/mve/intrinsics/vmulq_m_n_s16.c| 26 ++--
 .../arm/mve/intrinsics/vmulq_m_n_s32.c| 26 ++--
 .../arm/mve/intrinsics/vmulq_m_n_s8.c | 26 ++--
 .../arm/mve/intrinsics/vmulq_m_n_u16.c| 42 +--
 .../arm/mve/intrinsics/vmulq_m_n_u32.c| 42 +--
 .../arm/mve/intrinsics/vmulq_m_n_u8.c | 42 +--
 .../arm/mve/intrinsics/vmulq_m_s16.c  | 26 ++--
 .../arm/mve/intrinsics/vmulq_m_s32.c  | 26 ++--
 .../arm/mve/intrinsics/vmulq_m_s8.c   | 26 ++--
 .../arm/mve/intrinsics/vmulq_m_u16.c  | 26 ++--
 .../arm/mve/intrinsics/vmulq_m_u32.c  | 26 ++--
 .../arm/mve/intrinsics/vmulq_m_u8.c   | 26 ++--
 .../arm/mve/intrinsics/vmulq_n_f16.c  | 28 -
 .../arm/mve/intrinsics/vmulq_n_f32.c  | 28 -
 .../arm/mve/intrinsics/vmulq_n_s16.c  | 16 ++-
 .../arm/mve/intrinsics/vmulq_n_s32.c  | 16 ++-
 .../arm/mve/intrinsics/vmulq_n_s8.c   | 16 ++-
 .../arm/mve/intrinsics/vmulq_n_u16.c  | 28 -
 .../arm/mve/intrinsics/vmulq_n_u32.c  | 28 -
 .../arm/mve/intrinsics/vmulq_n_u8.c   | 28 -
 .../gcc.target/arm/mve/intrinsics/vmulq_s16.c | 16 ++-
 .../gcc.target/arm/mve/intrinsics/vmulq_s32.c | 16 ++-
 .../gcc.target/

[PATCH 34/35] arm: improve tests for vrshlq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c: Improve tests.
* gcc.target/arm/mve/intrinsics/vrshlq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_m_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_m_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_m_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_m_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_m_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_m_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_x_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_x_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_x_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_x_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_x_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vrshlq_x_u8.c: Likewise.
---
 .../arm/mve/intrinsics/vrshlq_m_n_s16.c   | 25 +++---
 .../arm/mve/intrinsics/vrshlq_m_n_s32.c   | 25 +++---
 .../arm/mve/intrinsics/vrshlq_m_n_s8.c| 25 +++---
 .../arm/mve/intrinsics/vrshlq_m_n_u16.c   | 25 +++---
 .../arm/mve/intrinsics/vrshlq_m_n_u32.c   | 25 +++---
 .../arm/mve/intrinsics/vrshlq_m_n_u8.c| 25 +++---
 .../arm/mve/intrinsics/vrshlq_m_s16.c | 26 ---
 .../arm/mve/intrinsics/vrshlq_m_s32.c | 26 ---
 .../arm/mve/intrinsics/vrshlq_m_s8.c  | 26 ---
 .../arm/mve/intrinsics/vrshlq_m_u16.c | 26 ---
 .../arm/mve/intrinsics/vrshlq_m_u32.c | 26 ---
 .../arm/mve/intrinsics/vrshlq_m_u8.c  | 26 ---
 .../arm/mve/intrinsics/vrshlq_n_s16.c | 16 ++--
 .../arm/mve/intrinsics/vrshlq_n_s32.c | 16 ++--
 .../arm/mve/intrinsics/vrshlq_n_s8.c  | 16 ++--
 .../arm/mve/intrinsics/vrshlq_n_u16.c | 16 ++--
 .../arm/mve/intrinsics/vrshlq_n_u32.c | 16 ++--
 .../arm/mve/intrinsics/vrshlq_n_u8.c  | 16 ++--
 .../arm/mve/intrinsics/vrshlq_s16.c   | 16 ++--
 .../arm/mve/intrinsics/vrshlq_s32.c   | 16 ++--
 .../gcc.target/arm/mve/intrinsics/vrshlq_s8.c | 16 ++--
 .../arm/mve/intrinsics/vrshlq_u16.c   | 16 ++--
 .../arm/mve/intrinsics/vrshlq_u32.c   | 16 ++--
 .../gcc.target/arm/mve/intrinsics/vrshlq_u8.c | 16 ++--
 .../arm/mve/intrinsics/vrshlq_x_s16.c | 25 +++---
 .../arm/mve/intrinsics/vrshlq_x_s32.c | 25 +++---
 .../arm/mve/intrinsics/vrshlq_x_s8.c  | 25 +++---
 .../arm/mve/intrinsics/vrshlq_x_u16.c | 25 +++---
 .../arm/mve/intrinsics/vrshlq_x_u32.c | 25 +++---
 .../arm/mve/intrinsics/vrshlq_x_u8.c  | 25 +++---
 30 files changed, 564 insertions(+), 84 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c
index cf51de6aa9c..c7d1f3a5b1c 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vrshlq_m_n_s16.c
@@ -1,22 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vrshlt.s16  q[0-9]+, (?:ip|fp|r[0-9]+)(?:   @.*|)
+** ...
+*/
 int16x8_t
 foo (int16x8_t a, int32_t b, mve_pred16_t p)
 {
   return vrshlq_m_n_s16 (a, b, p);
 }
 
-/* { dg-final { scan-assembl

[PATCH 26/35] arm: improve tests for vmlasq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlasq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlasq_m_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlasq_m_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlasq_m_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlasq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlasq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlasq_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlasq_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlasq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmlasq_n_u8.c: Likewise.
---
 .../arm/mve/intrinsics/vmlasq_m_n_s16.c   | 34 ++---
 .../arm/mve/intrinsics/vmlasq_m_n_s32.c   | 34 ++---
 .../arm/mve/intrinsics/vmlasq_m_n_s8.c| 34 ++---
 .../arm/mve/intrinsics/vmlasq_m_n_u16.c   | 50 ---
 .../arm/mve/intrinsics/vmlasq_m_n_u32.c   | 50 ---
 .../arm/mve/intrinsics/vmlasq_m_n_u8.c| 50 ---
 .../arm/mve/intrinsics/vmlasq_n_s16.c | 24 ++---
 .../arm/mve/intrinsics/vmlasq_n_s32.c | 24 ++---
 .../arm/mve/intrinsics/vmlasq_n_s8.c  | 24 ++---
 .../arm/mve/intrinsics/vmlasq_n_u16.c | 36 ++---
 .../arm/mve/intrinsics/vmlasq_n_u32.c | 36 ++---
 .../arm/mve/intrinsics/vmlasq_n_u8.c  | 36 ++---
 12 files changed, 348 insertions(+), 84 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c
index bf66e616ec7..af6e588adad 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s16.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.s16  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
-foo (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo (int16x8_t m1, int16x8_t m2, int16_t add, mve_pred16_t p)
 {
-  return vmlasq_m_n_s16 (a, b, c, p);
+  return vmlasq_m_n_s16 (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.s16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.s16  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
-foo1 (int16x8_t a, int16x8_t b, int16_t c, mve_pred16_t p)
+foo1 (int16x8_t m1, int16x8_t m2, int16_t add, mve_pred16_t p)
 {
-  return vmlasq_m (a, b, c, p);
+  return vmlasq_m (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.s16"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c
index 53c21e2e5b6..9d0cc3076d9 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vmlasq_m_n_s32.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.s32  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int32x4_t
-foo (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo (int32x4_t m1, int32x4_t m2, int32_t add, mve_pred16_t p)
 {
-  return vmlasq_m_n_s32 (a, b, c, p);
+  return vmlasq_m_n_s32 (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.s32"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vmlast.s32  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int32x4_t
-foo1 (int32x4_t a, int32x4_t b, int32_t c, mve_pred16_t p)
+foo1 (int32x4_t m1, int32x4_t m2, int32_t add, mve_pred16_t p)
 {
-  return vmlasq_m (a, b, c, p);
+  return vmlasq_m (m1, m2, add, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vmlast.s32"  }  } */
+/* { dg-final { scan-a

[PATCH 21/35] arm: improve tests for vhaddq_m*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vhaddq_m_n_s16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vhaddq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_m_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_m_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_m_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_m_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_m_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_m_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vhaddq_x_u8.c: Likewise.
---
 .../arm/mve/intrinsics/vhaddq_m_n_s16.c   | 26 ++--
 .../arm/mve/intrinsics/vhaddq_m_n_s32.c   | 26 ++--
 .../arm/mve/intrinsics/vhaddq_m_n_s8.c| 26 ++--
 .../arm/mve/intrinsics/vhaddq_m_n_u16.c   | 42 +--
 .../arm/mve/intrinsics/vhaddq_m_n_u32.c   | 42 +--
 .../arm/mve/intrinsics/vhaddq_m_n_u8.c| 42 +--
 .../arm/mve/intrinsics/vhaddq_m_s16.c | 26 ++--
 .../arm/mve/intrinsics/vhaddq_m_s32.c | 26 ++--
 .../arm/mve/intrinsics/vhaddq_m_s8.c  | 26 ++--
 .../arm/mve/intrinsics/vhaddq_m_u16.c | 26 ++--
 .../arm/mve/intrinsics/vhaddq_m_u32.c | 26 ++--
 .../arm/mve/intrinsics/vhaddq_m_u8.c  | 26 ++--
 .../arm/mve/intrinsics/vhaddq_n_s16.c | 16 ++-
 .../arm/mve/intrinsics/vhaddq_n_s32.c | 16 ++-
 .../arm/mve/intrinsics/vhaddq_n_s8.c  | 16 ++-
 .../arm/mve/intrinsics/vhaddq_n_u16.c | 28 -
 .../arm/mve/intrinsics/vhaddq_n_u32.c | 28 -
 .../arm/mve/intrinsics/vhaddq_n_u8.c  | 28 -
 .../arm/mve/intrinsics/vhaddq_s16.c   | 16 ++-
 .../arm/mve/intrinsics/vhaddq_s32.c   | 16 ++-
 .../gcc.target/arm/mve/intrinsics/vhaddq_s8.c | 16 ++-
 .../arm/mve/intrinsics/vhaddq_u16.c   | 16 ++-
 .../arm/mve/intrinsics/vhaddq_u32.c   | 16 ++-
 .../gcc.target/arm/mve/intrinsics/vhaddq_u8.c | 16 ++-
 .../arm/mve/intrinsics/vhaddq_x_n_s16.c   | 26 ++--
 .../arm/mve/intrinsics/vhaddq_x_n_s32.c   | 26 ++--
 .../arm/mve/intrinsics/vhaddq_x_n_s8.c| 26 ++--
 .../arm/mve/intrinsics/vhaddq_x_n_u16.c   | 42 +--
 .../arm/mve/intrinsics/vhaddq_x_n_u32.c   | 42 +--
 .../arm/mve/intrinsics/vhaddq_x_n_u8.c| 42 +--
 .../arm/mve/intrinsics/vhaddq_x_s16.c | 25 +--
 .../arm/mve/intrinsics/vhaddq_x_s32.c | 25 +--
 .../arm/mve/intrinsics/vhaddq_x_s8.c  | 25 +--
 .../arm/mve/intrinsics/vhaddq_x_u16.c | 25 +--
 .../arm/mve/intrinsics/vhaddq_x_u32.c | 25 +--
 .../arm/mve/intrinsics/vhaddq_x_u8.c  | 25 +--
 36 files changed, 828 insertions(+), 114 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vhaddq_m_n_s16.c
index e90af963697..0bd03832ff5 100644
--- a/gcc/testsuite/gcc

[PATCH 32/35] arm: improve tests for vqsubq*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c:
* gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c:
* gcc.target/arm/mve/intrinsics/vqsubq_m_n_s8.c:
* gcc.target/arm/mve/intrinsics/vqsubq_m_n_u16.c:
* gcc.target/arm/mve/intrinsics/vqsubq_m_n_u32.c:
* gcc.target/arm/mve/intrinsics/vqsubq_m_n_u8.c:
* gcc.target/arm/mve/intrinsics/vqsubq_m_s16.c:
* gcc.target/arm/mve/intrinsics/vqsubq_m_s32.c:
* gcc.target/arm/mve/intrinsics/vqsubq_m_s8.c:
* gcc.target/arm/mve/intrinsics/vqsubq_m_u16.c:
* gcc.target/arm/mve/intrinsics/vqsubq_m_u32.c:
* gcc.target/arm/mve/intrinsics/vqsubq_m_u8.c:
* gcc.target/arm/mve/intrinsics/vqsubq_n_s16.c:
* gcc.target/arm/mve/intrinsics/vqsubq_n_s32.c:
* gcc.target/arm/mve/intrinsics/vqsubq_n_s8.c:
* gcc.target/arm/mve/intrinsics/vqsubq_n_u16.c:
* gcc.target/arm/mve/intrinsics/vqsubq_n_u32.c:
* gcc.target/arm/mve/intrinsics/vqsubq_n_u8.c:
* gcc.target/arm/mve/intrinsics/vqsubq_s16.c:
* gcc.target/arm/mve/intrinsics/vqsubq_s32.c:
* gcc.target/arm/mve/intrinsics/vqsubq_s8.c:
* gcc.target/arm/mve/intrinsics/vqsubq_u16.c:
* gcc.target/arm/mve/intrinsics/vqsubq_u32.c:
* gcc.target/arm/mve/intrinsics/vqsubq_u8.c:
---
 .../arm/mve/intrinsics/vqsubq_m_n_s16.c   | 26 ++--
 .../arm/mve/intrinsics/vqsubq_m_n_s32.c   | 26 ++--
 .../arm/mve/intrinsics/vqsubq_m_n_s8.c| 26 ++--
 .../arm/mve/intrinsics/vqsubq_m_n_u16.c   | 42 +--
 .../arm/mve/intrinsics/vqsubq_m_n_u32.c   | 42 +--
 .../arm/mve/intrinsics/vqsubq_m_n_u8.c| 42 +--
 .../arm/mve/intrinsics/vqsubq_m_s16.c | 26 ++--
 .../arm/mve/intrinsics/vqsubq_m_s32.c | 26 ++--
 .../arm/mve/intrinsics/vqsubq_m_s8.c  | 26 ++--
 .../arm/mve/intrinsics/vqsubq_m_u16.c | 26 ++--
 .../arm/mve/intrinsics/vqsubq_m_u32.c | 26 ++--
 .../arm/mve/intrinsics/vqsubq_m_u8.c  | 26 ++--
 .../arm/mve/intrinsics/vqsubq_n_s16.c | 16 ++-
 .../arm/mve/intrinsics/vqsubq_n_s32.c | 16 ++-
 .../arm/mve/intrinsics/vqsubq_n_s8.c  | 16 ++-
 .../arm/mve/intrinsics/vqsubq_n_u16.c | 28 -
 .../arm/mve/intrinsics/vqsubq_n_u32.c | 28 -
 .../arm/mve/intrinsics/vqsubq_n_u8.c  | 28 -
 .../arm/mve/intrinsics/vqsubq_s16.c   | 16 ++-
 .../arm/mve/intrinsics/vqsubq_s32.c   | 16 ++-
 .../gcc.target/arm/mve/intrinsics/vqsubq_s8.c | 16 ++-
 .../arm/mve/intrinsics/vqsubq_u16.c   | 16 ++-
 .../arm/mve/intrinsics/vqsubq_u32.c   | 16 ++-
 .../gcc.target/arm/mve/intrinsics/vqsubq_u8.c | 16 ++-
 24 files changed, 516 insertions(+), 72 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c
index abcff4f0e3c..39b8089919d 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s16.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s16  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
 foo (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
 {
   return vqsubq_m_n_s16 (inactive, a, b, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqsubt.s16  q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
 foo1 (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
 {
   return vqsubq_m (inactive, a, b, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqsubt.s16"  }  } */
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c
index 23e59ff12a2..ed6b92ddcf5 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqsubq_m_n_s32.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "a

[PATCH 29/35] arm: improve tests for vqdmul*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c: Improve tests.
* gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulhq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulhq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulhq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulhq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulhq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulhq_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulhq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulhq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulhq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmullbq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmullbq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmullbq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmullbq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmullbq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmullbq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmullbq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulltq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulltq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulltq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulltq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulltq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulltq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vqdmulltq_s32.c: Likewise.
---
 .../arm/mve/intrinsics/vqdmulhq_m_n_s16.c | 26 ---
 .../arm/mve/intrinsics/vqdmulhq_m_n_s32.c | 26 ---
 .../arm/mve/intrinsics/vqdmulhq_m_n_s8.c  | 26 ---
 .../arm/mve/intrinsics/vqdmulhq_m_s16.c   | 26 ---
 .../arm/mve/intrinsics/vqdmulhq_m_s32.c   | 26 ---
 .../arm/mve/intrinsics/vqdmulhq_m_s8.c| 26 ---
 .../arm/mve/intrinsics/vqdmulhq_n_s16.c   | 16 ++--
 .../arm/mve/intrinsics/vqdmulhq_n_s32.c   | 16 ++--
 .../arm/mve/intrinsics/vqdmulhq_n_s8.c| 16 ++--
 .../arm/mve/intrinsics/vqdmulhq_s16.c | 16 ++--
 .../arm/mve/intrinsics/vqdmulhq_s32.c | 16 ++--
 .../arm/mve/intrinsics/vqdmulhq_s8.c  | 16 ++--
 .../arm/mve/intrinsics/vqdmullbq_m_n_s16.c| 26 ---
 .../arm/mve/intrinsics/vqdmullbq_m_n_s32.c| 26 ---
 .../arm/mve/intrinsics/vqdmullbq_m_s16.c  | 26 ---
 .../arm/mve/intrinsics/vqdmullbq_m_s32.c  | 26 ---
 .../arm/mve/intrinsics/vqdmullbq_n_s16.c  | 16 ++--
 .../arm/mve/intrinsics/vqdmullbq_n_s32.c  | 16 ++--
 .../arm/mve/intrinsics/vqdmullbq_s16.c| 16 ++--
 .../arm/mve/intrinsics/vqdmullbq_s32.c| 16 ++--
 .../arm/mve/intrinsics/vqdmulltq_m_n_s16.c| 26 ---
 .../arm/mve/intrinsics/vqdmulltq_m_n_s32.c| 26 ---
 .../arm/mve/intrinsics/vqdmulltq_m_s16.c  | 26 ---
 .../arm/mve/intrinsics/vqdmulltq_m_s32.c  | 26 ---
 .../arm/mve/intrinsics/vqdmulltq_n_s16.c  | 16 ++--
 .../arm/mve/intrinsics/vqdmulltq_n_s32.c  | 16 ++--
 .../arm/mve/intrinsics/vqdmulltq_s16.c| 16 ++--
 .../arm/mve/intrinsics/vqdmulltq_s32.c| 16 ++--
 28 files changed, 504 insertions(+), 84 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c
index 57ab85eaf52..a5c1a106205 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vqdmulhq_m_n_s16.c
@@ -1,23 +1,41 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|)
+** ...
+** vpst(?: @.*|)
+** ...
+** vqdmulht.s16q[0-9]+, q[0-9]+, (?:ip|fp|r[0-9]+)(?:  @.*|)
+** ...
+*/
 int16x8_t
 foo (int16x8_t inactive, int16x8_t a, int16_t b, mve_pred16_t p)
 {
   return vqdmulhq_m_n_s16 (inactive, a, b, p);
 }
 
-/* { dg-final { scan-assembler "vpst" } } */
-/* { dg-final { scan-assembler "vqdmulht.s16"  }  } */
 
+/*
+**foo1:
+** ...
+** vmsrp0, (?:ip|fp|r[0-9]+)(?:@.*|

[PATCH 09/35] arm: improve tests for vmax*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vmaxaq_m_s16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vmaxaq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxaq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxaq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxaq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxaq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxavq_p_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxavq_p_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxavq_p_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxavq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxavq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxavq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmaq_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmaq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmaq_m_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmavq_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmavq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmavq_p_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmq_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmq_m_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmq_m_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmq_x_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmq_x_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmvq_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmvq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxnmvq_p_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_m_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_m_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_m_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_x_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_x_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_x_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_x_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_x_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxq_x_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_p_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_p_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_p_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_p_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_p_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_p_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vmaxvq_u8.c: Likewise.
---
 .../arm/mve/intrinsics/vmaxaq_m_s16.c | 25 +--
 .../arm/mve/intrinsics/vmaxaq_m_s32.c | 25 +--
 .../arm/mve/intrinsics/vmaxaq_m_s8.c  | 25 +--
 .../arm/mve/intrinsics/vmaxaq_s16.c   | 16 +++-
 .../arm/mve/intrinsics/vmaxaq_s32.c   | 16 +++-
 .../gcc.target/arm/mve/intrinsics/vmaxaq_s8.c | 16 +++-
 .../arm/mve/intrinsics/vmaxavq_p_s16.c| 41 ---
 .../arm/mve/intrinsics/vmaxavq_p_s32.c| 41 ---
 .../arm/mve/intrinsics/vmaxavq_p_s8.c | 41 ---
 .../arm/mve/intrinsics/vmaxavq_s16.c  | 29 ++---
 .../arm/mve/intrinsics/vmaxavq_s32.c  | 29 ++---
 .../arm/mve/intrinsics/vmaxavq_s8.c   | 29 ++---
 .../arm/mve/intrinsics/vmaxnmaq_f16.c | 16 +++-
 .../arm/mve/intrinsics/vmaxnmaq_f32.c | 16 +++-
 .../arm/mve/intrinsics/vmaxnmaq_m_f16.c   | 25 +--
 .../arm/mve/intrinsics/vmaxnmaq_m_f32.c   | 25 +--
 .../arm/m

[PATCH 17/35] arm: improve tests and fix vadd*

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/ChangeLog:

* config/arm/mve.md (mve_vaddlvq_p_v4si)
(mve_vaddq_n_, mve_vaddvaq_)
(mve_vaddlvaq_v4si, mve_vaddq_n_f)
(mve_vaddlvaq_p_v4si, mve_vaddq, mve_vaddq_f):
Fix spacing.

gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vaddlvaq_p_s32.c: Improve test.
* gcc.target/arm/mve/intrinsics/vaddlvaq_p_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddlvaq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddlvaq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddlvq_p_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddlvq_p_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddlvq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddlvq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_m_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_n_f16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_n_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_n_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_n_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_n_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_n_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_n_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_n_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddq_x_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_p_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_p_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_p_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_p_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_p_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_p_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvaq_u8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvq_p_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvq_p_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvq_p_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vaddvq_p_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/

Re: [PATCH] [range-ops] Implement sqrt.

2022-11-17 Thread Aldy Hernandez via Gcc-patches
To go along with whatever magic we're gonna tack along to the
range-ops sqrt implementation, here is another revision addressing the
VARYING issue you pointed out.

A few things...

Instead of going through trees, I decided to call do_mpfr_arg1
directly.  Let's not go the wide int <-> tree rat hole in this one.

The function do_mpfr_arg1 bails on +INF, so I had to handle it manually.

There's a regression in gfortran.dg/ieee/ieee_6.f90, which I'm not
sure how to handle.  We are failing because we are calculating
sqrt(-1) and expecting certain IEEE flags set.  These flags aren't
set, presumably because we folded sqrt(-1) into a NAN directly:

// All negatives.
if (real_compare (LT_EXPR, &lh_ub, &dconst0))
  {
real_nan (&lb, "", 0, TYPE_MODE (type));
ub = lb;
maybe_nan = true;
return;
  }

The failing part of the test is:

  if (.not. (all(flags .eqv. [.false.,.false.,.true.,.true.,.false.]) &
 .or. all(flags .eqv. [.false.,.false.,.true.,.true.,.true.]) &
 .or. all(flags .eqv. [.false.,.false.,.true.,.false.,.false.]) &
 .or. all(flags .eqv.
[.false.,.false.,.true.,.false.,.true.]))) STOP 5

But we are generating F F F F F.  Google has informed me that that 3rd
flag is IEEE_INVALID.

So... is the optimization wrong?  Are we not allowed to substitute
that NAN if we know it's gonna happen?  Should we also allow F F F F F
in the test?  Or something else?

Thanks.
Aldy

On Wed, Nov 16, 2022 at 9:33 PM Jakub Jelinek  wrote:
>
> On Mon, Nov 14, 2022 at 09:55:29PM +, Joseph Myers wrote:
> > On Sun, 13 Nov 2022, Jakub Jelinek via Gcc-patches wrote:
> >
> > > So, I wonder if we don't need to add a target hook where targets will be
> > > able to provide upper bound on error for floating point functions for
> > > different floating point modes and some way to signal unknown 
> > > accuracy/can't
> > > be trusted, in which case we would give up or return just the range for
> > > VARYING.
> >
> > Note that the figures given in the glibc manual are purely empirical
> > (largest errors observed for inputs in the glibc testsuite on a system
> > that was then used to update the libm-test-ulps files); they don't
> > constitute any kind of guarantee about either the current implementation
> > or the API, nor are they formally verified, nor do they come from
> > exhaustive testing (though worst cases from exhaustive testing for float
> > may have been added to the glibc testsuite in some cases).  (I think the
> > only functions known to give huge errors for some inputs, outside of any
> > IBM long double issues, are the Bessel functions and cpow functions.  But
> > even if other functions don't have huge errors, and some
> > architecture-specific implementations might have issues, there are
> > certainly some cases where errors can exceed the 9ulp threshold on what
> > the libm tests will accept in libm-test-ulps files, which are thus
> > considered glibc bugs.  (That's 9ulp from the correctly rounded value,
> > computed in ulp of that value.  For IBM long double it's 16ulp instead,
> > treating the format as having a fixed 106 bits of precision.  Both figures
> > are empirical ones chosen based on what bounds sufficed for most libm
> > functions some years ago; ideally, with better implementations of some
> > functions we could probably bring those numbers down.))
>
> I know I can't get guarantees without formal proofs and even ulps from
> reported errors are better than randomized testing.
> But I think at least for non-glibc we want to be able to get a rough idea
> of the usual error range in ulps.
>
> This is what I came up with so far (link with
> gcc -o ulp-tester{,.c} -O2 -lmpfr -lm
> ), it still doesn't verify that functions are always within the mathematical
> range of results ([-0.0, Inf] for sqrt, [-1.0, 1.0] for sin/cos etc.), guess
> that would be useful and verify the program actually does what is intended.
> One can supply just one argument (number of tests, first 46 aren't really
> random) or two, in the latter case the second should be upward, downward or
> towardzero to use non-default rounding mode.
> The idea is that we'd collect ballpark estimates for roundtonearest and
> then estimates for the other 3 rounding modes, the former would be used
> without -frounding-math, max over all 4 rounding modes for -frounding-math
> as gcc will compute using mpfr always in round to nearest.
>
> Jakub
From 759bcd4b4b6f70fcec045b24fb6874aaca989549 Mon Sep 17 00:00:00 2001
From: Aldy Hernandez 
Date: Sun, 13 Nov 2022 18:39:59 +0100
Subject: [PATCH] [range-ops] Implement sqrt.

gcc/ChangeLog:

	* fold-const-call.cc (do_mpfr_arg1): Remove static.
	* gimple-range-op.cc (class cfn_sqrt): New.
	(gimple_range_op_handler::maybe_builtin_call): Add sqrt case.
	* realmpfr.h (do_mpfr_arg1): Add extern.

gcc/testsuite/ChangeLog:

	* gcc.dg/tree-ssa/vrp124.c: New test.
---
 gcc/fold-const-call.cc |  2 +-
 gcc/gimple-range-op.cc 

Re: [PATCH] RISC-V: Handle "(a & twobits) == singlebit" in branches using Zbs

2022-11-17 Thread Jeff Law via Gcc-patches



On 11/17/22 08:12, Philipp Tomsich wrote:


This serves as an assertion only, as that case is non-sensical and
will be optimized away by earlier passes (as "a & C == T" with C and T
sharing no bits will always be false).
IFAIK the preceding transforms should always clean such a check up,
but we can't exclude the possibility that with enough command line
overrides and params we might see such a non-sensical test making it
all the way to the backend.


Good!  I was thinking in the back of my mind that the no-sharing-bits 
case should have been handled in the generic optimizers.  Thanks for 
clarifying.





What would you recommend? Adding this to the pattern's condition feels
a bit redundant.


We can leave it in the splitter.



In fact, I am leaning towards hiding the !SMALL_OPERAND check in yet
another predicate that combines const_twobits_operand with a
match_test for !SMALL_OPERAND.


Sure.

jeff




[PATCH 01/35] arm: improve vcreateq* tests

2022-11-17 Thread Andrea Corallo via Gcc-patches
gcc/testsuite/ChangeLog:

* gcc.target/arm/mve/intrinsics/vcreateq_f16.c: Improve test.
* gcc.target/arm/mve/intrinsics/vcreateq_f32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcreateq_s16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcreateq_s32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcreateq_s64.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcreateq_s8.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcreateq_u16.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcreateq_u32.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcreateq_u64.c: Likewise.
* gcc.target/arm/mve/intrinsics/vcreateq_u8.c: Likewise.
---
 .../arm/mve/intrinsics/vcreateq_f16.c | 23 ++-
 .../arm/mve/intrinsics/vcreateq_f32.c | 23 ++-
 .../arm/mve/intrinsics/vcreateq_s16.c | 23 ++-
 .../arm/mve/intrinsics/vcreateq_s32.c | 23 ++-
 .../arm/mve/intrinsics/vcreateq_s64.c | 23 ++-
 .../arm/mve/intrinsics/vcreateq_s8.c  | 23 ++-
 .../arm/mve/intrinsics/vcreateq_u16.c | 23 ++-
 .../arm/mve/intrinsics/vcreateq_u32.c | 23 ++-
 .../arm/mve/intrinsics/vcreateq_u64.c | 23 ++-
 .../arm/mve/intrinsics/vcreateq_u8.c  | 23 ++-
 10 files changed, 220 insertions(+), 10 deletions(-)

diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f16.c
index fb3601edb94..c39303daa03 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f16.c
@@ -1,13 +1,34 @@
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /* { dg-add-options arm_v8_1m_mve_fp } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
 float16x8_t
 foo (uint64_t a, uint64_t b)
 {
   return vcreateq_f16 (a, b);
 }
 
-/* { dg-final { scan-assembler "vmov"  }  } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+float16x8_t
+foo1 ()
+{
+  return vcreateq_f16 (1, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f32.c
index 4f4da62eed7..ad66f4407cd 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f32.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_f32.c
@@ -1,13 +1,34 @@
 /* { dg-require-effective-target arm_v8_1m_mve_fp_ok } */
 /* { dg-add-options arm_v8_1m_mve_fp } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
 float32x4_t
 foo (uint64_t a, uint64_t b)
 {
   return vcreateq_f32 (a, b);
 }
 
-/* { dg-final { scan-assembler "vmov"  }  } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+float32x4_t
+foo1 ()
+{
+  return vcreateq_f32 (1, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s16.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s16.c
index 103be6310bd..7e70a486513 100644
--- a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s16.c
+++ b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s16.c
@@ -1,13 +1,34 @@
 /* { dg-require-effective-target arm_v8_1m_mve_ok } */
 /* { dg-add-options arm_v8_1m_mve } */
 /* { dg-additional-options "-O2" } */
+/* { dg-final { check-function-bodies "**" "" } } */
 
 #include "arm_mve.h"
 
+/*
+**foo:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
 int16x8_t
 foo (uint64_t a, uint64_t b)
 {
   return vcreateq_s16 (a, b);
 }
 
-/* { dg-final { scan-assembler "vmov"  }  } */
+/*
+**foo1:
+** ...
+** vmov q[0-9+]\[2\], q[0-9+]\[0\], r[0-9+], r[0-9+]
+** vmov q[0-9+]\[3\], q[0-9+]\[1\], r[0-9+], r[0-9+]
+** ...
+*/
+int16x8_t
+foo1 ()
+{
+  return vcreateq_s16 (1, 1);
+}
+
+/* { dg-final { scan-assembler-not "__ARM_undef" } } */
\ No newline at end of file
diff --git a/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s32.c 
b/gcc/testsuite/gcc.target/arm/mve/intrinsics/vcreateq_s32.c
index 96f7a972d93.

PING^2 [PATCH] testsuite: Windows paths use \ and not /

2022-11-17 Thread Torbjorn SVENSSON via Gcc-patches

Hi,

Ping, https://gcc.gnu.org/pipermail/gcc-patches/2022-November/604896.html

Ok for trunk?

Kind regards,
Torbjörn

On 2022-11-02 19:16, Torbjorn SVENSSON wrote:

Hi,

Ping, https://gcc.gnu.org/pipermail/gcc-patches/2022-October/604312.html

Ok for trunk?

Kind regards,
Torbjörn

On 2022-10-25 17:15, Torbjörn SVENSSON wrote:

Without this patch, the following error is reported on Windows:

In file included from 
t:\build\arm-none-eabi\include\c++\11.3.1\string:54,
   from 
t:\build\arm-none-eabi\include\c++\11.3.1\bits\locale_classes.h:40,
   from 
t:\build\arm-none-eabi\include\c++\11.3.1\bits\ios_base.h:41,

   from t:\build\arm-none-eabi\include\c++\11.3.1\ios:42,
   from 
t:\build\arm-none-eabi\include\c++\11.3.1\ostream:38,
   from 
t:\build\arm-none-eabi\include\c++\11.3.1\iostream:39:
t:\build\arm-none-eabi\include\c++\11.3.1\bits\range_access.h:36:10: 
note: include 
't:\build\arm-none-eabi\include\c++\11.3.1\initializer_list' 
translated to import
arm-none-eabi-g++.exe: warning: 
.../gcc/testsuite/g++.dg/modules/pr99023_b.X: linker input file unused 
because linking not done
FAIL: g++.dg/modules/pr99023_b.X -std=c++2a  dg-regexp 6 not found: 
"[^\n]*: note: include '[^\n]*/initializer_list' translated to import\n"


gcc/testsuite/ChangeLog:

* g++.dg/modules/pr99023_b.X: Match Windows paths too.

Co-Authored-By: Yvan ROUX 
Signed-off-by: Torbjörn SVENSSON 
---
  gcc/testsuite/g++.dg/modules/pr99023_b.X | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/g++.dg/modules/pr99023_b.X 
b/gcc/testsuite/g++.dg/modules/pr99023_b.X

index 3d82f34868b..ca5f32e5bcc 100644
--- a/gcc/testsuite/g++.dg/modules/pr99023_b.X
+++ b/gcc/testsuite/g++.dg/modules/pr99023_b.X
@@ -3,5 +3,5 @@
  // { dg-prune-output {linker input file unused} }
-// { dg-regexp {[^\n]*: note: include '[^\n]*/initializer_list' 
translated to import\n} }
+// { dg-regexp {[^\n]*: note: include '[^\n]*[/\\]initializer_list' 
translated to import\n} }

  NO DO NOT COMPILE


Re: [PATCH] AArch64: Add support for -mdirect-extern-access

2022-11-17 Thread Wilco Dijkstra via Gcc-patches
Hi Richard,

> Can you go into more detail about:
>
>    Use :option:`-mdirect-extern-access` either in shared libraries or in
>    executables, but not in both.  Protected symbols used both in a shared
>    library and executable may cause linker errors or fail to work correctly
>
> If this is LLVM's default for PIC (and by assumption shared libraries),
> is it then invalid to use -mdirect-extern-access for any PIEs that
> are linked against those shared libraries and use protected symbols
> from those libraries?  How would a user know that one of the shared
> libraries they're linking against was built in this way?

Yes, the usage model is that you'd either use it for static PIE or only on
data that is not shared. If you get it wrong them you'll get the copy
relocation error. In the future we need to decide what the ABI is and
ensure GCC and LLVM are compatible. An import feature to mark symbols
that may be overridden by a shared library would be useful too.

> It looks like the main difference between this implementation and
> the x86 one is that x86 allows direct accesses to common symbols.
> What's the reason for not doing that for AArch64?  Does it not work,
> is it a false optimisation (i.e. pessimisation), or did it not seem
> important now that -fno-common is the default?

I don't see any difference in the way common symbols are accessed on x86,
so it's not clear which cases common_local_p param actually affects (eg. with
-fPIC there is always a GOT indirection for common symbols).

Cheers,
Wilco

PING^2 [PATCH] cpp/remap: Only override if string matched

2022-11-17 Thread Torbjorn SVENSSON via Gcc-patches

Hi,

Ping, https://gcc.gnu.org/pipermail/gcc-patches/2022-November/604898.html

Ok for trunk?

Kind regards,
Torbjörn

On 2022-11-02 19:21, Torbjorn SVENSSON wrote:

Hi,

Ping, https://gcc.gnu.org/pipermail/gcc-patches/2022-October/604062.html

Ok for trunk?

Kind regards,
Torbjörn

On 2022-10-20 22:48, Torbjörn SVENSSON wrote:

For systems with HAVE_DOS_BASED_FILE_SYSTEM set, only override the
pointer if the backslash pattern matches.

Output without this patch:
.../gcc/testsuite/gcc.dg/cpp/pr71681-2.c:5:10: fatal error: a/t2.h: No 
such file or directory


With patch applied, no output and the test case succeeds.

libcpp/ChangeLog

* files.cc: Ensure pattern matches before use.

Signed-off-by: Torbjörn SVENSSON 
---
  libcpp/files.cc | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcpp/files.cc b/libcpp/files.cc
index 24208f7b0f8..a18b1caf48d 100644
--- a/libcpp/files.cc
+++ b/libcpp/files.cc
@@ -1833,7 +1833,7 @@ remap_filename (cpp_reader *pfile, _cpp_file *file)
  #ifdef HAVE_DOS_BASED_FILE_SYSTEM
    {
  const char *p2 = strchr (fname, '\\');
-    if (!p || (p > p2))
+    if (!p || (p2 && p > p2))
    p = p2;
    }
  #endif


[PATCH 15/35] arm: Explicitly specify other float types for _Generic overloading [PR107515]

2022-11-17 Thread Andrea Corallo via Gcc-patches
From: Stam Markianos-Wright 

This patch adds explicit references to other float types
to __ARM_mve_typeid in arm_mve.h.  Resolves PR 107515:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107515

gcc/ChangeLog:
PR 107515
* config/arm/arm_mve.h (__ARM_mve_typeid): Add float types.
---
 gcc/config/arm/arm_mve.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h
index fd1876b57a0..f6b42dc3fab 100644
--- a/gcc/config/arm/arm_mve.h
+++ b/gcc/config/arm/arm_mve.h
@@ -35582,6 +35582,9 @@ enum {
short: __ARM_mve_type_int_n, \
int: __ARM_mve_type_int_n, \
long: __ARM_mve_type_int_n, \
+   _Float16: __ARM_mve_type_fp_n, \
+   __fp16: __ARM_mve_type_fp_n, \
+   float: __ARM_mve_type_fp_n, \
double: __ARM_mve_type_fp_n, \
long long: __ARM_mve_type_int_n, \
unsigned char: __ARM_mve_type_int_n, \
-- 
2.25.1



Re: [PATCH] RISC-V: Handle "(a & twobits) == singlebit" in branches using Zbs

2022-11-17 Thread Philipp Tomsich
On Thu, 17 Nov 2022 at 17:39, Jeff Law  wrote:
>
>
> On 11/17/22 08:12, Philipp Tomsich wrote:
> >
> > This serves as an assertion only, as that case is non-sensical and
> > will be optimized away by earlier passes (as "a & C == T" with C and T
> > sharing no bits will always be false).
> > IFAIK the preceding transforms should always clean such a check up,
> > but we can't exclude the possibility that with enough command line
> > overrides and params we might see such a non-sensical test making it
> > all the way to the backend.
>
> Good!  I was thinking in the back of my mind that the no-sharing-bits
> case should have been handled in the generic optimizers.  Thanks for
> clarifying.
>
>
> >
> > What would you recommend? Adding this to the pattern's condition feels
> > a bit redundant.
>
> We can leave it in the splitter.
>
>
> > In fact, I am leaning towards hiding the !SMALL_OPERAND check in yet
> > another predicate that combines const_twobits_operand with a
> > match_test for !SMALL_OPERAND.

I'll send a v2 with this cleaned up (and look into clarifying things
around the FAIL).

Philipp.


[PATCH 13/35] arm: further fix overloading of MVE vaddq[_m]_n intrinsic

2022-11-17 Thread Andrea Corallo via Gcc-patches
From: Stam Markianos-Wright 

It was observed that in tests `vaddq_m_n_[s/u][8/16/32].c`, the _Generic
resolution would fall back to the `__ARM_undef` failure state.

This is a regression since `dc39db873670bea8d8e655444387ceaa53a01a79` and
`6bd4ce64eb48a72eca300cb52773e6101d646004`, but it previously wasn't
identified, because the tests were not checking for this kind of failure.

The above commits changed the definitions of the intrinsics from using
`[u]int[8/16/32]_t` types for the scalar argument to using `int`. This
allowed `int` to be supported in user code through the overloaded
`#defines`, but seems to have broken the `[u]int[8/16/32]_t` types

The solution implemented by this patch is to explicitly use a new
_Generic mapping from all the `[u]int[8/16/32]_t` types for int. With this
change, both `int` and `[u]int[8/16/32]_t` parameters are supported from
user code and are handled by the overloading mechanism correctly.

gcc/ChangeLog:

* config/arm/arm_mve.h (__arm_vaddq_m_n_s8): Change types.
(__arm_vaddq_m_n_s32): Likewise.
(__arm_vaddq_m_n_s16): Likewise.
(__arm_vaddq_m_n_u8): Likewise.
(__arm_vaddq_m_n_u32): Likewise.
(__arm_vaddq_m_n_u16): Likewise.
(__arm_vaddq_m): Fix Overloading.
(__ARM_mve_coerce3): New.
---
 gcc/config/arm/arm_mve.h | 78 
 1 file changed, 40 insertions(+), 38 deletions(-)

diff --git a/gcc/config/arm/arm_mve.h b/gcc/config/arm/arm_mve.h
index 684f997520f..951dc25374b 100644
--- a/gcc/config/arm/arm_mve.h
+++ b/gcc/config/arm/arm_mve.h
@@ -9675,42 +9675,42 @@ __arm_vabdq_m_u16 (uint16x8_t __inactive, uint16x8_t 
__a, uint16x8_t __b, mve_pr
 
 __extension__ extern __inline int8x16_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_s8 (int8x16_t __inactive, int8x16_t __a, int __b, mve_pred16_t 
__p)
+__arm_vaddq_m_n_s8 (int8x16_t __inactive, int8x16_t __a, int8_t __b, 
mve_pred16_t __p)
 {
   return __builtin_mve_vaddq_m_n_sv16qi (__inactive, __a, __b, __p);
 }
 
 __extension__ extern __inline int32x4_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_s32 (int32x4_t __inactive, int32x4_t __a, int __b, 
mve_pred16_t __p)
+__arm_vaddq_m_n_s32 (int32x4_t __inactive, int32x4_t __a, int32_t __b, 
mve_pred16_t __p)
 {
   return __builtin_mve_vaddq_m_n_sv4si (__inactive, __a, __b, __p);
 }
 
 __extension__ extern __inline int16x8_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_s16 (int16x8_t __inactive, int16x8_t __a, int __b, 
mve_pred16_t __p)
+__arm_vaddq_m_n_s16 (int16x8_t __inactive, int16x8_t __a, int16_t __b, 
mve_pred16_t __p)
 {
   return __builtin_mve_vaddq_m_n_sv8hi (__inactive, __a, __b, __p);
 }
 
 __extension__ extern __inline uint8x16_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_u8 (uint8x16_t __inactive, uint8x16_t __a, int __b, 
mve_pred16_t __p)
+__arm_vaddq_m_n_u8 (uint8x16_t __inactive, uint8x16_t __a, uint8_t __b, 
mve_pred16_t __p)
 {
   return __builtin_mve_vaddq_m_n_uv16qi (__inactive, __a, __b, __p);
 }
 
 __extension__ extern __inline uint32x4_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_u32 (uint32x4_t __inactive, uint32x4_t __a, int __b, 
mve_pred16_t __p)
+__arm_vaddq_m_n_u32 (uint32x4_t __inactive, uint32x4_t __a, uint32_t __b, 
mve_pred16_t __p)
 {
   return __builtin_mve_vaddq_m_n_uv4si (__inactive, __a, __b, __p);
 }
 
 __extension__ extern __inline uint16x8_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m_n_u16 (uint16x8_t __inactive, uint16x8_t __a, int __b, 
mve_pred16_t __p)
+__arm_vaddq_m_n_u16 (uint16x8_t __inactive, uint16x8_t __a, uint16_t __b, 
mve_pred16_t __p)
 {
   return __builtin_mve_vaddq_m_n_uv8hi (__inactive, __a, __b, __p);
 }
@@ -26417,42 +26417,42 @@ __arm_vabdq_m (uint16x8_t __inactive, uint16x8_t __a, 
uint16x8_t __b, mve_pred16
 
 __extension__ extern __inline int8x16_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m (int8x16_t __inactive, int8x16_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m (int8x16_t __inactive, int8x16_t __a, int8_t __b, mve_pred16_t 
__p)
 {
  return __arm_vaddq_m_n_s8 (__inactive, __a, __b, __p);
 }
 
 __extension__ extern __inline int32x4_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m (int32x4_t __inactive, int32x4_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m (int32x4_t __inactive, int32x4_t __a, int32_t __b, mve_pred16_t 
__p)
 {
  return __arm_vaddq_m_n_s32 (__inactive, __a, __b, __p);
 }
 
 __extension__ extern __inline int16x8_t
 __attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
-__arm_vaddq_m (int16x8_t __inactive, int16x8_t __a, int __b, mve_pred16_t __p)
+__arm_vaddq_m (int16x8_t __inactive, int16x8_t __a, int16_t __b, mve_pred16_t 
__p)
 {
  return __arm_vaddq_m_

PING^5 [PATCH] testsuite: Verify that module-mapper is available

2022-11-17 Thread Torbjorn SVENSSON via Gcc-patches

Hi,

Ping, https://gcc.gnu.org/pipermail/gcc-patches/2022-November/604895.html

Ok for trunk?

Kind regards,
Torbjörn

On 2022-11-02 19:13, Torbjorn SVENSSON wrote:

Hi,

Ping, https://gcc.gnu.org/pipermail/gcc-patches/2022-October/602844.html

Ok for trunk?

Kind regards,
Torbjörn

On 2022-10-25 16:24, Torbjorn SVENSSON via Gcc-patches wrote:

Hi,

Ping, https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603544.html

Kind regards,
Torbjörn

On 2022-10-14 09:42, Torbjorn SVENSSON wrote:

Hi,

Ping, https://gcc.gnu.org/pipermail/gcc-patches/2022-October/602843.html

Kind regards,
Torbjörn

On 2022-10-05 11:17, Torbjorn SVENSSON wrote:

Hi,

Ping, 
https://gcc.gnu.org/pipermail/gcc-patches/2022-September/602111.html


Kind regards,
Torbjörn

On 2022-09-23 14:03, Torbjörn SVENSSON wrote:

For some test cases, it's required that the optional module mapper
"g++-mapper-server" is built. As the server is not required, the
test cases will fail if it can't be found.

gcc/testsuite/ChangeLog:

* lib/target-supports.exp (check_is_prog_name_available):
New.
* lib/target-supports-dg.exp
(dg-require-prog-name-available): New.
* g++.dg/modules/modules.exp: Verify avilability of module
mapper.

Signed-off-by: Torbjörn SVENSSON  
---
  gcc/testsuite/g++.dg/modules/modules.exp | 31 


  gcc/testsuite/lib/target-supports-dg.exp | 15 
  gcc/testsuite/lib/target-supports.exp    | 15 
  3 files changed, 61 insertions(+)

diff --git a/gcc/testsuite/g++.dg/modules/modules.exp 
b/gcc/testsuite/g++.dg/modules/modules.exp

index afb323d0efd..4784803742a 100644
--- a/gcc/testsuite/g++.dg/modules/modules.exp
+++ b/gcc/testsuite/g++.dg/modules/modules.exp
@@ -279,6 +279,29 @@ proc module-init { src } {
  return $option_list
  }
+# Return 1 if requirements are met
+proc module-check-requirements { tests } {
+    foreach test $tests {
+    set tmp [dg-get-options $test]
+    foreach op $tmp {
+    switch [lindex $op 0] {
+    "dg-additional-options" {
+    # Example strings to match:
+    # -fmodules-ts -fmodule-mapper=|@g++-mapper-server\\ 
-t\\ [srcdir]/inc-xlate-1.map

+    # -fmodules-ts -fmodule-mapper=|@g++-mapper-server
+    if [regexp -- {(^| )-fmodule-mapper=\|@([^\\ ]*)} 
[lindex $op 2] dummy dummy2 prog] {

+    verbose "Checking that mapper exist: $prog"
+    if { ![ check_is_prog_name_available $prog ] } {
+    return 0
+    }
+    }
+    }
+    }
+    }
+    }
+    return 1
+}
+
  # cleanup any detritus from previous run
  cleanup_module_files [find $DEFAULT_REPO *.gcm]
@@ -307,6 +330,14 @@ foreach src [lsort [find $srcdir/$subdir 
{*_a.[CHX}]] {

  set tests [lsort [find [file dirname $src] \
    [regsub {_a.[CHX]$} [file tail $src] 
{_[a-z].[CHX]}]]]

+    if { ![module-check-requirements $tests] } {
+    set testcase [regsub {_a.[CH]} $src {}]
+    set testcase \
+    [string range $testcase [string length "$srcdir/"] end]
+    unsupported $testcase
+    continue
+    }
+
  set std_list [module-init $src]
  foreach std $std_list {
  set mod_files {}
diff --git a/gcc/testsuite/lib/target-supports-dg.exp 
b/gcc/testsuite/lib/target-supports-dg.exp

index aa2164bc789..6ce3b2b1a1b 100644
--- a/gcc/testsuite/lib/target-supports-dg.exp
+++ b/gcc/testsuite/lib/target-supports-dg.exp
@@ -683,3 +683,18 @@ proc dg-require-symver { args } {
  set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
  }
  }
+
+# If this target does not provide prog named "$args", skip this test.
+
+proc dg-require-prog-name-available { args } {
+    # The args are within another list; pull them out.
+    set args [lindex $args 0]
+
+    set prog [lindex $args 1]
+
+    if { ![ check_is_prog_name_available $prog ] } {
+    upvar dg-do-what dg-do-what
+    set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
+    }
+}
+
diff --git a/gcc/testsuite/lib/target-supports.exp 
b/gcc/testsuite/lib/target-supports.exp

index 703aba412a6..c3b7a6c17b3 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -11928,3 +11928,18 @@ main:
  .byte 0
    } ""]
  }
+
+# Return 1 if this target has prog named "$prog", 0 otherwise.
+
+proc check_is_prog_name_available { prog } {
+    global tool
+
+    set options [list "additional_flags=-print-prog-name=$prog"]
+    set output [lindex [${tool}_target_compile "" "" "none" 
$options] 0]

+
+    if { $output == $prog } {
+    return 0
+    }
+
+    return 1
+}


Re: [PATCH] [range-ops] Implement sqrt.

2022-11-17 Thread Aldy Hernandez via Gcc-patches




On 11/17/22 17:40, Aldy Hernandez wrote:

To go along with whatever magic we're gonna tack along to the
range-ops sqrt implementation, here is another revision addressing the
VARYING issue you pointed out.

A few things...

Instead of going through trees, I decided to call do_mpfr_arg1
directly.  Let's not go the wide int <-> tree rat hole in this one.

The function do_mpfr_arg1 bails on +INF, so I had to handle it manually.

There's a regression in gfortran.dg/ieee/ieee_6.f90, which I'm not
sure how to handle.  We are failing because we are calculating
sqrt(-1) and expecting certain IEEE flags set.  These flags aren't
set, presumably because we folded sqrt(-1) into a NAN directly:

 // All negatives.
 if (real_compare (LT_EXPR, &lh_ub, &dconst0))
   {
 real_nan (&lb, "", 0, TYPE_MODE (type));
 ub = lb;
 maybe_nan = true;
 return;
   }


FWIW, we could return [-0.0, +INF] +-NAN which would keep us from 
eliding the sqrt, but it'd be a pity to keep the sqrt unless it's 
mandated by some IEEE canon.


Aldy



Re: [PATCH] AArch64: Add support for -mdirect-extern-access

2022-11-17 Thread Richard Sandiford via Gcc-patches
Wilco Dijkstra  writes:
> Hi Richard,
>
>> Can you go into more detail about:
>>
>>Use :option:`-mdirect-extern-access` either in shared libraries or in
>>executables, but not in both.  Protected symbols used both in a shared
>>library and executable may cause linker errors or fail to work correctly
>>
>> If this is LLVM's default for PIC (and by assumption shared libraries),
>> is it then invalid to use -mdirect-extern-access for any PIEs that
>> are linked against those shared libraries and use protected symbols
>> from those libraries?  How would a user know that one of the shared
>> libraries they're linking against was built in this way?
>
> Yes, the usage model is that you'd either use it for static PIE or only on
> data that is not shared. If you get it wrong them you'll get the copy
> relocation error.

Thanks.  I think I'm still missing something though.  If, for the
non-executable case, people should only use the feature on data that
is not shared, why do we need to relax the binds-local condition for
protected symbols on -fPIC?  Oughtn't the symbol to be hidden rather
than protected if the data isn't shared?

I can understand the reasoning for the PIE changes but I'm still
struggling with the PIC-but-not-PIE bits.

> In the future we need to decide what the ABI is and
> ensure GCC and LLVM are compatible. An import feature to mark symbols
> that may be overridden by a shared library would be useful too.
>
>> It looks like the main difference between this implementation and
>> the x86 one is that x86 allows direct accesses to common symbols.
>> What's the reason for not doing that for AArch64?  Does it not work,
>> is it a false optimisation (i.e. pessimisation), or did it not seem
>> important now that -fno-common is the default?
>
> I don't see any difference in the way common symbols are accessed on x86,
> so it's not clear which cases common_local_p param actually affects (eg. with
> -fPIC there is always a GOT indirection for common symbols).

Hmm, OK.  Could it be for one of the other languages?  But yeah,
if we don't have a testcase for it, I agree it's better to leave
things as they are.

Thanks,
Richard


Re: [PATCH] [range-ops] Implement sqrt.

2022-11-17 Thread Aldy Hernandez via Gcc-patches
This may be DCE.

DOM uses ranger through simplify_using_ranges::fold_cond() to fold the
following conditional to false, because we know x_185 is a NAN:

 x_185 = __builtin_sqrtf (-1.0e+0);
if (x_185 ord x_185)

I believe we can do that, because there are no user observable
effects.  But DCE removes the sqrt which could trap:

Eliminating unnecessary statements:
Deleting : x_185 = __builtin_sqrtf (-1.0e+0);

Is DCE allowed to remove that sqrtf call?

Thanks.
Aldy

On Thu, Nov 17, 2022 at 5:48 PM Aldy Hernandez  wrote:
>
>
>
> On 11/17/22 17:40, Aldy Hernandez wrote:
> > To go along with whatever magic we're gonna tack along to the
> > range-ops sqrt implementation, here is another revision addressing the
> > VARYING issue you pointed out.
> >
> > A few things...
> >
> > Instead of going through trees, I decided to call do_mpfr_arg1
> > directly.  Let's not go the wide int <-> tree rat hole in this one.
> >
> > The function do_mpfr_arg1 bails on +INF, so I had to handle it manually.
> >
> > There's a regression in gfortran.dg/ieee/ieee_6.f90, which I'm not
> > sure how to handle.  We are failing because we are calculating
> > sqrt(-1) and expecting certain IEEE flags set.  These flags aren't
> > set, presumably because we folded sqrt(-1) into a NAN directly:
> >
> >  // All negatives.
> >  if (real_compare (LT_EXPR, &lh_ub, &dconst0))
> >{
> >  real_nan (&lb, "", 0, TYPE_MODE (type));
> >  ub = lb;
> >  maybe_nan = true;
> >  return;
> >}
>
> FWIW, we could return [-0.0, +INF] +-NAN which would keep us from
> eliding the sqrt, but it'd be a pity to keep the sqrt unless it's
> mandated by some IEEE canon.
>
> Aldy



Re: [PATCH] maintainer-scripts/gcc_release: compress xz in parallel

2022-11-17 Thread Sam James via Gcc-patches


> On 8 Nov 2022, at 07:14, Sam James  wrote:
> 
> 1. This should speed up decompression for folks, as parallel xz
>   creates a different archive which can be decompressed in parallel.
> 
>   Note that this different method is enabled by default in a new
>   xz release coming shortly anyway (>= 5.3.3_alpha1).
> 
>   I build GCC regularly from the weekly snapshots
>   and so the decompression time adds up.
> 
> 2. It should speed up compression on the webserver a bit.
> 
>   Note that -T0 won't be the default in the new xz release,
>   only the parallel compression mode (which enables parallel
>   decompression).
> 
>   -T0 detects the number of cores available.
> 
>   So, if a different number of threads is preferred, it's fine
>   to set e.g. -T2, etc.
> 
> Signed-off-by: Sam James 
> ---
> maintainer-scripts/gcc_release | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/maintainer-scripts/gcc_release b/maintainer-scripts/gcc_release
> index 2456908d716..962b8efe99a 100755
> --- a/maintainer-scripts/gcc_release
> +++ b/maintainer-scripts/gcc_release
> @@ -609,7 +609,7 @@ FILE_LIST=""
> # Programs we use.
> 
> BZIP2="${BZIP2:-bzip2}"
> -XZ="${XZ:-xz --best}"
> +XZ="${XZ:-xz -T0 --best}"
> CVS="${CVS:-cvs -f -Q -z9}"
> DIFF="${DIFF:-diff -Nrcpad}"
> ENV="${ENV:-env}"
> --
> 2.38.1
> 

ping


signature.asc
Description: Message signed with OpenPGP


[COMMITTED] [PR tree-optimization/107732] [range-ops] Handle attempt to abs() negatives.

2022-11-17 Thread Aldy Hernandez via Gcc-patches
The threader is creating a scenario where we are trying to solve:

[NEGATIVES] = abs(x)

While solving this we have an intermediate value of UNDEFINED because
we have no positive numbers.  But then we try to union the negative
pair to the final result by querying the bounds.  Since neither
UNDEFINED nor NAN have bounds, they need to be specially handled.

PR tree-optimization/107732

gcc/ChangeLog:

* range-op-float.cc (foperator_abs::op1_range): Early exit when
result is undefined.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/pr107732.c: New test.
---
 gcc/range-op-float.cc|  2 +-
 gcc/testsuite/gcc.dg/tree-ssa/pr107732.c | 13 +
 2 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr107732.c

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index adb0cbaa6d5..ee88511eba0 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -1407,7 +1407,7 @@ foperator_abs::op1_range (frange &r, tree type,
   neg_nan.set_nan (type, true);
   r.union_ (neg_nan);
 }
-  if (r.known_isnan ())
+  if (r.known_isnan () || r.undefined_p ())
 return true;
   // Then add the negative of each pair:
   // ABS(op1) = [5,20] would yield op1 => [-20,-5][5,20].
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr107732.c 
b/gcc/testsuite/gcc.dg/tree-ssa/pr107732.c
new file mode 100644
index 000..b216f38db0e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr107732.c
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-O2" }
+
+double sqrt(double);
+double a, b, c;
+void d() {
+  for (;;) {
+c = __builtin_fabs(a);
+sqrt(c);
+if (a)
+  a = b;
+  }
+}
-- 
2.38.1



[COMMITTED] Fix PR 107734: valgrind errors with sbitmap in match.pd

2022-11-17 Thread apinski--- via Gcc-patches
From: Andrew Pinski 

sbitmap is a simple bitmap and the memory allocated is not cleared
on creation; you have to clear it or set it to all ones before using
it.  This is unlike bitmap which is a sparse bitmap and the entries are
cleared as created.
The code added in r13-4044-gdc95e1e9702f2f missed that.
This patch fixes that mistake.

Committed as obvious after a bootstrap and test on x86_64-linux-gnu.

gcc/ChangeLog:

PR middle-end/107734
* match.pd (perm + vector op pattern): Clear the sbitmap before
use.
---
 gcc/match.pd | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/gcc/match.pd b/gcc/match.pd
index 5aba1653b80..a4d1386fd9f 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -8288,6 +8288,8 @@ and,
   if (sel.encoding ().encoded_full_vector_p ())
 {
   auto_sbitmap seen (nelts);
+  bitmap_clear (seen);
+
   unsigned HOST_WIDE_INT count = 0, i;
 
   for (i = 0; i < nelts; i++)
-- 
2.17.1



Re: [PATCH] RISC-V: Handle "(a & twobits) == singlebit" in branches using Zbs

2022-11-17 Thread Andrew Pinski via Gcc-patches
On Sun, Nov 13, 2022 at 12:51 PM Philipp Tomsich
 wrote:
>
> Use Zbs when generating a sequence for "if ((a & twobits) == singlebit) ..."
> that can be expressed as bexti + bexti + andn.

Can't you also handle if ((a & twobits) == 0) case doing a similar thing.
That is:
two bexti + and and then compare against zero which is exactly the
same # of instructions as the above case.


>
> gcc/ChangeLog:
>
> * config/riscv/bitmanip.md 
> (*branch_mask_twobits_equals_singlebit):
> Handle "if ((a & T) == C)" using Zbs, when T has 2 bits set and C has 
> one
> of these tow bits set.
> * config/riscv/predicates.md (const_twobits_operand): New predicate.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/zbs-if_then_else-01.c: New test.
>
> Signed-off-by: Philipp Tomsich 
> ---
>
>  gcc/config/riscv/bitmanip.md  | 42 +++
>  gcc/config/riscv/predicates.md|  5 +++
>  .../gcc.target/riscv/zbs-if_then_else-01.c| 20 +
>  3 files changed, 67 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
>
> diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> index 7a8f4e35880..2cea394671f 100644
> --- a/gcc/config/riscv/bitmanip.md
> +++ b/gcc/config/riscv/bitmanip.md
> @@ -690,3 +690,45 @@
>"TARGET_ZBS"
>[(set (match_dup 0) (zero_extract:X (match_dup 1) (const_int 1) (match_dup 
> 2)))
> (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
> +
> +;; IF_THEN_ELSE: test for 2 bits of opposite polarity
> +(define_insn_and_split "*branch_mask_twobits_equals_singlebit"
> +  [(set (pc)
> +   (if_then_else (match_operator 1 "equality_operator"
> +  [(and:X (match_operand:X 2 "register_operand" "r")
> +  (match_operand:X 3 "const_twobits_operand" 
> "i"))
> +   (match_operand:X 4 "single_bit_mask_operand" "i")])
> +(label_ref (match_operand 0 "" ""))
> +(pc)))
> +   (clobber (match_scratch:X 5 "=&r"))
> +   (clobber (match_scratch:X 6 "=&r"))]
> +  "TARGET_ZBS && TARGET_ZBB && !SMALL_OPERAND (INTVAL (operands[3]))"
> +  "#"
> +  "&& reload_completed"
> +  [(set (match_dup 5) (zero_extract:X (match_dup 2)
> + (const_int 1)
> + (match_dup 8)))
> +   (set (match_dup 6) (zero_extract:X (match_dup 2)
> + (const_int 1)
> + (match_dup 9)))
> +   (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
> +   (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
> +  (label_ref (match_dup 0))
> +  (pc)))]
> +{
> +   unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
> +   unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
> +
> +   /* Make sure that the reference value has one of the bits of the mask set 
> */
> +   if ((twobits_mask & singlebit_mask) == 0)
> +  FAIL;
> +
> +   int setbit = ctz_hwi (singlebit_mask);
> +   int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
> +
> +   operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE ? EQ : NE,
> +mode, operands[6], GEN_INT(0));
> +
> +   operands[8] = GEN_INT (setbit);
> +   operands[9] = GEN_INT (clearbit);
> +})
> diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
> index 490bff688a7..6e34829a59b 100644
> --- a/gcc/config/riscv/predicates.md
> +++ b/gcc/config/riscv/predicates.md
> @@ -321,6 +321,11 @@
>(and (match_code "const_int")
> (match_test "popcount_hwi (~UINTVAL (op)) == 2")))
>
> +;; A CONST_INT operand that has exactly two bits set.
> +(define_predicate "const_twobits_operand"
> +  (and (match_code "const_int")
> +   (match_test "popcount_hwi (UINTVAL (op)) == 2")))
> +
>  ;; A CONST_INT operand that fits into the unsigned half of a
>  ;; signed-immediate after the top bit has been cleared.
>  (define_predicate "uimm_extra_bit_operand"
> diff --git a/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c 
> b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> new file mode 100644
> index 000..d249a841ff9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zbb_zbs -mabi=lp64" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */

It would be useful to add a rv32 testcase too.

Thanks,
Andrew Pinski

> +
> +void g();
> +
> +void f1 (long a)
> +{
> +  if ((a & ((1ul << 33) | (1 << 4))) == (1ul << 33))
> +g();
> +}
> +
> +void f2 (long a)
> +{
> +  if ((a & 0x12) == 0x10)
> +g();
> +}
> +
> +/* { dg-final { scan-assembler-times "bexti\t" 2 } } */
> +/* { dg-final { scan-assembler-times "andn\t" 1 } } */
> --
> 2.34.1
>


Re: [PATCH] RISC-V: Handle "(a & twobits) == singlebit" in branches using Zbs

2022-11-17 Thread Andrew Pinski via Gcc-patches
On Thu, Nov 17, 2022 at 10:25 AM Andrew Pinski  wrote:
>
> On Sun, Nov 13, 2022 at 12:51 PM Philipp Tomsich
>  wrote:
> >
> > Use Zbs when generating a sequence for "if ((a & twobits) == singlebit) ..."
> > that can be expressed as bexti + bexti + andn.
>
> Can't you also handle if ((a & twobits) == 0) case doing a similar thing.
> That is:
> two bexti + and and then compare against zero which is exactly the
> same # of instructions as the above case.
>
>
> >
> > gcc/ChangeLog:
> >
> > * config/riscv/bitmanip.md 
> > (*branch_mask_twobits_equals_singlebit):
> > Handle "if ((a & T) == C)" using Zbs, when T has 2 bits set and C 
> > has one
> > of these tow bits set.
> > * config/riscv/predicates.md (const_twobits_operand): New predicate.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gcc.target/riscv/zbs-if_then_else-01.c: New test.
> >
> > Signed-off-by: Philipp Tomsich 
> > ---
> >
> >  gcc/config/riscv/bitmanip.md  | 42 +++
> >  gcc/config/riscv/predicates.md|  5 +++
> >  .../gcc.target/riscv/zbs-if_then_else-01.c| 20 +
> >  3 files changed, 67 insertions(+)
> >  create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> >
> > diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> > index 7a8f4e35880..2cea394671f 100644
> > --- a/gcc/config/riscv/bitmanip.md
> > +++ b/gcc/config/riscv/bitmanip.md
> > @@ -690,3 +690,45 @@
> >"TARGET_ZBS"
> >[(set (match_dup 0) (zero_extract:X (match_dup 1) (const_int 1) 
> > (match_dup 2)))
> > (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
> > +
> > +;; IF_THEN_ELSE: test for 2 bits of opposite polarity
> > +(define_insn_and_split "*branch_mask_twobits_equals_singlebit"
> > +  [(set (pc)
> > +   (if_then_else (match_operator 1 "equality_operator"
> > +  [(and:X (match_operand:X 2 "register_operand" "r")
> > +  (match_operand:X 3 "const_twobits_operand" 
> > "i"))
> > +   (match_operand:X 4 "single_bit_mask_operand" "i")])
> > +(label_ref (match_operand 0 "" ""))
> > +(pc)))
> > +   (clobber (match_scratch:X 5 "=&r"))
> > +   (clobber (match_scratch:X 6 "=&r"))]
> > +  "TARGET_ZBS && TARGET_ZBB && !SMALL_OPERAND (INTVAL (operands[3]))"

Is there a reason why you can't do this at expand time? I think there
are recent patches floating around which is supposed to help with that
case and the RISCV backend just needs to plug into that infrastructure
too.

Thanks,
Andrew Pinski

> > +  "#"
> > +  "&& reload_completed"
> > +  [(set (match_dup 5) (zero_extract:X (match_dup 2)
> > + (const_int 1)
> > + (match_dup 8)))
> > +   (set (match_dup 6) (zero_extract:X (match_dup 2)
> > + (const_int 1)
> > + (match_dup 9)))
> > +   (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
> > +   (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
> > +  (label_ref (match_dup 0))
> > +  (pc)))]
> > +{
> > +   unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
> > +   unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
> > +
> > +   /* Make sure that the reference value has one of the bits of the mask 
> > set */
> > +   if ((twobits_mask & singlebit_mask) == 0)
> > +  FAIL;
> > +
> > +   int setbit = ctz_hwi (singlebit_mask);
> > +   int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
> > +
> > +   operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE ? EQ : NE,
> > +mode, operands[6], GEN_INT(0));
> > +
> > +   operands[8] = GEN_INT (setbit);
> > +   operands[9] = GEN_INT (clearbit);
> > +})
> > diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
> > index 490bff688a7..6e34829a59b 100644
> > --- a/gcc/config/riscv/predicates.md
> > +++ b/gcc/config/riscv/predicates.md
> > @@ -321,6 +321,11 @@
> >(and (match_code "const_int")
> > (match_test "popcount_hwi (~UINTVAL (op)) == 2")))
> >
> > +;; A CONST_INT operand that has exactly two bits set.
> > +(define_predicate "const_twobits_operand"
> > +  (and (match_code "const_int")
> > +   (match_test "popcount_hwi (UINTVAL (op)) == 2")))
> > +
> >  ;; A CONST_INT operand that fits into the unsigned half of a
> >  ;; signed-immediate after the top bit has been cleared.
> >  (define_predicate "uimm_extra_bit_operand"
> > diff --git a/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c 
> > b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> > new file mode 100644
> > index 000..d249a841ff9
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> > @@ -0,0 +1,20 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gc_zbb_zbs -mabi=lp64" } */

Re: [PATCH] RISC-V: Handle "(a & twobits) == singlebit" in branches using Zbs

2022-11-17 Thread Andrew Waterman
Am I wrong to worry that this will increase dynamic instruction count
when used in a loop?  The obvious code is more efficient when the
constant loads can be hoisted out of a loop.  Or does the cost model
account for this somehow?


On Sun, Nov 13, 2022 at 12:50 PM Philipp Tomsich
 wrote:
>
> Use Zbs when generating a sequence for "if ((a & twobits) == singlebit) ..."
> that can be expressed as bexti + bexti + andn.
>
> gcc/ChangeLog:
>
> * config/riscv/bitmanip.md 
> (*branch_mask_twobits_equals_singlebit):
> Handle "if ((a & T) == C)" using Zbs, when T has 2 bits set and C has 
> one
> of these tow bits set.
> * config/riscv/predicates.md (const_twobits_operand): New predicate.
>
> gcc/testsuite/ChangeLog:
>
> * gcc.target/riscv/zbs-if_then_else-01.c: New test.
>
> Signed-off-by: Philipp Tomsich 
> ---
>
>  gcc/config/riscv/bitmanip.md  | 42 +++
>  gcc/config/riscv/predicates.md|  5 +++
>  .../gcc.target/riscv/zbs-if_then_else-01.c| 20 +
>  3 files changed, 67 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
>
> diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> index 7a8f4e35880..2cea394671f 100644
> --- a/gcc/config/riscv/bitmanip.md
> +++ b/gcc/config/riscv/bitmanip.md
> @@ -690,3 +690,45 @@
>"TARGET_ZBS"
>[(set (match_dup 0) (zero_extract:X (match_dup 1) (const_int 1) (match_dup 
> 2)))
> (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
> +
> +;; IF_THEN_ELSE: test for 2 bits of opposite polarity
> +(define_insn_and_split "*branch_mask_twobits_equals_singlebit"
> +  [(set (pc)
> +   (if_then_else (match_operator 1 "equality_operator"
> +  [(and:X (match_operand:X 2 "register_operand" "r")
> +  (match_operand:X 3 "const_twobits_operand" 
> "i"))
> +   (match_operand:X 4 "single_bit_mask_operand" "i")])
> +(label_ref (match_operand 0 "" ""))
> +(pc)))
> +   (clobber (match_scratch:X 5 "=&r"))
> +   (clobber (match_scratch:X 6 "=&r"))]
> +  "TARGET_ZBS && TARGET_ZBB && !SMALL_OPERAND (INTVAL (operands[3]))"
> +  "#"
> +  "&& reload_completed"
> +  [(set (match_dup 5) (zero_extract:X (match_dup 2)
> + (const_int 1)
> + (match_dup 8)))
> +   (set (match_dup 6) (zero_extract:X (match_dup 2)
> + (const_int 1)
> + (match_dup 9)))
> +   (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
> +   (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
> +  (label_ref (match_dup 0))
> +  (pc)))]
> +{
> +   unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
> +   unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
> +
> +   /* Make sure that the reference value has one of the bits of the mask set 
> */
> +   if ((twobits_mask & singlebit_mask) == 0)
> +  FAIL;
> +
> +   int setbit = ctz_hwi (singlebit_mask);
> +   int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
> +
> +   operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE ? EQ : NE,
> +mode, operands[6], GEN_INT(0));
> +
> +   operands[8] = GEN_INT (setbit);
> +   operands[9] = GEN_INT (clearbit);
> +})
> diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
> index 490bff688a7..6e34829a59b 100644
> --- a/gcc/config/riscv/predicates.md
> +++ b/gcc/config/riscv/predicates.md
> @@ -321,6 +321,11 @@
>(and (match_code "const_int")
> (match_test "popcount_hwi (~UINTVAL (op)) == 2")))
>
> +;; A CONST_INT operand that has exactly two bits set.
> +(define_predicate "const_twobits_operand"
> +  (and (match_code "const_int")
> +   (match_test "popcount_hwi (UINTVAL (op)) == 2")))
> +
>  ;; A CONST_INT operand that fits into the unsigned half of a
>  ;; signed-immediate after the top bit has been cleared.
>  (define_predicate "uimm_extra_bit_operand"
> diff --git a/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c 
> b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> new file mode 100644
> index 000..d249a841ff9
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> @@ -0,0 +1,20 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_zbb_zbs -mabi=lp64" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-Og" "-O1" } } */
> +
> +void g();
> +
> +void f1 (long a)
> +{
> +  if ((a & ((1ul << 33) | (1 << 4))) == (1ul << 33))
> +g();
> +}
> +
> +void f2 (long a)
> +{
> +  if ((a & 0x12) == 0x10)
> +g();
> +}
> +
> +/* { dg-final { scan-assembler-times "bexti\t" 2 } } */
> +/* { dg-final { scan-assembler-times "andn\t" 1 } } */
> --
> 2.34.1
>


[PATCH] c++: constinit on pointer to function [PR104066]

2022-11-17 Thread Marek Polacek via Gcc-patches
[dcl.constinit]: "The constinit specifier shall be applied only to
a declaration of a variable with static or thread storage duration."

Thus, this ought to be OK:

  constinit void (*p)() = nullptr;

but the error message I introduced when implementing constinit was
not looking at funcdecl_p, so the code above was rejected.

Fixed thus.  I'm checking constinit_p first because I think that's
far more likely to be false than funcdecl_p.

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
I think I'd like to backport this all the way back to 10.

PR c++/104066

gcc/cp/ChangeLog:

* decl.cc (grokdeclarator): Check funcdecl_p before complaining
about constinit.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/constinit18.C: New test.
---
 gcc/cp/decl.cc   |  2 +-
 gcc/testsuite/g++.dg/cpp2a/constinit18.C | 12 
 2 files changed, 13 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/constinit18.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index d28889ed865..9a7b1a6c381 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -13071,7 +13071,7 @@ grokdeclarator (const cp_declarator *declarator,
  "an array", name);
return error_mark_node;
  }
-   if (constinit_p)
+   if (constinit_p && funcdecl_p)
  {
error_at (declspecs->locations[ds_constinit],
  "% on function return type is not "
diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit18.C 
b/gcc/testsuite/g++.dg/cpp2a/constinit18.C
new file mode 100644
index 000..51b4f0273be
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/constinit18.C
@@ -0,0 +1,12 @@
+// PR c++/104066
+// { dg-do compile { target c++20 } }
+
+constinit void (*p)() = nullptr;
+constinit void (*pp)() = nullptr;
+void fn();
+constinit void (&r)() = fn;
+
+extern constinit long (* const syscall_reexported) (long, ...);
+
+constinit void bad (); // { dg-error ".constinit. on function return type is 
not allowed" }
+constinit void bad () { } // { dg-error ".constinit. on function return type 
is not allowed" }

base-commit: ee892832ea19b21a3420ef042e582204fac852a2
-- 
2.38.1



Re: [PATCH] c++, v3: Implement C++23 P2647R1 - Permitting static constexpr variables in constexpr functions

2022-11-17 Thread Jakub Jelinek via Gcc-patches
On Thu, Nov 17, 2022 at 09:42:18AM -0500, Jason Merrill wrote:
> > --- gcc/cp/constexpr.cc.jj  2022-11-17 08:48:30.530357181 +0100
> > +++ gcc/cp/constexpr.cc 2022-11-17 09:56:50.479522863 +0100
> > @@ -7098,7 +7098,8 @@ cxx_eval_constant_expression (const cons
> > && (TREE_STATIC (r)
> > || (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r)))
> > /* Allow __FUNCTION__ etc.  */
> > -   && !DECL_ARTIFICIAL (r))
> > +   && !DECL_ARTIFICIAL (r)
> > +   && (cxx_dialect < cxx20 || !decl_constant_var_p (r)))
> 
> I don't think we need to check cxx_dialect here since
> diagnose_static_in_constexpr will have already complained.

I thought for older C++ this is to catch
void
foo ()
{
  constexpr int a = ({ static constexpr int b = 2; b; });
}
and for C++23 the only 3 spots that diagnose those.
But perhaps for C++20 or older we can check if the var has a context
of a constexpr function (then assume cp_finish_decl errored or pedwarned
already) and only error or pedwarn otherwise.

> 
> >   {
> > if (!ctx->quiet)
> >   {
> > @@ -9588,7 +9589,12 @@ potential_constant_expression_1 (tree t,
> > tmp = DECL_EXPR_DECL (t);
> > if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp))
> > {
> > - if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp))
> > + if (CP_DECL_THREAD_LOCAL_P (tmp)
> > + && !DECL_REALLY_EXTERN (tmp)
> > + && (cxx_dialect < cxx20
> > + || (processing_template_decl
> > + ? !decl_maybe_constant_var_p (tmp)
> > + : !decl_constant_var_p (tmp
> 
> Or here.
> 
> > {
> >   if (flags & tf_error)
> > constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
> > @@ -9596,7 +9602,11 @@ potential_constant_expression_1 (tree t,
> >  "% context", tmp);
> >   return false;
> > }
> > - else if (TREE_STATIC (tmp))
> > + else if (TREE_STATIC (tmp)
> > +  && (cxx_dialect < cxx20
> > +  || (processing_template_decl
> > +  ? !decl_maybe_constant_var_p (tmp)
> > +  : !decl_constant_var_p (tmp
> > {
> >   if (flags & tf_error)
> > constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,

And these too.

> > +static void
> > +diagnose_static_in_constexpr (tree decl)
> > +{
> > +  if (current_function_decl && VAR_P (decl)
> > +  && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
> > +  && cxx_dialect < cxx23
> > +  && (cxx_dialect < cxx20
> > + || (processing_template_decl
> > + ? !decl_maybe_constant_var_p (decl)
> > + : !decl_constant_var_p (decl
> 
> For (maybe) constant variables let's make this error a pedwarn in C++20 and
> below.

Ok.
> 
> > +{
> > +  bool ok = false;
> > +  if (CP_DECL_THREAD_LOCAL_P (decl) && !DECL_REALLY_EXTERN (decl))
> > +   error_at (DECL_SOURCE_LOCATION (decl),
> > + "%qD defined % in %qs function only "
> > + "available with %<-std=c++2b%> or %<-std=gnu++2b%>", decl,
> > + DECL_IMMEDIATE_FUNCTION_P (current_function_decl)
> > + ? "consteval" : "constexpr");
> > +  else if (TREE_STATIC (decl))
> > +   error_at (DECL_SOURCE_LOCATION (decl),
> > + "%qD defined % in %qs function only available "
> > + "with %<-std=c++2b%> or %<-std=gnu++2b%>", decl,
> > + DECL_IMMEDIATE_FUNCTION_P (current_function_decl)
> > + ? "consteval" : "constexpr");
> > +  else
> > +   ok = true;
> > +  if (!ok)
> > +   cp_function_chain->invalid_constexpr = true;
> > +}
> > +}
> > +
> >   /* Process a DECLARATOR for a function-scope or namespace-scope
> >  variable or function declaration.
> >  (Function definitions go through start_function; class member
> > @@ -5860,28 +5895,8 @@ start_decl (const cp_declarator *declara
> > DECL_THIS_STATIC (decl) = 1;
> >   }
> > -  if (current_function_decl && VAR_P (decl)
> > -  && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
> > -  && cxx_dialect < cxx23)
> > -{
> > -  bool ok = false;
> > -  if (CP_DECL_THREAD_LOCAL_P (decl) && !DECL_REALLY_EXTERN (decl))
> > -   error_at (DECL_SOURCE_LOCATION (decl),
> > - "%qD defined % in %qs function only "
> > - "available with %<-std=c++2b%> or %<-std=gnu++2b%>", decl,
> > - DECL_IMMEDIATE_FUNCTION_P (current_function_decl)
> > - ? "consteval" : "constexpr");
> > -  else if (TREE_STATIC (decl))
> > -   error_at (DECL_SOURCE_LOCATION (decl),
> > - "%qD defined % in %qs function only available "
> > - "with %<-std=c++2b%> or %<-std=gnu++2b%>", decl,
> > - DECL_IMMEDIATE_FUNCTION_P (current_function_decl)
> > - ? "consteval" : "constexpr");
> > -  else
> > -   ok = true;
> > -  if (!ok)
> > -   cp_function_chain->inva

Re: [PATCH] RISC-V: Handle "(a & twobits) == singlebit" in branches using Zbs

2022-11-17 Thread Philipp Tomsich
On Thu, 17 Nov 2022 at 19:33, Andrew Waterman  wrote:
>
> Am I wrong to worry that this will increase dynamic instruction count
> when used in a loop?  The obvious code is more efficient when the
> constant loads can be hoisted out of a loop.  Or does the cost model
> account for this somehow?

With this change merged, GCC still hoists the constants out of the
loop (just checked with a quick test case).
So the cost model seems correct (whether intentionally or accidentally).

Thanks,
Philipp.

>
>
> On Sun, Nov 13, 2022 at 12:50 PM Philipp Tomsich
>  wrote:
> >
> > Use Zbs when generating a sequence for "if ((a & twobits) == singlebit) ..."
> > that can be expressed as bexti + bexti + andn.
> >
> > gcc/ChangeLog:
> >
> > * config/riscv/bitmanip.md 
> > (*branch_mask_twobits_equals_singlebit):
> > Handle "if ((a & T) == C)" using Zbs, when T has 2 bits set and C 
> > has one
> > of these tow bits set.
> > * config/riscv/predicates.md (const_twobits_operand): New predicate.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * gcc.target/riscv/zbs-if_then_else-01.c: New test.
> >
> > Signed-off-by: Philipp Tomsich 
> > ---
> >
> >  gcc/config/riscv/bitmanip.md  | 42 +++
> >  gcc/config/riscv/predicates.md|  5 +++
> >  .../gcc.target/riscv/zbs-if_then_else-01.c| 20 +
> >  3 files changed, 67 insertions(+)
> >  create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> >
> > diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> > index 7a8f4e35880..2cea394671f 100644
> > --- a/gcc/config/riscv/bitmanip.md
> > +++ b/gcc/config/riscv/bitmanip.md
> > @@ -690,3 +690,45 @@
> >"TARGET_ZBS"
> >[(set (match_dup 0) (zero_extract:X (match_dup 1) (const_int 1) 
> > (match_dup 2)))
> > (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
> > +
> > +;; IF_THEN_ELSE: test for 2 bits of opposite polarity
> > +(define_insn_and_split "*branch_mask_twobits_equals_singlebit"
> > +  [(set (pc)
> > +   (if_then_else (match_operator 1 "equality_operator"
> > +  [(and:X (match_operand:X 2 "register_operand" "r")
> > +  (match_operand:X 3 "const_twobits_operand" 
> > "i"))
> > +   (match_operand:X 4 "single_bit_mask_operand" "i")])
> > +(label_ref (match_operand 0 "" ""))
> > +(pc)))
> > +   (clobber (match_scratch:X 5 "=&r"))
> > +   (clobber (match_scratch:X 6 "=&r"))]
> > +  "TARGET_ZBS && TARGET_ZBB && !SMALL_OPERAND (INTVAL (operands[3]))"
> > +  "#"
> > +  "&& reload_completed"
> > +  [(set (match_dup 5) (zero_extract:X (match_dup 2)
> > + (const_int 1)
> > + (match_dup 8)))
> > +   (set (match_dup 6) (zero_extract:X (match_dup 2)
> > + (const_int 1)
> > + (match_dup 9)))
> > +   (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
> > +   (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
> > +  (label_ref (match_dup 0))
> > +  (pc)))]
> > +{
> > +   unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
> > +   unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
> > +
> > +   /* Make sure that the reference value has one of the bits of the mask 
> > set */
> > +   if ((twobits_mask & singlebit_mask) == 0)
> > +  FAIL;
> > +
> > +   int setbit = ctz_hwi (singlebit_mask);
> > +   int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
> > +
> > +   operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE ? EQ : NE,
> > +mode, operands[6], GEN_INT(0));
> > +
> > +   operands[8] = GEN_INT (setbit);
> > +   operands[9] = GEN_INT (clearbit);
> > +})
> > diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md
> > index 490bff688a7..6e34829a59b 100644
> > --- a/gcc/config/riscv/predicates.md
> > +++ b/gcc/config/riscv/predicates.md
> > @@ -321,6 +321,11 @@
> >(and (match_code "const_int")
> > (match_test "popcount_hwi (~UINTVAL (op)) == 2")))
> >
> > +;; A CONST_INT operand that has exactly two bits set.
> > +(define_predicate "const_twobits_operand"
> > +  (and (match_code "const_int")
> > +   (match_test "popcount_hwi (UINTVAL (op)) == 2")))
> > +
> >  ;; A CONST_INT operand that fits into the unsigned half of a
> >  ;; signed-immediate after the top bit has been cleared.
> >  (define_predicate "uimm_extra_bit_operand"
> > diff --git a/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c 
> > b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> > new file mode 100644
> > index 000..d249a841ff9
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> > @@ -0,0 +1,20 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-march=rv64gc_zbb_zbs -mabi=lp64" } */
> 

Re: [PATCH] RISC-V: Handle "(a & twobits) == singlebit" in branches using Zbs

2022-11-17 Thread Andrew Waterman
On Thu, Nov 17, 2022 at 10:52 AM Philipp Tomsich
 wrote:
>
> On Thu, 17 Nov 2022 at 19:33, Andrew Waterman  wrote:
> >
> > Am I wrong to worry that this will increase dynamic instruction count
> > when used in a loop?  The obvious code is more efficient when the
> > constant loads can be hoisted out of a loop.  Or does the cost model
> > account for this somehow?
>
> With this change merged, GCC still hoists the constants out of the
> loop (just checked with a quick test case).
> So the cost model seems correct (whether intentionally or accidentally).

Cool, thanks for checking.

>
> Thanks,
> Philipp.
>
> >
> >
> > On Sun, Nov 13, 2022 at 12:50 PM Philipp Tomsich
> >  wrote:
> > >
> > > Use Zbs when generating a sequence for "if ((a & twobits) == singlebit) 
> > > ..."
> > > that can be expressed as bexti + bexti + andn.
> > >
> > > gcc/ChangeLog:
> > >
> > > * config/riscv/bitmanip.md 
> > > (*branch_mask_twobits_equals_singlebit):
> > > Handle "if ((a & T) == C)" using Zbs, when T has 2 bits set and C 
> > > has one
> > > of these tow bits set.
> > > * config/riscv/predicates.md (const_twobits_operand): New 
> > > predicate.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * gcc.target/riscv/zbs-if_then_else-01.c: New test.
> > >
> > > Signed-off-by: Philipp Tomsich 
> > > ---
> > >
> > >  gcc/config/riscv/bitmanip.md  | 42 +++
> > >  gcc/config/riscv/predicates.md|  5 +++
> > >  .../gcc.target/riscv/zbs-if_then_else-01.c| 20 +
> > >  3 files changed, 67 insertions(+)
> > >  create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> > >
> > > diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> > > index 7a8f4e35880..2cea394671f 100644
> > > --- a/gcc/config/riscv/bitmanip.md
> > > +++ b/gcc/config/riscv/bitmanip.md
> > > @@ -690,3 +690,45 @@
> > >"TARGET_ZBS"
> > >[(set (match_dup 0) (zero_extract:X (match_dup 1) (const_int 1) 
> > > (match_dup 2)))
> > > (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
> > > +
> > > +;; IF_THEN_ELSE: test for 2 bits of opposite polarity
> > > +(define_insn_and_split "*branch_mask_twobits_equals_singlebit"
> > > +  [(set (pc)
> > > +   (if_then_else (match_operator 1 "equality_operator"
> > > +  [(and:X (match_operand:X 2 "register_operand" "r")
> > > +  (match_operand:X 3 "const_twobits_operand" 
> > > "i"))
> > > +   (match_operand:X 4 "single_bit_mask_operand" 
> > > "i")])
> > > +(label_ref (match_operand 0 "" ""))
> > > +(pc)))
> > > +   (clobber (match_scratch:X 5 "=&r"))
> > > +   (clobber (match_scratch:X 6 "=&r"))]
> > > +  "TARGET_ZBS && TARGET_ZBB && !SMALL_OPERAND (INTVAL (operands[3]))"
> > > +  "#"
> > > +  "&& reload_completed"
> > > +  [(set (match_dup 5) (zero_extract:X (match_dup 2)
> > > + (const_int 1)
> > > + (match_dup 8)))
> > > +   (set (match_dup 6) (zero_extract:X (match_dup 2)
> > > + (const_int 1)
> > > + (match_dup 9)))
> > > +   (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
> > > +   (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
> > > +  (label_ref (match_dup 0))
> > > +  (pc)))]
> > > +{
> > > +   unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
> > > +   unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
> > > +
> > > +   /* Make sure that the reference value has one of the bits of the mask 
> > > set */
> > > +   if ((twobits_mask & singlebit_mask) == 0)
> > > +  FAIL;
> > > +
> > > +   int setbit = ctz_hwi (singlebit_mask);
> > > +   int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
> > > +
> > > +   operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE ? EQ : NE,
> > > +mode, operands[6], GEN_INT(0));
> > > +
> > > +   operands[8] = GEN_INT (setbit);
> > > +   operands[9] = GEN_INT (clearbit);
> > > +})
> > > diff --git a/gcc/config/riscv/predicates.md 
> > > b/gcc/config/riscv/predicates.md
> > > index 490bff688a7..6e34829a59b 100644
> > > --- a/gcc/config/riscv/predicates.md
> > > +++ b/gcc/config/riscv/predicates.md
> > > @@ -321,6 +321,11 @@
> > >(and (match_code "const_int")
> > > (match_test "popcount_hwi (~UINTVAL (op)) == 2")))
> > >
> > > +;; A CONST_INT operand that has exactly two bits set.
> > > +(define_predicate "const_twobits_operand"
> > > +  (and (match_code "const_int")
> > > +   (match_test "popcount_hwi (UINTVAL (op)) == 2")))
> > > +
> > >  ;; A CONST_INT operand that fits into the unsigned half of a
> > >  ;; signed-immediate after the top bit has been cleared.
> > >  (define_predicate "uimm_extra_bit_operand"
> > > diff --git a/gcc/testsuite/gcc.target/r

Re: [PATCH] RISC-V: Handle "(a & twobits) == singlebit" in branches using Zbs

2022-11-17 Thread Philipp Tomsich
On Thu, 17 Nov 2022 at 19:28, Andrew Pinski  wrote:
>
> On Thu, Nov 17, 2022 at 10:25 AM Andrew Pinski  wrote:
> >
> > On Sun, Nov 13, 2022 at 12:51 PM Philipp Tomsich
> >  wrote:
> > >
> > > Use Zbs when generating a sequence for "if ((a & twobits) == singlebit) 
> > > ..."
> > > that can be expressed as bexti + bexti + andn.
> >
> > Can't you also handle if ((a & twobits) == 0) case doing a similar thing.
> > That is:
> > two bexti + and and then compare against zero which is exactly the
> > same # of instructions as the above case.

We can form any 2-bit constant with BSETI + BSETI (no OR required).
So no explicit support for that case will be required (as a AND + BEQ
will be formed anyway).

> >
> >
> > >
> > > gcc/ChangeLog:
> > >
> > > * config/riscv/bitmanip.md 
> > > (*branch_mask_twobits_equals_singlebit):
> > > Handle "if ((a & T) == C)" using Zbs, when T has 2 bits set and C 
> > > has one
> > > of these tow bits set.
> > > * config/riscv/predicates.md (const_twobits_operand): New 
> > > predicate.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * gcc.target/riscv/zbs-if_then_else-01.c: New test.
> > >
> > > Signed-off-by: Philipp Tomsich 
> > > ---
> > >
> > >  gcc/config/riscv/bitmanip.md  | 42 +++
> > >  gcc/config/riscv/predicates.md|  5 +++
> > >  .../gcc.target/riscv/zbs-if_then_else-01.c| 20 +
> > >  3 files changed, 67 insertions(+)
> > >  create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> > >
> > > diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> > > index 7a8f4e35880..2cea394671f 100644
> > > --- a/gcc/config/riscv/bitmanip.md
> > > +++ b/gcc/config/riscv/bitmanip.md
> > > @@ -690,3 +690,45 @@
> > >"TARGET_ZBS"
> > >[(set (match_dup 0) (zero_extract:X (match_dup 1) (const_int 1) 
> > > (match_dup 2)))
> > > (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
> > > +
> > > +;; IF_THEN_ELSE: test for 2 bits of opposite polarity
> > > +(define_insn_and_split "*branch_mask_twobits_equals_singlebit"
> > > +  [(set (pc)
> > > +   (if_then_else (match_operator 1 "equality_operator"
> > > +  [(and:X (match_operand:X 2 "register_operand" "r")
> > > +  (match_operand:X 3 "const_twobits_operand" 
> > > "i"))
> > > +   (match_operand:X 4 "single_bit_mask_operand" 
> > > "i")])
> > > +(label_ref (match_operand 0 "" ""))
> > > +(pc)))
> > > +   (clobber (match_scratch:X 5 "=&r"))
> > > +   (clobber (match_scratch:X 6 "=&r"))]
> > > +  "TARGET_ZBS && TARGET_ZBB && !SMALL_OPERAND (INTVAL (operands[3]))"
>
> Is there a reason why you can't do this at expand time? I think there
> are recent patches floating around which is supposed to help with that
> case and the RISCV backend just needs to plug into that infrastructure
> too.

I may have missed the specific patches you refer to (pointer to the
relevant series appreciated).

However, if we move this to expand-time, then ifcvt.cc will run after
(and may form this case once our support for polarity-reversed bit
tests is merged).
So there is good reason to have this pattern.

> Thanks,
> Andrew Pinski
>
> > > +  "#"
> > > +  "&& reload_completed"
> > > +  [(set (match_dup 5) (zero_extract:X (match_dup 2)
> > > + (const_int 1)
> > > + (match_dup 8)))
> > > +   (set (match_dup 6) (zero_extract:X (match_dup 2)
> > > + (const_int 1)
> > > + (match_dup 9)))
> > > +   (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
> > > +   (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 0)])
> > > +  (label_ref (match_dup 0))
> > > +  (pc)))]
> > > +{
> > > +   unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
> > > +   unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
> > > +
> > > +   /* Make sure that the reference value has one of the bits of the mask 
> > > set */
> > > +   if ((twobits_mask & singlebit_mask) == 0)
> > > +  FAIL;
> > > +
> > > +   int setbit = ctz_hwi (singlebit_mask);
> > > +   int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
> > > +
> > > +   operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE ? EQ : NE,
> > > +mode, operands[6], GEN_INT(0));
> > > +
> > > +   operands[8] = GEN_INT (setbit);
> > > +   operands[9] = GEN_INT (clearbit);
> > > +})
> > > diff --git a/gcc/config/riscv/predicates.md 
> > > b/gcc/config/riscv/predicates.md
> > > index 490bff688a7..6e34829a59b 100644
> > > --- a/gcc/config/riscv/predicates.md
> > > +++ b/gcc/config/riscv/predicates.md
> > > @@ -321,6 +321,11 @@
> > >(and (match_code "const_int")
> > > (match_test "popcount_hwi (~UINTVAL (op)) == 2")))
> > >
> > > +;; A

Re: [PATCH] [range-ops] Implement sqrt.

2022-11-17 Thread Joseph Myers
On Thu, 17 Nov 2022, Aldy Hernandez via Gcc-patches wrote:

> So... is the optimization wrong?  Are we not allowed to substitute
> that NAN if we know it's gonna happen?  Should we also allow F F F F F
> in the test?  Or something else?

This seems like the usual ambiguity about what transformations 
-ftrapping-math (on by default) is meant to prevent.

Generally it's understood to prevent transformations that add *or remove* 
exceptions, so folding a case that raises "invalid" to a NaN (with 
"invalid" no longer raised) is invalid with -ftrapping-math.  But that 
doesn't tend to be applied if the operation raising the exceptions has a 
result that is otherwise unused - in such a case the operation may still 
be removed completely (the exception isn't properly treated as a side 
effect to avoid dead code elimination; cf. Marc Glisse's -ffenv-access 
patches from August 2020).  And it may often also not be applied to 
"inexact".

There have been various past discussions of possible ways to split up the 
different effects of options such as -ftrapping-math into finer-grained 
options allowing more control of what transformations are permitted - see 
e.g. 
 
and bug 54192.  There is also the question in that context of which 
sub-options should be enabled by default at all.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH] RISC-V: Handle "(a & twobits) == singlebit" in branches using Zbs

2022-11-17 Thread Philipp Tomsich
On Thu, 17 Nov 2022 at 19:56, Andrew Waterman  wrote:
>
> On Thu, Nov 17, 2022 at 10:52 AM Philipp Tomsich
>  wrote:
> >
> > On Thu, 17 Nov 2022 at 19:33, Andrew Waterman  wrote:
> > >
> > > Am I wrong to worry that this will increase dynamic instruction count
> > > when used in a loop?  The obvious code is more efficient when the
> > > constant loads can be hoisted out of a loop.  Or does the cost model
> > > account for this somehow?
> >
> > With this change merged, GCC still hoists the constants out of the
> > loop (just checked with a quick test case).
> > So the cost model seems correct (whether intentionally or accidentally).
>
> Cool, thanks for checking.

We have an updated cost-model for IF_THEN_ELSE brewing, but it didn't
make the cut (and will need some more adjustments and a lot more
testing).
It seems to make a difference on some SPEC workloads.  I don't have a
timeline on finalizing that cost-model improvement yet.

>
> >
> > Thanks,
> > Philipp.
> >
> > >
> > >
> > > On Sun, Nov 13, 2022 at 12:50 PM Philipp Tomsich
> > >  wrote:
> > > >
> > > > Use Zbs when generating a sequence for "if ((a & twobits) == singlebit) 
> > > > ..."
> > > > that can be expressed as bexti + bexti + andn.
> > > >
> > > > gcc/ChangeLog:
> > > >
> > > > * config/riscv/bitmanip.md 
> > > > (*branch_mask_twobits_equals_singlebit):
> > > > Handle "if ((a & T) == C)" using Zbs, when T has 2 bits set and 
> > > > C has one
> > > > of these tow bits set.
> > > > * config/riscv/predicates.md (const_twobits_operand): New 
> > > > predicate.
> > > >
> > > > gcc/testsuite/ChangeLog:
> > > >
> > > > * gcc.target/riscv/zbs-if_then_else-01.c: New test.
> > > >
> > > > Signed-off-by: Philipp Tomsich 
> > > > ---
> > > >
> > > >  gcc/config/riscv/bitmanip.md  | 42 +++
> > > >  gcc/config/riscv/predicates.md|  5 +++
> > > >  .../gcc.target/riscv/zbs-if_then_else-01.c| 20 +
> > > >  3 files changed, 67 insertions(+)
> > > >  create mode 100644 gcc/testsuite/gcc.target/riscv/zbs-if_then_else-01.c
> > > >
> > > > diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
> > > > index 7a8f4e35880..2cea394671f 100644
> > > > --- a/gcc/config/riscv/bitmanip.md
> > > > +++ b/gcc/config/riscv/bitmanip.md
> > > > @@ -690,3 +690,45 @@
> > > >"TARGET_ZBS"
> > > >[(set (match_dup 0) (zero_extract:X (match_dup 1) (const_int 1) 
> > > > (match_dup 2)))
> > > > (set (match_dup 0) (xor:X (match_dup 0) (const_int 1)))])
> > > > +
> > > > +;; IF_THEN_ELSE: test for 2 bits of opposite polarity
> > > > +(define_insn_and_split "*branch_mask_twobits_equals_singlebit"
> > > > +  [(set (pc)
> > > > +   (if_then_else (match_operator 1 "equality_operator"
> > > > +  [(and:X (match_operand:X 2 "register_operand" 
> > > > "r")
> > > > +  (match_operand:X 3 
> > > > "const_twobits_operand" "i"))
> > > > +   (match_operand:X 4 "single_bit_mask_operand" 
> > > > "i")])
> > > > +(label_ref (match_operand 0 "" ""))
> > > > +(pc)))
> > > > +   (clobber (match_scratch:X 5 "=&r"))
> > > > +   (clobber (match_scratch:X 6 "=&r"))]
> > > > +  "TARGET_ZBS && TARGET_ZBB && !SMALL_OPERAND (INTVAL (operands[3]))"
> > > > +  "#"
> > > > +  "&& reload_completed"
> > > > +  [(set (match_dup 5) (zero_extract:X (match_dup 2)
> > > > + (const_int 1)
> > > > + (match_dup 8)))
> > > > +   (set (match_dup 6) (zero_extract:X (match_dup 2)
> > > > + (const_int 1)
> > > > + (match_dup 9)))
> > > > +   (set (match_dup 6) (and:X (not:X (match_dup 6)) (match_dup 5)))
> > > > +   (set (pc) (if_then_else (match_op_dup 1 [(match_dup 6) (const_int 
> > > > 0)])
> > > > +  (label_ref (match_dup 0))
> > > > +  (pc)))]
> > > > +{
> > > > +   unsigned HOST_WIDE_INT twobits_mask = UINTVAL (operands[3]);
> > > > +   unsigned HOST_WIDE_INT singlebit_mask = UINTVAL (operands[4]);
> > > > +
> > > > +   /* Make sure that the reference value has one of the bits of the 
> > > > mask set */
> > > > +   if ((twobits_mask & singlebit_mask) == 0)
> > > > +  FAIL;
> > > > +
> > > > +   int setbit = ctz_hwi (singlebit_mask);
> > > > +   int clearbit = ctz_hwi (twobits_mask & ~singlebit_mask);
> > > > +
> > > > +   operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE ? EQ : 
> > > > NE,
> > > > +mode, operands[6], GEN_INT(0));
> > > > +
> > > > +   operands[8] = GEN_INT (setbit);
> > > > +   operands[9] = GEN_INT (clearbit);
> > > > +})
> > > > diff --git a/gcc/config/riscv/predicates.md 
> > > > b/gcc/config/riscv/predicates.md
> > > > index 490bff688a7..6e34829a59b 100644
> > > > --- a/gcc/config/riscv/predicates.md
> > > > +++ b/gcc/config/riscv/predicates.md
> > > > 

Re: [PATCH 2/5] c++: Set the locus of the function result decl

2022-11-17 Thread Bernhard Reutner-Fischer via Gcc-patches
On Thu, 17 Nov 2022 09:53:32 -0500
Jason Merrill  wrote:

> On 11/17/22 03:56, Bernhard Reutner-Fischer wrote:
> > On Tue, 15 Nov 2022 18:52:41 -0500
> > Jason Merrill  wrote:
> >   
> >> On 11/12/22 13:45, Bernhard Reutner-Fischer wrote:  
> >>> gcc/cp/ChangeLog:
> >>>
> >>>   * decl.cc (start_function): Set the result decl source location to
> >>>   the location of the typespec.
> >>>
> >>> ---
> >>> Bootstrapped and regtested on x86_86-unknown-linux with no regressions.
> >>> Ok for trunk?
> >>>
> >>> Cc: Nathan Sidwell 
> >>> Cc: Jason Merrill 
> >>> ---
> >>>gcc/cp/decl.cc | 15 ++-
> >>>1 file changed, 14 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> >>> index 6e98ea35a39..ed40815e645 100644
> >>> --- a/gcc/cp/decl.cc
> >>> +++ b/gcc/cp/decl.cc
> >>> @@ -17449,6 +17449,8 @@ start_function (cp_decl_specifier_seq *declspecs,
> >>>   tree attrs)
> >>>{
> >>>  tree decl1;
> >>> +  tree result;
> >>> +  bool ret;  
> >>
> >> We now prefer to declare new variables as late as possible, usually when
> >> they are initialized.  
> > 
> > Moved. Ok like attached? Bootstrapped and regtested fine.
> >   
> >>>  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
> >>>  invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1);
> >>> @@ -17461,7 +17463,18 @@ start_function (cp_decl_specifier_seq *declspecs,
> >>>gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
> >>>integer_type_node));
> >>>
> >>> -  return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
> >>> +  ret = start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
> >>> +
> >>> +  /* decl1 might be ggc_freed here.  */
> >>> +  decl1 = current_function_decl;
> >>> +
> >>> +  /* Set the result decl source location to the location of the 
> >>> typespec.  */
> >>> +  if (TREE_CODE (decl1) == FUNCTION_DECL
> >>> +  && declspecs->locations[ds_type_spec] != UNKNOWN_LOCATION
> >>> +  && (result = DECL_RESULT (decl1)) != NULL_TREE
> >>> +  && DECL_SOURCE_LOCATION (result) == input_location)
> >>> +DECL_SOURCE_LOCATION (result) = declspecs->locations[ds_type_spec];  
> >>
> >> One way to handle the template case would be for the code in
> >> start_preparsed_function that sets DECL_RESULT to check whether decl1 is
> >> a template instantiation, and in that case copy the location from the
> >> template's DECL_RESULT, i.e.
> >>
> >> DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1)))  
> > 
> > Well, that would probably work if something would set the location of
> > that template result decl properly, which nothing does out of the box.  
> 
> Hmm, it should get set by your patch, since templates go through 
> start_function like normal functions.
> 
> > diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> > index ed7226b82f0..65d78c82a2d 100644
> > --- a/gcc/cp/decl.cc
> > +++ b/gcc/cp/decl.cc
> > @@ -17230,6 +17231,17 @@ start_preparsed_function (tree decl1, tree attrs, 
> > int flags)
> > cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
> >   }
> >   
> > +  /* Set the result decl source location to the location of the typespec.  
> > */
> > +  if (DECL_RESULT (decl1)
> > +  && !DECL_USE_TEMPLATE (decl1)
> > +  && DECL_TEMPLATE_INFO (decl1)
> > +  && DECL_TI_TEMPLATE (decl1)
> > +  && DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1))
> > +  && DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1  
> 
> This condition is true only for the template definition, for which you 
> haven't gotten to your start_function change yet.
> 
> Instead, you want to copy the location for instantiations, i.e. check 
> DECL_TEMPLATE_INSTANTIATION instead of !DECL_USE_TEMPLATE.

No, that makes no difference.
But really I'm not interested in the template case, i only mentioned
them because they don't work and in case somebody wanted to have correct
locations.
I remember just frustration when i looked at those a year ago.

Is the hunk for normal functions OK for trunk?

thanks,

> 
> > +  DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
> > +   = DECL_SOURCE_LOCATION (  
> 
> Open paren goes on the new line.
> 
> > +   DECL_RESULT (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (decl1; >   
> >   /* Record the decl so that the function name is defined.
> >If we already have a decl for this name, and it is a FUNCTION_DECL,
> >use the old decl.  */
> > 
> > (gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result 
> > locus before")
> > ../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus before
> >  7 |   { return _M_finish != 0; }
> >|   ^
> > (gdb) n
> > (gdb) call inform(DECL_SOURCE_LOCATION (DECL_RESULT (decl1)), "decl1 result 
> > locus from TI")
> > ../tmp4/return-narrow-2.cc:7:3: note: decl1 result locus from TI
> > (gdb) p DECL_SOURCE_LOCATION (DECL_RESULT (decl1))
> > $1 =

Re: [PATCH] [range-ops] Implement sqrt.

2022-11-17 Thread Jakub Jelinek via Gcc-patches
On Thu, Nov 17, 2022 at 06:59:45PM +, Joseph Myers wrote:
> On Thu, 17 Nov 2022, Aldy Hernandez via Gcc-patches wrote:
> 
> > So... is the optimization wrong?  Are we not allowed to substitute
> > that NAN if we know it's gonna happen?  Should we also allow F F F F F
> > in the test?  Or something else?
> 
> This seems like the usual ambiguity about what transformations 
> -ftrapping-math (on by default) is meant to prevent.
> 
> Generally it's understood to prevent transformations that add *or remove* 
> exceptions, so folding a case that raises "invalid" to a NaN (with 
> "invalid" no longer raised) is invalid with -ftrapping-math.  But that 
> doesn't tend to be applied if the operation raising the exceptions has a 
> result that is otherwise unused - in such a case the operation may still 
> be removed completely (the exception isn't properly treated as a side 
> effect to avoid dead code elimination; cf. Marc Glisse's -ffenv-access 
> patches from August 2020).  And it may often also not be applied to 
> "inexact".

The problem is that the above model I'm afraid is largely incompatible with
the optimizations ranger provides.
A strict model where no operations that could raise exceptions are discarded
is easy, we let frange optimize as much as it wants and just tell DCE not to
eliminate operations that can raise exceptions.
But in the model where some exceptions can be discarded if results are unused
but not others where they are used, there is no way to distinguish between
the result of the operation really isn't needed and ranger figured out a
result (or usable range of something) and therefore the result of the
operation isn't needed.
Making frange more limited with -ftrapping-math, making it punt for
operations that could raise an exception would be quite drastic
pessimization.  Perhaps for -ftrapping-math we could say no frange value is
singleton and so at least for most of operations we actually wouldn't
optimize out the whole computation when we know the result?  Still, we could
also just have
r = long_computation (x, y, z);
if (r > 42.0)
and if frange figures out that r must be [256.0, 1024.0] and never NAN, we'd
still happily optimize away the comparison.

Jakub



Re: [PATCH v2] tree-object-size: Support strndup and strdup

2022-11-17 Thread Siddhesh Poyarekar

Ping!

On 2022-11-04 08:48, Siddhesh Poyarekar wrote:

Use string length of input to strdup to determine the usable size of the
resulting object.  Avoid doing the same for strndup since there's a
chance that the input may be too large, resulting in an unnecessary
overhead or worse, the input may not be NULL terminated, resulting in a
crash where there would otherwise have been none.

gcc/ChangeLog:

* tree-object-size.cc (todo): New variable.
(object_sizes_execute): Use it.
(strdup_object_size): New function.
(call_object_size): Use it.

gcc/testsuite/ChangeLog:

* gcc.dg/builtin-dynamic-object-size-0.c (test_strdup,
test_strndup, test_strdup_min, test_strndup_min): New tests.
(main): Call them.
* gcc.dg/builtin-dynamic-object-size-1.c: Silence overread
warnings.
* gcc.dg/builtin-dynamic-object-size-2.c: Likewise.
* gcc.dg/builtin-dynamic-object-size-3.c: Likewise.
* gcc.dg/builtin-dynamic-object-size-4.c: Likewise.
* gcc.dg/builtin-object-size-1.c: Silence overread warnings.
Declare free, strdup and strndup.
(test11): New test.
(main): Call it.
* gcc.dg/builtin-object-size-2.c: Silence overread warnings.
Declare free, strdup and strndup.
(test9): New test.
(main): Call it.
* gcc.dg/builtin-object-size-3.c: Silence overread warnings.
Declare free, strdup and strndup.
(test11): New test.
(main): Call it.
* gcc.dg/builtin-object-size-4.c: Silence overread warnings.
Declare free, strdup and strndup.
(test9): New test.
(main): Call it.
---
Tested:

- x86_64 bootstrap and testsuite run
- i686 build and testsuite run
- ubsan bootstrap

  .../gcc.dg/builtin-dynamic-object-size-0.c| 43 +
  .../gcc.dg/builtin-dynamic-object-size-1.c|  2 +-
  .../gcc.dg/builtin-dynamic-object-size-2.c|  2 +-
  .../gcc.dg/builtin-dynamic-object-size-3.c|  2 +-
  .../gcc.dg/builtin-dynamic-object-size-4.c|  2 +-
  gcc/testsuite/gcc.dg/builtin-object-size-1.c  | 94 +-
  gcc/testsuite/gcc.dg/builtin-object-size-2.c  | 94 +-
  gcc/testsuite/gcc.dg/builtin-object-size-3.c  | 95 ++-
  gcc/testsuite/gcc.dg/builtin-object-size-4.c  | 94 +-
  gcc/tree-object-size.cc   | 84 +++-
  10 files changed, 502 insertions(+), 10 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c 
b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
index 01a280b2d7b..4f1606a486b 100644
--- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c
@@ -479,6 +479,40 @@ test_loop (int *obj, size_t sz, size_t start, size_t end, 
int incr)
return __builtin_dynamic_object_size (ptr, 0);
  }
  
+/* strdup/strndup.  */

+
+size_t
+__attribute__ ((noinline))
+test_strdup (const char *in)
+{
+  char *res = __builtin_strdup (in);
+  return __builtin_dynamic_object_size (res, 0);
+}
+
+size_t
+__attribute__ ((noinline))
+test_strndup (const char *in, size_t bound)
+{
+  char *res = __builtin_strndup (in, bound);
+  return __builtin_dynamic_object_size (res, 0);
+}
+
+size_t
+__attribute__ ((noinline))
+test_strdup_min (const char *in)
+{
+  char *res = __builtin_strdup (in);
+  return __builtin_dynamic_object_size (res, 2);
+}
+
+size_t
+__attribute__ ((noinline))
+test_strndup_min (const char *in, size_t bound)
+{
+  char *res = __builtin_strndup (in, bound);
+  return __builtin_dynamic_object_size (res, 2);
+}
+
  /* Other tests.  */
  
  struct TV4

@@ -651,6 +685,15 @@ main (int argc, char **argv)
int *t = test_pr105736 (&val3);
if (__builtin_dynamic_object_size (t, 0) != -1)
  FAIL ();
+  const char *str = "hello world";
+  if (test_strdup (str) != __builtin_strlen (str) + 1)
+FAIL ();
+  if (test_strndup (str, 4) != 5)
+FAIL ();
+  if (test_strdup_min (str) != __builtin_strlen (str) + 1)
+FAIL ();
+  if (test_strndup_min (str, 4) != 1)
+FAIL ();
  
if (nfails > 0)

  __builtin_abort ();
diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c 
b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c
index 7cc8b1c9488..8f17c8edcaf 100644
--- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-1.c
@@ -1,5 +1,5 @@
  /* { dg-do run } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -Wno-stringop-overread" } */
  /* { dg-require-effective-target alloca } */
  
  #define __builtin_object_size __builtin_dynamic_object_size

diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c 
b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c
index 267dbf48ca7..3677782ff1c 100644
--- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c
+++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-2.c
@@ -1,5 +1,5 @@
  /* { dg-do run } */
-/* { dg-opti

Re: [Patch Arm] Fix PR 92999

2022-11-17 Thread Ramana Radhakrishnan via Gcc-patches
On Fri, Nov 11, 2022 at 9:50 PM Ramana Radhakrishnan
 wrote:
>
> On Thu, Nov 10, 2022 at 7:46 PM Ramana Radhakrishnan
>  wrote:
> >
> > On Thu, Nov 10, 2022 at 6:03 PM Richard Earnshaw
> >  wrote:
> > >
> > >
> > >
> > > On 10/11/2022 17:21, Richard Earnshaw via Gcc-patches wrote:
> > > >
> > > >
> > > > On 08/11/2022 18:20, Ramana Radhakrishnan via Gcc-patches wrote:
> > > >> PR92999 is a case where the VFP calling convention does not allocate
> > > >> enough FP registers for a homogenous aggregate containing FP16 values.
> > > >> I believe this is the complete fix but would appreciate another set of
> > > >> eyes on this.
> > > >>
> > > >> Could I get a hand with a regression test run on an armhf environment
> > > >> while I fix my environment ?
> > > >>
> > > >> gcc/ChangeLog:
> > > >>
> > > >> PR target/92999
> > > >> *  config/arm/arm.c (aapcs_vfp_allocate_return_reg): Adjust to handle
> > > >> aggregates with elements smaller than SFmode.
> > > >>
> > > >> gcc/testsuite/ChangeLog:
> > > >>
> > > >> * gcc.target/arm/pr92999.c: New test.
> > > >>
> > > >>
> > > >> Thanks,
> > > >> Ramana
> > > >>
> > > >> Signed-off-by: Ramana Radhakrishnan 
> > > >
> > > > I'm not sure about this.  The AAPCS does not mention a base type of a
> > > > half-precision FP type as an appropriate homogeneous aggregate for using
> > > > VFP registers for either calling or returning.
> >
> > Ooh interesting, thanks for taking a look and poking at the AAPCS and
> > that's a good catch. BF16 should also have the same behaviour as FP16
> > , I suspect ?
>
> I suspect I got caught out by the definition of the Homogenous
> aggregate from Section 5.3.5
> ((https://github.com/ARM-software/abi-aa/blob/2982a9f3b512a5bfdc9e3fea5d3b298f9165c36b/aapcs32/aapcs32.rst#homogeneous-aggregates)
> which simply suggests it's an aggregate of fundamental types which
> lists half precision floating point .
>
> FTR, ideally I should have read 7.1.2.1
> https://github.com/ARM-software/abi-aa/blob/2982a9f3b512a5bfdc9e3fea5d3b298f9165c36b/aapcs32/aapcs32.rst#procedure-calling)
> :)
>
>
>
> >
> > > >
> > > > So perhaps the bug is that we try to treat this as a homogeneous
> > > > aggregate at all.
> >
> > Yep I agree - I'll take a look again tomorrow and see if I can get a fix.
> >
> > (And thanks Alex for the test run, I might trouble you again while I
> > still (slowly) get some of my boards back up)
>
>
> and as promised take 2. I'd really prefer another review on this one
> to see if I've not missed anything in the cases below.

Ping  ?

Ramana

>
> regards
> Ramana
>
>
> >
> > regards,
> > Ramana
> >
> >
> > >
> > > R.


Re: [PATCH][GCC] arm: Add support for new frame unwinding instruction "0xb5".

2022-11-17 Thread Ramana Radhakrishnan via Gcc-patches
On Thu, Nov 10, 2022 at 10:38 AM Srinath Parvathaneni via Gcc-patches
 wrote:
>
> Hi,
>
> This patch adds support for Arm frame unwinding instruction "0xb5" [1]. When
> an exception is taken and "0xb5" instruction is encounter during runtime
> stack-unwinding, we use effective vsp as modifier in pointer authentication.
> On completion of stack unwinding if "0xb5" instruction is not encountered
> then CFA will be used as modifier in pointer authentication.
>
> [1] 
> https://github.com/ARM-software/abi-aa/releases/download/2022Q3/ehabi32.pdf
>
> Regression tested on arm-none-eabi target and found no regressions.
>
> Ok for master?
>

No, not yet.

Presumably the logic to produce 0xb5 is in the source base and this
was tested with suitable options that produce said opcode ? I see no
logic in place to produce the said opcode in the backend in a quick
read as the pacbti patches still seem to be in review. ?

So what was the test suite run actually testing ?

regards
Ramana


> Regards,
> Srinath.
>
> gcc/ChangeLog:
>
> 2022-11-09  Srinath Parvathaneni  
>
> * libgcc/config/arm/pr-support.c (__gnu_unwind_execute): Decode opcode
> "0xb5".
>
>
> ### Attachment also inlined for ease of reply
> ###
>
>
> diff --git a/libgcc/config/arm/pr-support.c b/libgcc/config/arm/pr-support.c
> index 
> e48854587c667a959aa66ccc4982231f6ecc..73e4942a39b34a83c2da85def6b13e82ec501552
>  100644
> --- a/libgcc/config/arm/pr-support.c
> +++ b/libgcc/config/arm/pr-support.c
> @@ -107,7 +107,9 @@ __gnu_unwind_execute (_Unwind_Context * context, 
> __gnu_unwind_state * uws)
>_uw op;
>int set_pc;
>int set_pac = 0;
> +  int set_pac_sp = 0;
>_uw reg;
> +  _uw sp;
>
>set_pc = 0;
>for (;;)
> @@ -124,10 +126,11 @@ __gnu_unwind_execute (_Unwind_Context * context, 
> __gnu_unwind_state * uws)
>  #if defined(TARGET_HAVE_PACBTI)
>   if (set_pac)
> {
> - _uw sp;
>   _uw lr;
>   _uw pac;
> - _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, 
> &sp);
> + if (!set_pac_sp)
> +   _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32,
> +&sp);
>   _Unwind_VRS_Get (context, _UVRSC_CORE, R_LR, _UVRSD_UINT32, 
> &lr);
>   _Unwind_VRS_Get (context, _UVRSC_PAC, R_IP,
>_UVRSD_UINT32, &pac);
> @@ -259,7 +262,19 @@ __gnu_unwind_execute (_Unwind_Context * context, 
> __gnu_unwind_state * uws)
>   continue;
> }
>
> - if ((op & 0xfc) == 0xb4)  /* Obsolete FPA.  */
> + /* Use current VSP as modifier in PAC validation.  */
> + if (op == 0xb5)
> +   {
> + if (set_pac)
> +   _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32,
> +&sp);
> + else
> +   return _URC_FAILURE;
> + set_pac_sp = 1;
> + continue;
> +   }
> +
> + if ((op & 0xfd) == 0xb6)  /* Obsolete FPA.  */
> return _URC_FAILURE;
>
>   /* op & 0xf8 == 0xb8.  */
>
>
>


[PATCH] c++, v4: Implement C++23 P2647R1 - Permitting static constexpr variables in constexpr functions

2022-11-17 Thread Jakub Jelinek via Gcc-patches
On Thu, Nov 17, 2022 at 07:42:40PM +0100, Jakub Jelinek via Gcc-patches wrote:
> I thought for older C++ this is to catch
> void
> foo ()
> {
>   constexpr int a = ({ static constexpr int b = 2; b; });
> }
> and for C++23 the only 3 spots that diagnose those.
> But perhaps for C++20 or older we can check if the var has a context
> of a constexpr function (then assume cp_finish_decl errored or pedwarned
> already) and only error or pedwarn otherwise.

So, here is an updated patch, which in constexpr.cc will accept
DECL_EXPR of decl_*constant_var_p static/thread_local non-extern vars
for C++23 or if they are not declared in constexpr/consteval function.
So, the statement expression case will remain hard error for C++ <= 20 rather 
than
pedwarn, because due to the ctx->quiet vs. !ctx->quiet case I don't see
what else we could do, either something is a constant expression, or
it is not, but whether it is or is not shouldn't depend on
-Wpedantic/-Wno-pedantic/-Werror=pedantic.

2022-11-17  Jakub Jelinek  

gcc/c-family/
* c-cppbuiltin.cc (c_cpp_builtins): Bump __cpp_constexpr
value from 202207L to 202211L.
gcc/cp/
* constexpr.cc (cxx_eval_constant_expression): Implement C++23
P2647R1 - Permitting static constexpr variables in constexpr functions.
Allow decl_constant_var_p static or thread_local vars for
C++23 and later or if they are declared inside of constexpr or
consteval function.
(potential_constant_expression_1): Similarly, except use
decl_maybe_constant_var_p instead of decl_constant_var_p if
processing_template_decl.
* decl.cc (diagnose_static_in_constexpr): New function.
(start_decl): Remove diagnostics of static or thread_local
vars in constexpr or consteval functions.
(cp_finish_decl): Call diagnose_static_in_constexpr.
gcc/testsuite/
* g++.dg/cpp23/constexpr-nonlit17.C: New test.
* g++.dg/cpp23/constexpr-nonlit18.C: New test.
* g++.dg/cpp23/constexpr-nonlit19.C: New test.
* g++.dg/cpp23/constexpr-nonlit20.C: New test.
* g++.dg/cpp23/feat-cxx2b.C: Adjust expected __cpp_constexpr
value.
* g++.dg/ext/stmtexpr19.C: Don't expect an error for C++20 or later. 

--- gcc/c-family/c-cppbuiltin.cc.jj 2022-11-17 09:00:42.106249011 +0100
+++ gcc/c-family/c-cppbuiltin.cc2022-11-17 09:01:49.286320527 +0100
@@ -1074,7 +1074,7 @@ c_cpp_builtins (cpp_reader *pfile)
  /* Set feature test macros for C++23.  */
  cpp_define (pfile, "__cpp_size_t_suffix=202011L");
  cpp_define (pfile, "__cpp_if_consteval=202106L");
- cpp_define (pfile, "__cpp_constexpr=202207L");
+ cpp_define (pfile, "__cpp_constexpr=202211L");
  cpp_define (pfile, "__cpp_multidimensional_subscript=202211L");
  cpp_define (pfile, "__cpp_named_character_escapes=202207L");
  cpp_define (pfile, "__cpp_static_call_operator=202207L");
--- gcc/cp/constexpr.cc.jj  2022-11-17 08:48:30.530357181 +0100
+++ gcc/cp/constexpr.cc 2022-11-17 20:53:15.432408015 +0100
@@ -7100,17 +7100,35 @@ cxx_eval_constant_expression (const cons
/* Allow __FUNCTION__ etc.  */
&& !DECL_ARTIFICIAL (r))
  {
-   if (!ctx->quiet)
+   bool ok = decl_constant_var_p (r);
+   /* Since P2647R1 control can pass through definitions of static
+  or thread_local vars usable in constant expressions.
+  In C++20 or older, if such vars are declared inside of
+  constexpr or consteval function, diagnose_static_in_constexpr
+  should have already pedwarned on those.  Otherwise they could
+  be e.g. in a statement expression, reject those before
+  C++23.  */
+   if (ok && cxx_dialect < cxx23)
  {
-   if (CP_DECL_THREAD_LOCAL_P (r))
- error_at (loc, "control passes through definition of %qD "
-"with thread storage duration", r);
-   else
- error_at (loc, "control passes through definition of %qD "
-"with static storage duration", r);
+   tree fnctx = decl_function_context (r);
+   if (fnctx == NULL_TREE
+   || !DECL_DECLARED_CONSTEXPR_P (fnctx))
+ ok = false;
+ }
+   if (!ok)
+ {
+   if (!ctx->quiet)
+ {
+   if (CP_DECL_THREAD_LOCAL_P (r))
+ error_at (loc, "control passes through definition of "
+"%qD with thread storage duration", r);
+   else
+ error_at (loc, "control passes through definition of "
+"%qD with static storage duration", r);
+ }
+   *non_constant_p = true;
+   break;
  }
-

Re: [PATCH] [range-ops] Implement sqrt.

2022-11-17 Thread Joseph Myers
On Thu, 17 Nov 2022, Jakub Jelinek via Gcc-patches wrote:

> On Thu, Nov 17, 2022 at 06:59:45PM +, Joseph Myers wrote:
> > On Thu, 17 Nov 2022, Aldy Hernandez via Gcc-patches wrote:
> > 
> > > So... is the optimization wrong?  Are we not allowed to substitute
> > > that NAN if we know it's gonna happen?  Should we also allow F F F F F
> > > in the test?  Or something else?
> > 
> > This seems like the usual ambiguity about what transformations 
> > -ftrapping-math (on by default) is meant to prevent.
> > 
> > Generally it's understood to prevent transformations that add *or remove* 
> > exceptions, so folding a case that raises "invalid" to a NaN (with 
> > "invalid" no longer raised) is invalid with -ftrapping-math.  But that 
> > doesn't tend to be applied if the operation raising the exceptions has a 
> > result that is otherwise unused - in such a case the operation may still 
> > be removed completely (the exception isn't properly treated as a side 
> > effect to avoid dead code elimination; cf. Marc Glisse's -ffenv-access 
> > patches from August 2020).  And it may often also not be applied to 
> > "inexact".
> 
> The problem is that the above model I'm afraid is largely incompatible with
> the optimizations ranger provides.

That model is more an empirical description of when the nominal 
-ftrapping-math semantics tend to be respected, than a coherent design for 
any kind of API commitment to what the option does or what the default 
trapping-math rules are.

-- 
Joseph S. Myers
jos...@codesourcery.com


[PATCH] Fortran: reject NULL actual argument without explicit interface [PR107576]

2022-11-17 Thread Harald Anlauf via Gcc-patches
Dear all,

one cannot pass a NULL actual argument to a procedure without an
explicit interface.  This is detected and reported by NAG and Intel.
(Cray accepts this silently, and some other brands ICE.)

The testcase by Gerhard even tricked gfortran into inconsistent
behavior which could lead to an ICE with -fallow-argument-mismatch,
or silently accepting invalid code.

The solution is to reject such code, see attached patch.

Regtested on x86_64-pc-linux-gnu.  OK for mainline?

As this is marked as a regression which started at v7,
OK for backports to open branches?

Thanks,
Harald

From c6b19d662f51b1e2d2691e81cfeb68ad953a4c09 Mon Sep 17 00:00:00 2001
From: Harald Anlauf 
Date: Thu, 17 Nov 2022 21:36:49 +0100
Subject: [PATCH] Fortran: reject NULL actual argument without explicit
 interface [PR107576]

gcc/fortran/ChangeLog:

	PR fortran/107576
	* interface.cc (gfc_procedure_use): Reject NULL as actual argument
	when there is no explicit procedure interface.

gcc/testsuite/ChangeLog:

	PR fortran/107576
	* gfortran.dg/null_actual_3.f90: New test.
---
 gcc/fortran/interface.cc|  8 
 gcc/testsuite/gfortran.dg/null_actual_3.f90 | 18 ++
 2 files changed, 26 insertions(+)
 create mode 100644 gcc/testsuite/gfortran.dg/null_actual_3.f90

diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc
index 616ae2b1197..73799c175b7 100644
--- a/gcc/fortran/interface.cc
+++ b/gcc/fortran/interface.cc
@@ -4162,6 +4162,14 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
 	  return false;
 	}

+	  if (a->expr && a->expr->expr_type == EXPR_NULL)
+	{
+	  gfc_error ("Passing intrinsic NULL as actual argument at %L "
+			 "requires an explicit interface", &a->expr->where);
+	  a->expr->error = 1;
+	  return false;
+	}
+
 	  /* TS 29113, C407b.  */
 	  if (a->expr && a->expr->expr_type == EXPR_VARIABLE
 	  && symbol_rank (a->expr->symtree->n.sym) == -1)
diff --git a/gcc/testsuite/gfortran.dg/null_actual_3.f90 b/gcc/testsuite/gfortran.dg/null_actual_3.f90
new file mode 100644
index 000..ea49f9630c9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/null_actual_3.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-options "-fallow-argument-mismatch -w" }
+! PR fortran/107576
+! Contributed by G.Steinmetz
+
+program p
+  implicit none
+  interface
+ subroutine r(y)
+   integer, pointer :: y(:)
+ end subroutine r
+  end interface
+  integer, pointer :: z(:) => null()
+  call r(z)
+  call s(z)
+  call r(null(z))
+  call s(null(z)) ! { dg-error "requires an explicit interface" }
+end
--
2.35.3



  1   2   >