[COMMITTED 01/26] ada: Fix detection of suspicious loop patterns

2024-08-02 Thread Marc Poulhiès
From: Ronan Desplanques 

This patch fixes an assertion failure in some cases in the code to
warn about possible misuse of range attributes in loop. The root of
the problem is that this code failed to consider the case where the
outer loop is a while loop.

Also fix a typo in a nearby comment.

gcc/ada/

* sem_ch5.adb (Analyze_Loop_Statement): Fix loop pattern detection
code. Fix typo.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_ch5.adb | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index e4506036cc2..4db3a1a26ee 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -3967,7 +3967,7 @@ package body Sem_Ch5 is
   Push_Scope (Ent);
   Analyze_Iteration_Scheme (Iter);
 
-  --  Check for following case which merits a warning if the type E of is
+  --  Check for following case which merits a warning if the type of E is
   --  a multi-dimensional array (and no explicit subscript ranges present).
 
   --  for J in E'Range
@@ -3992,6 +3992,10 @@ package body Sem_Ch5 is
 and then Number_Dimensions (Typ) > 1
 and then Nkind (Parent (N)) = N_Loop_Statement
 and then Present (Iteration_Scheme (Parent (N)))
+  --  The next conjunct tests that the enclosing loop is
+  --  a for loop and not a while loop.
+and then Present (Loop_Parameter_Specification
+  (Iteration_Scheme (Parent (N
   then
  declare
 OIter : constant Node_Id :=
-- 
2.45.2



[COMMITTED 02/26] ada: Fix crash on expression function returning tagged type in nested package

2024-08-02 Thread Marc Poulhiès
From: Eric Botcazou 

This happens when the expression is a reference to a formal parameter of
the function, or a conditional expression with such a reference as one of
its dependent expressions, because the RM 6.5(8/5) subclause prescribes a
tag reassignment in this case, which requires freezing the tagged type in
the GNAT freezing model, although the language says there is no freezing.

In other words, it's another occurrence of the discrepancy between this
model tailored to Ada 95 and the freezing rules introduced in Ada 2012,
that is papered over by Should_Freeze_Type and the associated processing.

gcc/ada/

* exp_util.ads (Is_Conversion_Or_Reference_To_Formal): New
function declaration.
* exp_util.adb (Is_Conversion_Or_Reference_To_Formal): New
function body.
* exp_ch6.adb (Expand_Simple_Function_Return): Call the predicate
Is_Conversion_Or_Reference_To_Formal in order to decide whether a
tag check or reassignment is needed.
* freeze.adb (Should_Freeze_Type): Move declaration and body to
the appropriate places. Also return True for tagged results
subject to the expansion done in Expand_Simple_Function_Return
that is guarded by the predicate
Is_Conversion_Or_Reference_To_Formal.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_ch6.adb  |   9 +--
 gcc/ada/exp_util.adb |  16 
 gcc/ada/exp_util.ads |   4 +
 gcc/ada/freeze.adb   | 180 ++-
 4 files changed, 130 insertions(+), 79 deletions(-)

diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 548589284e2..9c182b2c6b4 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -6989,14 +6989,7 @@ package body Exp_Ch6 is
   if Present (Utyp)
 and then Is_Tagged_Type (Utyp)
 and then not Is_Class_Wide_Type (Utyp)
-and then (Nkind (Exp) in
-  N_Type_Conversion | N_Unchecked_Type_Conversion
-or else (Nkind (Exp) = N_Explicit_Dereference
-   and then Nkind (Prefix (Exp)) in
-  N_Type_Conversion |
-  N_Unchecked_Type_Conversion)
-or else (Is_Entity_Name (Exp)
-   and then Is_Formal (Entity (Exp
+and then Is_Conversion_Or_Reference_To_Formal (Exp)
   then
  --  When the return type is limited, perform a check that the tag of
  --  the result is the same as the tag of the return type.
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index de096ea752a..c5d3af7545e 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -8560,6 +8560,22 @@ package body Exp_Util is
   end if;
end Is_Captured_Function_Call;
 
+   --
+   -- Is_Conversion_Or_Reference_To_Formal --
+   --
+
+   function Is_Conversion_Or_Reference_To_Formal (N : Node_Id) return Boolean
+   is
+   begin
+  return Nkind (N) in N_Type_Conversion | N_Unchecked_Type_Conversion
+or else (Nkind (N) = N_Explicit_Dereference
+  and then Nkind (Prefix (N)) in N_Type_Conversion
+  |  N_Unchecked_Type_Conversion)
+or else (Is_Entity_Name (N)
+  and then Present (Entity (N))
+  and then Is_Formal (Entity (N)));
+   end Is_Conversion_Or_Reference_To_Formal;
+
--
-- Is_Finalizable_Transient --
--
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index c772d411bcf..7fbbe5fc9fd 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -769,6 +769,10 @@ package Exp_Util is
--Rnn : constant Ann := Func (...)'reference;
--Rnn.all
 
+   function Is_Conversion_Or_Reference_To_Formal (N : Node_Id) return Boolean;
+   --  Return True if N is a type conversion, or a dereference thereof, or a
+   --  reference to a formal parameter.
+
function Is_Finalizable_Transient
  (Decl : Node_Id;
   N: Node_Id) return Boolean;
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index cf7a22efcae..c8d20d020c7 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -185,77 +185,6 @@ package body Freeze is
--  the designated type. Otherwise freezing the access type does not freeze
--  the designated type.
 
-   function Should_Freeze_Type
- (Typ : Entity_Id; E : Entity_Id; N : Node_Id) return Boolean;
-   --  If Typ is in the current scope, then return True.
-   --  N is a node whose source location corresponds to the freeze point.
-   --  ??? Expression functions (represented by E) shouldn't freeze types in
-   --  general, but our current expansion and freezing model requires an early
-   --  freezing when the dispatch table is needed or when building an aggregate
-   --  with a su

[COMMITTED 04/26] ada: Improve documenation about security of PRGNs

2024-08-02 Thread Marc Poulhiès
From: Johannes Kliemann 

The pseudo random number generators used in GNAT are not
suitable for applications that require cryptographic
security. While this was mentioned in some places others
did not have a corresponding note, leading to these
generators being used in a non-suitable context.

gcc/ada/

* doc/gnat_rm/standard_library_routines.rst: Add note to section
of Ada.Numerics.Discrete_Random and Ada.Numerics.Float_Random.
* doc/gnat_rm/the_gnat_library.rst: Add note to section about
GNAT.Random_Numbers.
* libgnat/a-nudira.ads: Add note about cryptographic properties.
* gnat_rm.texi: Regenerate.
* gnat_ugn.texi: Regenerate.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/doc/gnat_rm/standard_library_routines.rst |  6 --
 gcc/ada/doc/gnat_rm/the_gnat_library.rst  |  4 +++-
 gcc/ada/gnat_rm.texi  | 10 +++---
 gcc/ada/gnat_ugn.texi |  2 +-
 gcc/ada/libgnat/a-nudira.ads  |  2 ++
 5 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/gcc/ada/doc/gnat_rm/standard_library_routines.rst 
b/gcc/ada/doc/gnat_rm/standard_library_routines.rst
index 27659a40463..2e7642652b2 100644
--- a/gcc/ada/doc/gnat_rm/standard_library_routines.rst
+++ b/gcc/ada/doc/gnat_rm/standard_library_routines.rst
@@ -302,12 +302,14 @@ the unit is not implemented.
 
 ``Ada.Numerics.Discrete_Random``
   This generic package provides a random number generator suitable for 
generating
-  uniformly distributed values of a specified discrete subtype.
+  uniformly distributed values of a specified discrete subtype. It should not 
be
+  used as a cryptographic pseudo-random source.
 
 
 ``Ada.Numerics.Float_Random``
   This package provides a random number generator suitable for generating
-  uniformly distributed floating point values in the unit interval.
+  uniformly distributed floating point values in the unit interval. It should 
not
+  be used as a cryptographic pseudo-random source.
 
 
 ``Ada.Numerics.Generic_Complex_Elementary_Functions``
diff --git a/gcc/ada/doc/gnat_rm/the_gnat_library.rst 
b/gcc/ada/doc/gnat_rm/the_gnat_library.rst
index 88204d4cfe7..ac45b5eb7af 100644
--- a/gcc/ada/doc/gnat_rm/the_gnat_library.rst
+++ b/gcc/ada/doc/gnat_rm/the_gnat_library.rst
@@ -1329,7 +1329,9 @@ convenient for use with realtime applications.
 .. index:: Random number generation
 
 Provides random number capabilities which extend those available in the
-standard Ada library and are more convenient to use.
+standard Ada library and are more convenient to use. This package is
+however NOT suitable for situations requiring cryptographically secure
+randomness.
 
 .. _`GNAT.Regexp_(g-regexp.ads)`:
 
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index d15d6204cd8..d6e2f265ab9 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -21142,12 +21142,14 @@ build the type @code{Complex} and @code{Imaginary}.
 @item @code{Ada.Numerics.Discrete_Random}
 
 This generic package provides a random number generator suitable for generating
-uniformly distributed values of a specified discrete subtype.
+uniformly distributed values of a specified discrete subtype. It should not be
+used as a cryptographic pseudo-random source.
 
 @item @code{Ada.Numerics.Float_Random}
 
 This package provides a random number generator suitable for generating
-uniformly distributed floating point values in the unit interval.
+uniformly distributed floating point values in the unit interval. It should not
+be used as a cryptographic pseudo-random source.
 
 @item @code{Ada.Numerics.Generic_Complex_Elementary_Functions}
 
@@ -24688,7 +24690,9 @@ convenient for use with realtime applications.
 @geindex Random number generation
 
 Provides random number capabilities which extend those available in the
-standard Ada library and are more convenient to use.
+standard Ada library and are more convenient to use. This package is
+however NOT suitable for situations requiring cryptographically secure
+randomness.
 
 @node GNAT Regexp g-regexp ads,GNAT Registry g-regist ads,GNAT Random_Numbers 
g-rannum ads,The GNAT Library
 @anchor{gnat_rm/the_gnat_library 
gnat-regexp-g-regexp-ads}@anchor{270}@anchor{gnat_rm/the_gnat_library 
id90}@anchor{39b}
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index 0e3ee935552..ea1d2f9d71a 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -29670,8 +29670,8 @@ to permit their use in free software.
 
 @printindex ge
 
-@anchor{d1}@w{  }
 @anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{   
   }
+@anchor{d1}@w{  }
 
 @c %**end of body
 @bye
diff --git a/gcc/ada/libgnat/a-nudira.ads b/gcc/ada/libgnat/a-nudira.ads
index 1b3eacb897d..c6d95731821 100644
--- a/gcc/ada/libgnat/a-nudira.ads
+++ b/gcc/ada/libgnat/a-nudira.ads
@@ -35,6 +35,8 @@
 

[COMMITTED 03/26] ada: Fix layout of GNAT reference manual section

2024-08-02 Thread Marc Poulhiès
From: Ronan Desplanques 

gcc/ada/

* doc/gnat_rm/gnat_language_extensions.rst: Fix layout of section.
* gnat_rm.texi: Regenerate.
* gnat_ugn.texi: Regenerate.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/doc/gnat_rm/gnat_language_extensions.rst | 5 +++--
 gcc/ada/gnat_rm.texi | 5 +++--
 gcc/ada/gnat_ugn.texi| 2 +-
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst 
b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst
index 0f001c4aca9..efda4afb742 100644
--- a/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst
+++ b/gcc/ada/doc/gnat_rm/gnat_language_extensions.rst
@@ -53,8 +53,6 @@ A basic_declarative_item may appear at the place of any 
statement.
 This avoids the heavy syntax of block_statements just to declare
 something locally.
 
-Link to the original RFC:
-https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-local-vars-without-block.md
 For example:
 
 .. code-block:: ada
@@ -67,6 +65,9 @@ For example:
   X := X + Squared;
end if;
 
+Link to the original RFC:
+https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-local-vars-without-block.md
+
 Conditional when constructs
 ---
 
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index b27bd627c17..d15d6204cd8 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -28850,8 +28850,6 @@ A basic_declarative_item may appear at the place of any 
statement.
 This avoids the heavy syntax of block_statements just to declare
 something locally.
 
-Link to the original RFC:
-@indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-local-vars-without-block.md}
 For example:
 
 @example
@@ -28864,6 +28862,9 @@ if X > 5 then
 end if;
 @end example
 
+Link to the original RFC:
+@indicateurl{https://github.com/AdaCore/ada-spark-rfcs/blob/master/prototyped/rfc-local-vars-without-block.md}
+
 @node Conditional when constructs,Fixed lower bounds for array types and 
subtypes,Local Declarations Without Block,Curated Extensions
 @anchor{gnat_rm/gnat_language_extensions 
conditional-when-constructs}@anchor{443}
 @subsection Conditional when constructs
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index ea1d2f9d71a..0e3ee935552 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -29670,8 +29670,8 @@ to permit their use in free software.
 
 @printindex ge
 
-@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{   
   }
 @anchor{d1}@w{  }
+@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{   
   }
 
 @c %**end of body
 @bye
-- 
2.45.2



[COMMITTED 14/26] ada: Clean up handling of inlining of finalizer procedures

2024-08-02 Thread Marc Poulhiès
From: Richard Kenner 

Change Is_Finalizer from synthesized attribute into flag. Remove duplicate
Is_Finalizer_Proc. Add new Try_Inline_Always for backend usage.

gcc/ada/

* einfo-utils.ads (Is_Finalizer): Delete.
* einfo-utils.adb (Is_Finalizer): Delete.
* einfo.ads: Adjust comment.
* gen_il-fields.ads, gen_il-gen-gen_entities.adb: Add Is_Finalizer
flag.
* exp_ch3.adb (Build_Init_Procedure): Set it.
* exp_ch7.adb (Create_Finalizer): Likewise.
* exp_util.adb (Try_Inline_Always): New function.
* exp_util.ads (Try_Inline_Always): New function.
* sem_elab.adb (Is_Finalizer_Proc): Replace with Is_Finalizer.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/einfo-utils.adb |  9 -
 gcc/ada/einfo-utils.ads |  1 -
 gcc/ada/einfo.ads   |  2 +-
 gcc/ada/exp_ch3.adb |  1 +
 gcc/ada/exp_ch7.adb |  1 +
 gcc/ada/exp_util.adb| 10 ++
 gcc/ada/exp_util.ads|  5 +
 gcc/ada/gen_il-fields.ads   |  1 +
 gcc/ada/gen_il-gen-gen_entities.adb |  1 +
 gcc/ada/sem_elab.adb| 26 +-
 10 files changed, 25 insertions(+), 32 deletions(-)

diff --git a/gcc/ada/einfo-utils.adb b/gcc/ada/einfo-utils.adb
index c0c79f92e13..3dc25b36ad4 100644
--- a/gcc/ada/einfo-utils.adb
+++ b/gcc/ada/einfo-utils.adb
@@ -1567,15 +1567,6 @@ package body Einfo.Utils is
 Has_Option (Id, Name_Synchronous));
end Is_External_State;
 
-   --
-   -- Is_Finalizer --
-   --
-
-   function Is_Finalizer (Id : E) return B is
-   begin
-  return Ekind (Id) = E_Procedure and then Chars (Id) = Name_uFinalizer;
-   end Is_Finalizer;
-
--
-- Is_Full_Access --
--
diff --git a/gcc/ada/einfo-utils.ads b/gcc/ada/einfo-utils.ads
index 8207576fb89..c0480c71cb8 100644
--- a/gcc/ada/einfo-utils.ads
+++ b/gcc/ada/einfo-utils.ads
@@ -190,7 +190,6 @@ package Einfo.Utils is
function Is_Dynamic_Scope (Id : E) return B;
function Is_Elaboration_Target (Id : E) return B;
function Is_External_State (Id : E) return B;
-   function Is_Finalizer (Id : E) return B with Inline;
function Is_Full_Access (Id : E) return B with Inline;
function Is_Null_State (Id : E) return B;
function Is_Package_Or_Generic_Package (Id : E) return B with Inline;
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index 9d0f2ee3c02..4486ab3636f 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -2647,7 +2647,7 @@ package Einfo is
 --   the transient finalization mechanisms. The flag prevents the double
 --   finalization of the object.
 
---Is_Finalizer (synthesized)
+--Is_Finalizer
 --   Applies to all entities, true for procedures containing finalization
 --   code to process local or library level objects.
 
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 6fee2b41bac..bf04ea9d70a 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -3532,6 +3532,7 @@ package body Exp_Ch3 is
DF_Id :=
  Make_Defining_Identifier (Loc,
Chars => New_External_Name (Name_uFinalizer));
+   Set_Is_Finalizer (DF_Id);
 
Append_To (Decls, Make_Local_Deep_Finalize (Rec_Type, DF_Id));
 
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index b545a58448d..72f0b539c2e 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -1979,6 +1979,7 @@ package body Exp_Ch7 is
 Fin_Id :=
   Make_Defining_Identifier (Loc,
 Chars => New_External_Name (Name_uFinalizer));
+Set_Is_Finalizer (Fin_Id);
 
 --  The visibility semantics of At_End handlers force a strange
 --  separation of spec and body for stack-related finalizers:
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index c5d3af7545e..bd8bbb39d9c 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -14525,6 +14525,16 @@ package body Exp_Util is
   return Target;
end Thunk_Target;
 
+   ---
+   -- Try_Inline_Always --
+   ---
+
+   function Try_Inline_Always (Subp : Entity_Id) return Boolean is
+ ((Is_Expression_Function (Subp) or else Is_Finalizer (Subp))
+   and then not Debug_Flag_Dot_8);
+   --  We want to inline expression functions and finalizers as much as
+   --  practical unless -gnatd.8.
+
---
-- Type_Map_Hash --
---
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index 7fbbe5fc9fd..14d9e345b53 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -1260,6 +1260,11 @@ package Exp_Util is
 
--  WARNING: There is a matching C declaration of this subprogram in fe.h
 
+   function Try_Inline_Always (Subp : Entity_Id) return Boolean;
+   --  Determines

[COMMITTED 06/26] ada: Type conversion in instance incorrectly rejected.

2024-08-02 Thread Marc Poulhiès
From: Steve Baird 

In some cases, a legal type conversion in a generic package is correctly
accepted but the corresponding type conversion in an instance of the generic
is incorrectly rejected.

gcc/ada/

* sem_res.adb (Valid_Conversion): Test In_Instance instead of
In_Instance_Body.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_res.adb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 8a18430ff58..9a3b6ddbb53 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -14697,7 +14697,7 @@ package body Sem_Res is
 
   --  If it was legal in the generic, it's legal in the instance
 
-  elsif In_Instance_Body then
+  elsif In_Instance then
  return True;
 
   --  Ignore privacy for streaming or Put_Image routines
-- 
2.45.2



[COMMITTED 07/26] ada: Reject illegal uses of type/subtype current instance

2024-08-02 Thread Marc Poulhiès
From: Steve Baird 

The current instance of a type or subtype (see RM 8.6) is an object or
value, not a type or subtype. So a name denoting such a current instance is
illegal in any context that requires a name denoting a type or subtype.
In some cases this error was not detected.

gcc/ada/

* sem_ch8.adb (Find_Type): If Is_Current_Instance returns True for
N (and Comes_From_Source (N) is also True) then flag an error.
Call Is_Current_Instance (twice) instead of duplicating (twice)
N_Access_Definition-related code in Is_Current_Instance.
* sem_util.adb (Is_Current_Instance): Implement
access-type-related clauses of the RM 8.6 current instance rule.
For pragmas Predicate and Predicate_Failure, distinguish between
the first and subsequent pragma arguments.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_ch8.adb  | 24 ++--
 gcc/ada/sem_util.adb | 31 ++-
 2 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index d2752af320e..c77a69e5118 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -8801,6 +8801,16 @@ package body Sem_Ch8 is
 Error_Msg_NE ("\\found & declared#", N, T_Name);
 Set_Entity (N, Any_Type);
 
+ elsif Is_Current_Instance (N) and then Comes_From_Source (N) then
+if Nkind (Parent (T_Name)) = N_Subtype_Declaration then
+   Error_Msg_N ("reference to current instance of subtype" &
+" does not denote a subtype (RM 8.6)", N);
+else
+   Error_Msg_N ("reference to current instance of type" &
+" does not denote a type (RM 8.6)", N);
+end if;
+Set_Entity (N, Any_Type);
+
  else
 --  If the type is an incomplete type created to handle
 --  anonymous access components of a record type, then the
@@ -8831,12 +8841,9 @@ package body Sem_Ch8 is
 if In_Open_Scopes (T_Name) then
if Ekind (Base_Type (T_Name)) = E_Task_Type then
 
-  --  In Ada 2005, a task name can be used in an access
-  --  definition within its own body.
+  --  OK if the "current instance" rule does not apply.
 
-  if Ada_Version >= Ada_2005
-and then Nkind (Parent (N)) = N_Access_Definition
-  then
+  if not Is_Current_Instance (N) then
  Set_Entity (N, T_Name);
  Set_Etype  (N, T_Name);
  return;
@@ -8849,12 +8856,9 @@ package body Sem_Ch8 is
 
elsif Ekind (Base_Type (T_Name)) = E_Protected_Type then
 
-  --  In Ada 2005, a protected name can be used in an access
-  --  definition within its own body.
+  --  OK if the "current instance" rule does not apply.
 
-  if Ada_Version >= Ada_2005
-and then Nkind (Parent (N)) = N_Access_Definition
-  then
+  if not Is_Current_Instance (N) then
  Set_Entity (N, T_Name);
  Set_Etype  (N, T_Name);
  return;
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 032684f3ddb..7901eb8ee38 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -16080,6 +16080,29 @@ package body Sem_Util is
   P   : Node_Id;
 
begin
+  --  Since Ada 2005, the "current instance" rule does not apply
+  --  to a type_mark in an access_definition (RM 8.6),
+  --  although it does apply in an access_to_object definition.
+  --  So the rule does not apply in the definition of an anonymous
+  --  access type, but it does apply in the definition of a named
+  --  access-to-object type.
+  --  The rule also does not apply in a designated subprogram profile.
+
+  if Ada_Version >= Ada_2005 then
+ case Nkind (Parent (N)) is
+when N_Access_Definition | N_Access_Function_Definition =>
+   return False;
+when N_Parameter_Specification =>
+   if Nkind (Parent (Parent (N))) in
+ N_Access_To_Subprogram_Definition
+   then
+  return False;
+   end if;
+when others =>
+   null;
+ end case;
+  end if;
+
   --  Simplest case: entity is a concurrent type and we are currently
   --  inside the body. This will eventually be expanded into a call to
   --  Self (for tasks) or _object (for protected objects).
@@ -16129,6 +16152,12 @@ package body Sem_Util is
 elsif Nkind (P) = N_Pragma
   and then Get_Pragma_Id (P) in Pragma_Predicate
   | Pragma_Predicate_Failure
+
+  --  For "pragma Predica

[COMMITTED 12/26] ada: Update doc of Style_Checks pragma

2024-08-02 Thread Marc Poulhiès
From: Tonu Naks 

gcc/ada/

* doc/gnat_rm/implementation_defined_pragmas.rst: Add examples.
* gnat_rm.texi: Regenerate.
* gnat_ugn.texi: Regenerate.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 .../implementation_defined_pragmas.rst| 79 +--
 gcc/ada/gnat_rm.texi  | 77 +-
 gcc/ada/gnat_ugn.texi |  2 +-
 3 files changed, 150 insertions(+), 8 deletions(-)

diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst 
b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
index 926c5f4e37b..7ff94c4c2b9 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
@@ -6328,21 +6328,91 @@ activated.  These are additive, so they apply in 
addition to any previously
 set style check options.  The codes for the options are the same as those
 used in the *-gnaty* switch to *gcc* or *gnatmake*.
 For example the following two methods can be used to enable
-layout checking:
+layout checking and to change the maximum nesting level value:
 
 *
 
-  ::
+  .. code-block:: ada
 
+--  switch on layout checks
 pragma Style_Checks ("l");
-
+--  set the number of maximum allowed nesting levels to 15
+pragma Style_Checks ("L15");
 
 *
 
   ::
 
-gcc -c -gnatyl ...
+gcc -c -gnatyl -gnatyL15 ...
+
+
+The string literal values can be cumulatively switched on and off by prefixing
+the value with ``+`` or ``-``, where:
+
+* ``+`` is equivalent to no prefix. It applies the check referenced by the
+  literal value;
+* ``-`` switches the referenced check off.
+
+
+.. code-block:: ada
+  :linenos:
+  :emphasize-lines: 15
+
+  --  allow misaligned block by disabling layout check
+  pragma Style_Checks ("-l");
+  declare
+  msg : constant String := "Hello";
+  begin
+  Put_Line (msg);
+  end;
+
+  --  enable the layout check again
+  pragma Style_Checks ("l");
+  declare
+  msg : constant String := "Hello";
+  begin
+  Put_Line (msg);
+  end;
+
+The code above contains two layout errors, however, only
+the last line is picked up by the compiler.
+
+Similarly, the switches containing a numeric value can be applied in sequence.
+In the example below, the permitted nesting level is reduced in in the middle
+block and the compiler raises a warning on the highlighted line.
 
+.. code-block:: ada
+  :linenos:
+  :emphasize-lines: 15
+
+  -- Permit 3 levels of nesting
+  pragma Style_Checks ("L3");
+
+  procedure Main is
+  begin
+  if True then
+if True then
+null;
+end if;
+  end if;
+  --  Reduce permitted nesting levels to 2.
+  --  Note that "+L2" and "L2" are equivalent.
+  pragma Style_Checks ("+L2");
+  if True then
+if True then
+null;
+end if;
+  end if;
+  --  Disable checking permitted nesting levels.
+  --  Note that the number after "-L" is insignificant,
+  --  "-L", "-L3" and "-Lx" are all equivalent.
+  pragma Style_Checks ("-L3");
+  if True then
+if True then
+null;
+end if;
+  end if;
+  end Main;
 
 The form ``ALL_CHECKS`` activates all standard checks (its use is equivalent
 to the use of the :switch:`gnaty` switch with no options.
@@ -6356,7 +6426,6 @@ The forms with ``Off`` and ``On``
 can be used to temporarily disable style checks
 as shown in the following example:
 
-
 .. code-block:: ada
 
   pragma Style_Checks ("k"); -- requires keywords in lower case
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index d5e8931e088..3a766ccc38d 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -7901,22 +7901,95 @@ activated.  These are additive, so they apply in 
addition to any previously
 set style check options.  The codes for the options are the same as those
 used in the `-gnaty' switch to `gcc' or `gnatmake'.
 For example the following two methods can be used to enable
-layout checking:
+layout checking and to change the maximum nesting level value:
 
 
 @itemize *
 
 @item 
 @example
+--  switch on layout checks
 pragma Style_Checks ("l");
+--  set the number of maximum allowed nesting levels to 15
+pragma Style_Checks ("L15");
 @end example
 
 @item 
 @example
-gcc -c -gnatyl ...
+gcc -c -gnatyl -gnatyL15 ...
 @end example
 @end itemize
 
+The string literal values can be cumulatively switched on and off by prefixing
+the value with @code{+} or @code{-}, where:
+
+
+@itemize *
+
+@item 
+@code{+} is equivalent to no prefix. It applies the check referenced by the
+literal value;
+
+@item 
+@code{-} switches the referenced check off.
+@end itemize
+
+@example
+--  allow misaligned block by disabling layout check
+pragma Style_Checks ("-l");
+declare
+msg : constant String := "Hello";
+begin
+Put_Line (msg);
+end;
+
+--  enable the layout check again
+pragma Style_Checks ("l");
+declare
+msg : constant String 

[COMMITTED 08/26] ada: Fix handling reference warnings with slices

2024-08-02 Thread Marc Poulhiès
From: Viljar Indus 

gcc/ada/

* sem_util.adb (Set_Referenced_Modified): Set referenced as LHS
for the prefixes of array slices.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_util.adb | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 7901eb8ee38..7b575c09c30 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -27787,9 +27787,10 @@ package body Sem_Util is
   Pref : Node_Id;
 
begin
-  --  Deal with indexed or selected component where prefix is modified
+  --  Deal with indexed components, selected components, or slices where
+  --  the prefix is modified.
 
-  if Nkind (N) in N_Indexed_Component | N_Selected_Component then
+  if Nkind (N) in N_Indexed_Component | N_Selected_Component | N_Slice then
 
  --  Grab the original node to avoid looking at internally generated
  --  objects.
-- 
2.45.2



[COMMITTED 19/26] ada: Plug loophole in handling of No_Raise pragma

2024-08-02 Thread Marc Poulhiès
From: Eric Botcazou 

Unlike the aspect, the pragma needs to be propagated explicitly from a
generic subprogram to its instances.

gcc/ada/

* sem_ch12.adb (Analyze_Subprogram_Instantiation): Propagate the
No_Raise flag like the No_Return flag.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_ch12.adb | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index 6b98343aeeb..25821cb7695 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -6069,9 +6069,16 @@ package body Sem_Ch12 is
  Set_Has_Pragma_No_Inline
(Anon_Id, Has_Pragma_No_Inline (Gen_Unit));
 
- --  Propagate No_Return if pragma applied to generic unit. This must
- --  be done explicitly because pragma does not appear in generic
- --  declaration (unlike the aspect case).
+ --  Propagate No_Raise if pragma applied to generic unit. This must
+ --  be done explicitly because the pragma does not appear in generic
+ --  declarations (unlike the aspect).
+
+ if No_Raise (Gen_Unit) then
+Set_No_Raise (Act_Decl_Id);
+Set_No_Raise (Anon_Id);
+ end if;
+
+ --  Likewise for No_Return
 
  if No_Return (Gen_Unit) then
 Set_No_Return (Act_Decl_Id);
-- 
2.45.2



[COMMITTED 09/26] ada: Finish up support for relaxed finalization

2024-08-02 Thread Marc Poulhiès
From: Eric Botcazou 

This adds a variant of the System.Finalization_Primitives unit that supports
only controlled types with relaxed finalization, and adds the description of
its implementation to Exp_Ch7.

gcc/ada/

* exp_ch7.adb (Relaxed Finalization): New paragraph in head
comment.
* sem_ch13.adb (Validate_Finalizable_Aspect): Give an error
message if strict finalization is required but not supported by
the runtime.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_ch7.adb  | 58 
 gcc/ada/sem_ch13.adb | 18 +++---
 2 files changed, 72 insertions(+), 4 deletions(-)

diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 044b14ad305..b545a58448d 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -337,6 +337,64 @@ package body Exp_Ch7 is
--  directly by the compiler during the expansion of allocators and calls to
--  instances of the Unchecked_Deallocation procedure.
 
+   --
+   -- Relaxed Finalization --
+   --
+
+   --  This paragraph describes the differences between the implementation of
+   --  finalization as specified by the Ada RM (called "strict" and documented
+   --  in the previous paragraph) and that of finalization as specified by the
+   --  GNAT RM (called "relaxed") for a second category of controlled objects.
+
+   --  For objects (statically) declared in a scope, the default implementation
+   --  documented in the previous paragraph is used for the scope as a whole as
+   --  soon as one controlled object with strict finalization is present in it,
+   --  including one transient controlled object. Otherwise, that is to say, if
+   --  all the controlled objects in the scope have relaxed finalization, then
+   --  no Finalization_Master is built for this scope, and all the objects are
+   --  finalized explicitly in the reverse order of their creation:
+
+   --declare
+   --   X : Ctrl := Init;
+   --   Y : Ctrl := Init;
+
+   --begin
+   --   null;
+   --end;
+
+   --  is expanded into:
+
+   --declare
+   --   XMN : aliased System.Finalization_Primitives.Master_Node;
+   --   X : Ctrl := Init;
+   --   System.Finalization_Primitives.Attach_To_Node
+   -- (X'address,
+   --  CtrlFD'unrestricted_access,
+   --  XMN'unrestricted_access);
+   --   YMN : aliased System.Finalization_Primitives.Master_Node;
+   --   Y : Ctrl := Init;
+   --   System.Finalization_Primitives.Attach_To_Node
+   -- (Y'address,
+   --  CtrlFD'unrestricted_access,
+   --  YMN'unrestricted_access);
+
+   --   procedure _Finalizer is
+   --   begin
+   --  Abort_Defer;
+   --  System.Finalization_Primitives.Finalize_Object (YMN);
+   --  System.Finalization_Primitives.Finalize_Object (XMN);
+   --  Abort_Undefer;
+   --   end _Finalizer;
+
+   --begin
+   --   null;
+   --end;
+   --at end
+   --   _Finalizer;
+
+   --  Dynamically allocated objects with relaxed finalization need not be
+   --  finalized and, therefore, are not attached to any finalization chain.
+
type Final_Primitives is
  (Initialize_Case, Adjust_Case, Finalize_Case, Address_Case);
--  This enumeration type is defined in order to ease sharing code for
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 55b0a7a5ccf..3fb0209f612 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -17907,9 +17907,10 @@ package body Sem_Ch13 is
   --  If Relaxed_Finalization is set, the Finalize and Adjust procedures
   --  are considered as having the No_Raise aspect specified.
 
-  if Has_Relaxed_Finalization (Typ)
-and then Serious_Errors_Detected = 0
-  then
+  if Serious_Errors_Detected > 0 then
+ null;
+
+  elsif Has_Relaxed_Finalization (Typ) then
  Assoc := First (Component_Associations (Aggr));
  while Present (Assoc) loop
 Nam := First (Choices (Assoc));
@@ -17922,8 +17923,17 @@ package body Sem_Ch13 is
 
 Next (Assoc);
  end loop;
-  end if;
 
+  --  If Relaxed_Finalization is not set, then check that the support for
+  --  strict finalization is available in the runtime library.
+
+  elsif not In_Predefined_Unit (Cunit (Get_Source_Unit (Typ)))
+and then not RTE_Available (RE_Finalization_Master)
+  then
+ Error_Msg_N
+   ("only Relaxed Finalization is supported in this configuration",
+ASN);
+  end if;
end Validate_Finalizable_Aspect;
 
--
-- 
2.45.2



[COMMITTED 16/26] ada: Ensure variable is initialized before use

2024-08-02 Thread Marc Poulhiès
From: Ronan Desplanques 

This patch is motivated by a GNAT SAS report.

gcc/ada/

* scng.adb (Slit): Initialize object in uncommon path.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/scng.adb | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/ada/scng.adb b/gcc/ada/scng.adb
index c9ccc4d9b52..08ce2ab5ad1 100644
--- a/gcc/ada/scng.adb
+++ b/gcc/ada/scng.adb
@@ -1166,6 +1166,7 @@ package body Scng is
  when '\' | '"' | '{' | '}'
   => Code := Get_Char_Code (C);
  when others =>
+Code := Get_Char_Code ('?');
 Error_Msg_S ("illegal escaped character");
   end case;
 
-- 
2.45.2



[COMMITTED 13/26] ada: Add leap second support to conversion of Unix_Time

2024-08-02 Thread Marc Poulhiès
From: Tonu Naks 

Unix timestamp jumps one second back when a leap second
is applied and doesn't count cumulative leap seconds.
This was not taken into account in conversions between
Unix time and Ada time. Now fixed.

gcc/ada/

* libgnat/a-calend.adb: Modify unix time handling.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/libgnat/a-calend.adb | 135 ++-
 1 file changed, 70 insertions(+), 65 deletions(-)

diff --git a/gcc/ada/libgnat/a-calend.adb b/gcc/ada/libgnat/a-calend.adb
index 1083ece44d2..c28042d13c4 100644
--- a/gcc/ada/libgnat/a-calend.adb
+++ b/gcc/ada/libgnat/a-calend.adb
@@ -110,6 +110,17 @@ is
  new Ada.Unchecked_Conversion (Duration, Time_Rep);
--  Convert a duration value into a time representation value
 
+   function Elapsed_Leaps (Start_Time, End_Time : Time_Rep) return Natural
+  with Pre => (End_Time >= Start_Time);
+   --  If the target supports leap seconds, determine the number of leap
+   --  seconds elapsed between start_time and end_time.
+   --
+   --  NB! This function assumes that End_Time is not smaller than
+   --  Start_Time. There are usages of the function that correct the time
+   --  by passed leap seconds and use the results for another seach.
+   --  If negative leap seconds are introduced eventually, then such
+   --  calls should be revised as the correction can go to either direction.
+
function Time_Rep_To_Duration is
  new Ada.Unchecked_Conversion (Time_Rep, Duration);
--  Convert a time representation value into a duration value
@@ -355,13 +366,34 @@ is
   end if;
end Check_Within_Time_Bounds;
 
+   ---
+   -- Elapsed_Leaps --
+   ---
+
+   function Elapsed_Leaps (Start_Time, End_Time : Time_Rep) return Natural
+   is
+  Elapsed   : Natural := 0;
+  Next_Leap_N   : Time_Rep;
+   begin
+  if Leap_Support then
+ Cumulative_Leap_Seconds
+   (Start_Time, End_Time, Elapsed, Next_Leap_N);
+
+ --  The system clock may fall exactly on a leap second
+
+ if End_Time >= Next_Leap_N then
+Elapsed := Elapsed + 1;
+ end if;
+  end if;
+
+  return Elapsed;
+   end Elapsed_Leaps;
+
---
-- Clock --
---
 
function Clock return Time is
-  Elapsed_Leaps : Natural;
-  Next_Leap_N   : Time_Rep;
 
   --  The system clock returns the time in UTC since the Unix Epoch of
   --  1970-01-01 00:00:00.0. We perform an origin shift to the Ada Epoch
@@ -371,26 +403,7 @@ is
 Duration_To_Time_Rep (System.OS_Primitives.Clock) + Unix_Min;
 
begin
-  --  If the target supports leap seconds, determine the number of leap
-  --  seconds elapsed until this moment.
-
-  if Leap_Support then
- Cumulative_Leap_Seconds
-   (Start_Of_Time, Res_N, Elapsed_Leaps, Next_Leap_N);
-
- --  The system clock may fall exactly on a leap second
-
- if Res_N >= Next_Leap_N then
-Elapsed_Leaps := Elapsed_Leaps + 1;
- end if;
-
-  --  The target does not support leap seconds
-
-  else
- Elapsed_Leaps := 0;
-  end if;
-
-  Res_N := Res_N + Time_Rep (Elapsed_Leaps) * Nano;
+  Res_N := Res_N + Time_Rep (Elapsed_Leaps (Start_Of_Time, Res_N)) * Nano;
 
   return Time (Res_N);
end Clock;
@@ -806,10 +819,8 @@ is
   is
  Res_Dur   : Time_Dur;
  Earlier   : Time_Rep;
- Elapsed_Leaps : Natural;
  Later : Time_Rep;
  Negate: Boolean := False;
- Next_Leap_N   : Time_Rep;
  Sub_Secs  : Duration;
  Sub_Secs_Diff : Time_Rep;
 
@@ -825,22 +836,6 @@ is
 Negate  := True;
  end if;
 
- --  If the target supports leap seconds, process them
-
- if Leap_Support then
-Cumulative_Leap_Seconds
-  (Earlier, Later, Elapsed_Leaps, Next_Leap_N);
-
-if Later >= Next_Leap_N then
-   Elapsed_Leaps := Elapsed_Leaps + 1;
-end if;
-
- --  The target does not support leap seconds
-
- else
-Elapsed_Leaps := 0;
- end if;
-
  --  Sub seconds processing. We add the resulting difference to one
  --  of the input dates in order to account for any potential rounding
  --  of the difference in the next step.
@@ -856,12 +851,14 @@ is
  --  either add or drop a second. We compensate for this issue in the
  --  previous step.
 
+ Leap_Seconds := Elapsed_Leaps (Earlier, Later);
+
  Res_Dur :=
-   Time_Dur (Later / Nano - Earlier / Nano) - Time_Dur (Elapsed_Leaps);
+   Time_Dur (Later / Nano - Earlier / Nano) -
+   Time_Dur (Leap_Seconds);
 
  Days := Long_Integer (Res_Dur / Secs_In_Day);
  Seconds  := Duration (Res_Dur mod Secs_In_Day) + Sub_Secs;
- Leap_Seconds := Integer (Elap

[COMMITTED 18/26] ada: Tweak container aggregate expansion code

2024-08-02 Thread Marc Poulhiès
From: Ronan Desplanques 

This patch makes a minor modification to Expand_Container_Aggregate
in order to silence a GNAT SAS false positive.

gcc/ada/

* exp_aggr.adb (Expand_Container_Aggregate): Remove variables.
(To_Int): New function.
(Add_Range_Size): Use newly introduced function.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_aggr.adb | 40 ++--
 1 file changed, 22 insertions(+), 18 deletions(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 59ed75e8d69..ed0dad1444b 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -6642,8 +6642,6 @@ package body Exp_Aggr is
 
   Choice_Lo : Node_Id := Empty;
   Choice_Hi : Node_Id := Empty;
-  Int_Choice_Lo : Int;
-  Int_Choice_Hi : Int;
 
   Is_Indexed_Aggregate : Boolean := False;
 
@@ -6696,32 +6694,38 @@ package body Exp_Aggr is
  
 
  procedure Add_Range_Size is
-Range_Int_Lo : Int;
-Range_Int_Hi : Int;
+function To_Int (Expr : N_Subexpr_Id) return Int;
+--  Return the Int value corresponding to the bound Expr
 
- begin
---  The bounds of the discrete range are integers or enumeration
---  literals
+
+-- To_Int --
+
 
-if Nkind (Lo) = N_Integer_Literal then
-   Range_Int_Lo := UI_To_Int (Intval (Lo));
-   Range_Int_Hi := UI_To_Int (Intval (Hi));
+function To_Int (Expr : N_Subexpr_Id) return Int is
+begin
+   --  The bounds of the discrete range are integers or enumeration
+   --  literals
+   return UI_To_Int
+ ((if Nkind (Expr) = N_Integer_Literal then
+ Intval (Expr)
+   else
+ Enumeration_Pos (Expr)));
+end To_Int;
 
-else
-   Range_Int_Lo := UI_To_Int (Enumeration_Pos (Lo));
-   Range_Int_Hi := UI_To_Int (Enumeration_Pos (Hi));
-end if;
+--  Local variables
+
+Range_Int_Lo : constant Int := To_Int (Lo);
+Range_Int_Hi : constant Int := To_Int (Hi);
 
+ begin
 Siz := Siz + Range_Int_Hi - Range_Int_Lo + 1;
 
-if No (Choice_Lo) or else Range_Int_Lo < Int_Choice_Lo then
+if No (Choice_Lo) or else Range_Int_Lo < To_Int (Choice_Lo) then
Choice_Lo   := Lo;
-   Int_Choice_Lo := Range_Int_Lo;
 end if;
 
-if No (Choice_Hi) or else Range_Int_Hi > Int_Choice_Hi then
+if No (Choice_Hi) or else Range_Int_Hi > To_Int (Choice_Hi) then
Choice_Hi   := Hi;
-   Int_Choice_Hi := Range_Int_Hi;
 end if;
  end Add_Range_Size;
 
-- 
2.45.2



[COMMITTED 10/26] ada: Compiler accepts illegal assignment to reference type target.

2024-08-02 Thread Marc Poulhiès
From: Steve Baird 

An assignment statement whose LHS is of a reference type is never legal. If
no other legality rule is violated, then it is ambiguous. In some cases this
ambiguity was not correctly detected.

gcc/ada/

* sem_ch5.adb (Analyze_Assignment): Delete code that was
incorrectly implementing a preference rule.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/sem_ch5.adb | 8 
 1 file changed, 8 deletions(-)

diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index 4db3a1a26ee..d44a12d1dd1 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -437,14 +437,6 @@ package body Sem_Ch5 is
then
   null;
 
-   --  This may be a call to a parameterless function through an
-   --  implicit dereference, so discard interpretation as well.
-
-   elsif Is_Entity_Name (Lhs)
- and then Has_Implicit_Dereference (It.Typ)
-   then
-  null;
-
elsif Has_Compatible_Type (Rhs, It.Typ) then
   if T1 = Any_Type then
  T1 := It.Typ;
-- 
2.45.2



[COMMITTED 23/26] ada: Simplify manipulation of the list with loop actions

2024-08-02 Thread Marc Poulhiès
From: Piotr Trojanek 

Code cleanup; behavior is unaffected.

gcc/ada/

* exp_aggr.adb (Add_Loop_Actions): Change manipulation of list
to avoid unnecessary calls to Parent and Loop_Actions.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_aggr.adb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 7a2d0570dbd..8496fcd9b00 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -1262,9 +1262,9 @@ package body Exp_Aggr is
 elsif Nkind (Parent (Expr)) = N_Component_Association
   and then Present (Loop_Actions (Parent (Expr)))
 then
-   Append_List (Lis, Loop_Actions (Parent (Expr)));
Res := Loop_Actions (Parent (Expr));
Set_Loop_Actions (Parent (Expr), No_List);
+   Append_List (Lis, To => Res);
return Res;
 
 else
-- 
2.45.2



[COMMITTED 21/26] ada: Simplify code by reusing Choice_List

2024-08-02 Thread Marc Poulhiès
From: Piotr Trojanek 

Code cleanup; semantics is unaffected.

gcc/ada/

* exp_aggr.adb (Gen_Assign): Fix layout.
* sem_aggr.adb (Empty_Range): Reuse Choice_List.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_aggr.adb | 8 
 gcc/ada/sem_aggr.adb | 8 +---
 2 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 25af78a4da7..7a2d0570dbd 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -1010,8 +1010,8 @@ package body Exp_Aggr is
   --  Returns a new reference to the index type name
 
   function Gen_Assign
-(Ind : Node_Id;
- Expr: Node_Id) return List_Id;
+(Ind  : Node_Id;
+ Expr : Node_Id) return List_Id;
   --  Ind must be a side-effect-free expression. If the input aggregate N
   --  to Build_Loop contains no subaggregates, then this function returns
   --  the assignment statement:
@@ -1237,8 +1237,8 @@ package body Exp_Aggr is
   
 
   function Gen_Assign
-(Ind : Node_Id;
- Expr: Node_Id) return List_Id
+(Ind  : Node_Id;
+ Expr : Node_Id) return List_Id
is
  function Add_Loop_Actions (Lis : List_Id) return List_Id;
  --  Collect insert_actions generated in the construction of a loop,
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index 565f2cb8a79..656d789de73 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -2735,15 +2735,9 @@ package body Sem_Aggr is
 -
 
 function Empty_Range (A : Node_Id) return Boolean is
-   R : Node_Id;
+   R : constant Node_Id := First (Choice_List (A));
 
 begin
-   if Nkind (A) = N_Iterated_Component_Association then
-  R := First (Discrete_Choices (A));
-   else
-  R := First (Choices (A));
-   end if;
-
return No (Next (R))
  and then Nkind (R) = N_Range
  and then Compile_Time_Compare
-- 
2.45.2



[COMMITTED 11/26] ada: Reject ambiguous function calls in interpolated string expressions

2024-08-02 Thread Marc Poulhiès
From: Javier Miranda 

This patch enhances support for this language feature by rejecting
more ambiguous function calls. In terms of name resolution, the
analysis of interpolated expressions is now treated as an expression
of any type, as required by the documentation. Additionally, support
for nested interpolated strings has been removed.

gcc/ada/

* gen_il-fields.ads (Is_Interpolated_String_Literal): New field.
* gen_il-gen-gen_nodes.adb (Is_Interpolated_String_Literal): The
new field is a flag handled by the parser (syntax flag).
* par-ch2.adb (P_Interpolated_String_Literal): Decorate the new
flag.
* sem_ch2.adb (Analyze_Interpolated_String_Literal): Improve code
detecting and reporting ambiguous function calls.
* sem_res.adb (Resolve_Interpolated_String_Literal): Restrict
resolution imposed by the context type to string literals that
have the new flag.
* sinfo.ads (Is_Interpolated_String_Literal): New field defined in
string literals. Fix documentation of the syntax rule of
interpolated string literal.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/gen_il-fields.ads|   1 +
 gcc/ada/gen_il-gen-gen_nodes.adb |   1 +
 gcc/ada/par-ch2.adb  |   2 +
 gcc/ada/sem_ch2.adb  | 242 ---
 gcc/ada/sem_res.adb  |  13 +-
 gcc/ada/sinfo.ads|   9 +-
 6 files changed, 213 insertions(+), 55 deletions(-)

diff --git a/gcc/ada/gen_il-fields.ads b/gcc/ada/gen_il-fields.ads
index 520ea554e11..9b85401eadc 100644
--- a/gcc/ada/gen_il-fields.ads
+++ b/gcc/ada/gen_il-fields.ads
@@ -263,6 +263,7 @@ package Gen_IL.Fields is
   Is_In_Discriminant_Check,
   Is_Inherited_Pragma,
   Is_Initialization_Block,
+  Is_Interpolated_String_Literal,
   Is_Known_Guaranteed_ABE,
   Is_Machine_Number,
   Is_Null_Loop,
diff --git a/gcc/ada/gen_il-gen-gen_nodes.adb b/gcc/ada/gen_il-gen-gen_nodes.adb
index b1ca6cf6c86..7224556accd 100644
--- a/gcc/ada/gen_il-gen-gen_nodes.adb
+++ b/gcc/ada/gen_il-gen-gen_nodes.adb
@@ -444,6 +444,7 @@ begin -- Gen_IL.Gen.Gen_Nodes
Cc (N_String_Literal, N_Numeric_Or_String_Literal,
(Sy (Strval, String_Id),
 Sy (Is_Folded_In_Parser, Flag),
+Sy (Is_Interpolated_String_Literal, Flag),
 Sm (Has_Wide_Character, Flag),
 Sm (Has_Wide_Wide_Character, Flag)));
 
diff --git a/gcc/ada/par-ch2.adb b/gcc/ada/par-ch2.adb
index f249ae76023..98232344dce 100644
--- a/gcc/ada/par-ch2.adb
+++ b/gcc/ada/par-ch2.adb
@@ -237,6 +237,7 @@ package body Ch2 is
  Error_Msg_SC ("string literal expected");
 
   else
+ Set_Is_Interpolated_String_Literal (Token_Node);
  Append_To (Elements_List, Token_Node);
  Scan;  --  past string_literal
 
@@ -261,6 +262,7 @@ package body Ch2 is
   Error_Msg_SC ("unexpected string literal");
end if;
 
+   Set_Is_Interpolated_String_Literal (Token_Node);
Append_To (Elements_List, Token_Node);
Scan; --  past string_literal
 end if;
diff --git a/gcc/ada/sem_ch2.adb b/gcc/ada/sem_ch2.adb
index ddbb329d1f8..6d11b71b95f 100644
--- a/gcc/ada/sem_ch2.adb
+++ b/gcc/ada/sem_ch2.adb
@@ -138,67 +138,113 @@ package body Sem_Ch2 is
 
procedure Analyze_Interpolated_String_Literal (N : Node_Id) is
 
-  procedure Check_Ambiguous_Parameterless_Call (Func_Call : Node_Id);
-  --  Examine the interpretations of the call to the given parameterless
-  --  function call and report the location of each interpretation.
+  procedure Check_Ambiguous_Call (Func_Call : Node_Id);
+  --  Examine the interpretations of the call to the given function call
+  --  and report the location of each interpretation.
 
-  
-  -- Check_Ambiguous_Parameterless_Call --
-  
+  --
+  -- Check_Ambiguous_Call --
+  --
 
-  procedure Check_Ambiguous_Parameterless_Call (Func_Call : Node_Id) is
+  procedure Check_Ambiguous_Call (Func_Call : Node_Id) is
 
- procedure Report_Interpretation (E : Entity_Id);
- --  Report an interpretation of the function call
+ procedure Report_Interpretation (Nam : Entity_Id; Typ : Entity_Id);
+ --  Report an interpretation of the function call. When calling a
+ --  standard operator, use the location of the type, which may be
+ --  user-defined.
 
  ---
  -- Report_Interpretation --
  ---
 
- procedure Report_Interpretation (E : Entity_Id) is
+ procedure Report_Interpretation (Nam : Entity_Id; Typ : Entity_Id) is
  begin
-Error_Msg_Sloc := Sloc (E);
+if Sloc (Nam) = Standard_Locati

[COMMITTED 25/26] ada: Fix handling of iterated component associations with sub-aggregates

2024-08-02 Thread Marc Poulhiès
From: Piotr Trojanek 

Fix a number of problems in handling of actions generated for a
2-dimensional array aggregate where the outer aggregate has iterated
component association and the inner aggregate involves run-time checks.

gcc/ada/

* exp_aggr.adb (Add_Loop_Actions): Actions are now attached to
iterated component association just like they are attached to
ordinary component association.
(Build_Array_Aggr_Code): If resolution of the array aggregate
generated some actions, e.g. for run-time checks, then we must
keep them; same for the Other_Clause.
* sem_aggr.adb (Resolve_Iterated_Component_Association): Unset
references to iterator variable in loop actions (which might come
from run-time check), just these references are unset in the
expression itself.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_aggr.adb | 14 +++---
 gcc/ada/sem_aggr.adb |  9 +
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index 8496fcd9b00..aa6079d82b5 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -1259,7 +1259,8 @@ package body Exp_Aggr is
 if No (Expr) then
return Lis;
 
-elsif Nkind (Parent (Expr)) = N_Component_Association
+elsif Nkind (Parent (Expr)) in N_Component_Association
+ | N_Iterated_Component_Association
   and then Present (Loop_Actions (Parent (Expr)))
 then
Res := Loop_Actions (Parent (Expr));
@@ -1962,7 +1963,9 @@ package body Exp_Aggr is
 
Bounds := Get_Index_Bounds (Choice);
 
-   if Low /= High then
+   if Low /= High
+ and then No (Loop_Actions (Assoc))
+   then
   Set_Loop_Actions (Assoc, New_List);
end if;
 
@@ -2038,7 +2041,12 @@ package body Exp_Aggr is
 
   if First or else not Empty_Range (Low, High) then
  First := False;
- Set_Loop_Actions (Others_Assoc, New_List);
+ if Present (Loop_Actions (Others_Assoc)) then
+pragma Assert
+  (Is_Empty_List (Loop_Actions (Others_Assoc)));
+ else
+Set_Loop_Actions (Others_Assoc, New_List);
+ end if;
  Expr := Get_Assoc_Expr (Others_Assoc);
  Append_List (Gen_Loop (Low, High, Expr), To => New_Code);
   end if;
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index 656d789de73..087e324b5c1 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -2212,6 +2212,15 @@ package body Sem_Aggr is
 
  if Operating_Mode /= Check_Semantics then
 Remove_References (Expr);
+declare
+   Loop_Action : Node_Id;
+begin
+   Loop_Action := First (Loop_Actions (N));
+   while Present (Loop_Action) loop
+  Remove_References (Loop_Action);
+  Next (Loop_Action);
+   end loop;
+end;
  end if;
 
  --  An iterated_component_association may appear in a nested
-- 
2.45.2



[COMMITTED 15/26] ada: Remove unreferenced procedure

2024-08-02 Thread Marc Poulhiès
From: Richard Kenner 

gcc/ada/

* exp_ch4.adb (Generate_Temporary): Remove unused procedure.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_ch4.adb | 43 ---
 1 file changed, 43 deletions(-)

diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 371cb118243..18ec7125cc1 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -10816,49 +10816,6 @@ package body Exp_Ch4 is
  Expr : Node_Id;
  Ityp : Entity_Id;
 
- procedure Generate_Temporary;
- --  Generate a temporary to facilitate in the C backend the code
- --  generation of the unchecked conversion since the size of the
- --  source type may differ from the size of the target type.
-
- 
- -- Generate_Temporary --
- 
-
- procedure Generate_Temporary is
- begin
-if Esize (Etype (Expr)) < Esize (Etype (Ityp)) then
-   declare
-  Exp_Type : constant Entity_Id := Ityp;
-  Def_Id   : constant Entity_Id :=
-   Make_Temporary (Loc, 'R', Expr);
-  E: Node_Id;
-  Res  : Node_Id;
-
-   begin
-  Set_Is_Internal (Def_Id);
-  Set_Etype (Def_Id, Exp_Type);
-  Res := New_Occurrence_Of (Def_Id, Loc);
-
-  E :=
-Make_Object_Declaration (Loc,
-  Defining_Identifier => Def_Id,
-  Object_Definition   => New_Occurrence_Of
-   (Exp_Type, Loc),
-  Constant_Present=> True,
-  Expression  => Relocate_Node (Expr));
-
-  Set_Assignment_OK (E);
-  Insert_Action (Expr, E);
-
-  Set_Assignment_OK (Res, Assignment_OK (Expr));
-
-  Rewrite (Expr, Res);
-  Analyze_And_Resolve (Expr, Exp_Type);
-   end;
-end if;
- end Generate_Temporary;
-
   --  Start of processing for Discrete_Range_Check
 
   begin
-- 
2.45.2



[COMMITTED 20/26] ada: Errors on legal container aggregates with iterated_element_associations

2024-08-02 Thread Marc Poulhiès
From: Gary Dismukes 

The compiler rejects various cases of container aggregates with
iterated_element_associations that include a loop_parameter_subtype_indication
or that include the "reverse" keyword. The fixes are in the parser, for
naccepting the syntax for these cases, as well as for properly accounting
for reverse iterators in the analyzer and expander.

gcc/ada/

* exp_aggr.adb
(Expand_Container_Aggregate.Expand_Iterated_Component): Set the
Reverse_Present flag when creating the loop's iteration_scheme.
* gen_il-gen-gen_nodes.adb: Add flag Reverse_Present to
N_Iterated_Component_Association nodes.
* par-ch3.adb (P_Constraint_Op): Remove testing for and ignoring
of Tok_In following a constraint. It's allowed for "in" to follow
a constraint of loop_parameter_subtype_indication of an
iterator_specification, so it shouldn't be ignored.
* par-ch4.adb (P_Iterated_Component_Association): Account for
"reverse" following the "in" in an iterated_component_association,
and set the Reverse_Present flag on the
N_Iterated_Component_Association node. Add handling for a ":"
following the identifier in an iterator_specification of an
iterated_element_association, sharing the code with the "of" case
(which backs up to the identifier at the beginning of the
iterator_specification). Fix incorrect trailing comment following
the call to Scan.
(Build_Iterated_Element_Association): Set the Reverse_Present flag
on an N_Loop_Parameter_Specification node of an
N_Iterated_Element_Association.
* par-ch5.adb (P_Iterator_Specification): Remove error-recovery
and error code that reports "subtype indication is only legal on
an element iterator", as that error can no longer be emitted (and
was formerly only reported on one fixedbugs test).
* sem_aggr.adb
(Resolve_Container_Aggregate.Resolve_Iterated_Association): When
creating an N_Iterator_Specification for an
N_Iterated_Component_Association, set the Reverse_Present flag of
the N_Iterated_Specification from the flag on the latter.
* sinfo.ads: Add comments for the Reverse_Present flag, which is
now allowed on nodes of kind N_Iterated_Component_Association.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_aggr.adb |  1 +
 gcc/ada/gen_il-gen-gen_nodes.adb |  1 +
 gcc/ada/par-ch3.adb  |  4 
 gcc/ada/par-ch4.adb  | 12 +++-
 gcc/ada/par-ch5.adb  | 12 
 gcc/ada/sem_aggr.adb |  2 +-
 gcc/ada/sinfo.ads|  6 ++
 7 files changed, 20 insertions(+), 18 deletions(-)

diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index ed0dad1444b..25af78a4da7 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -7019,6 +7019,7 @@ package body Exp_Aggr is
Loop_Parameter_Specification =>
  Make_Loop_Parameter_Specification (Loc,
Defining_Identifier => Loop_Id,
+   Reverse_Present => Reverse_Present (Comp),
Discrete_Subtype_Definition => L_Range));
 end if;
  end if;
diff --git a/gcc/ada/gen_il-gen-gen_nodes.adb b/gcc/ada/gen_il-gen-gen_nodes.adb
index 7224556accd..327ff376d12 100644
--- a/gcc/ada/gen_il-gen-gen_nodes.adb
+++ b/gcc/ada/gen_il-gen-gen_nodes.adb
@@ -1489,6 +1489,7 @@ begin -- Gen_IL.Gen.Gen_Nodes
 Sy (Iterator_Specification, Node_Id, Default_Empty),
 Sy (Expression, Node_Id, Default_Empty),
 Sy (Discrete_Choices, List_Id),
+Sy (Reverse_Present, Flag),
 Sy (Box_Present, Flag),
 Sm (Loop_Actions, List_Id)));
 
diff --git a/gcc/ada/par-ch3.adb b/gcc/ada/par-ch3.adb
index 01dd45c4f23..a5f4319debf 100644
--- a/gcc/ada/par-ch3.adb
+++ b/gcc/ada/par-ch3.adb
@@ -1196,10 +1196,6 @@ package body Ch3 is
   elsif Token = Tok_Left_Paren then
  return P_Index_Or_Discriminant_Constraint;
 
-  elsif Token = Tok_In then
- Ignore (Tok_In);
- return P_Constraint_Opt;
-
   --  One more possibility is e.g. 1 .. 10 (i.e. missing RANGE keyword)
 
   elsif Token = Tok_Identifier  or else
diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb
index 9c9b0d70207..8b491c2cfd7 100644
--- a/gcc/ada/par-ch4.adb
+++ b/gcc/ada/par-ch4.adb
@@ -3584,6 +3584,7 @@ package body Ch4 is
   Iter_Spec  : Node_Id;
   Loop_Spec  : Node_Id;
   State  : Saved_Scan_State;
+  In_Reverse : Boolean := False;
 
   procedure Build_Iterated_Element_Association;
   --  If the iterator includes a key expression or a filter, it is
@@ -3602,6 +3603,8 @@ package body Ch4 is
New_Node (N_Loop_Parameter_Specification, Prev_Token_Ptr);
  Set_Defining_Identifier (Loop_Spec, Id);
 
+ Set_Revers

[COMMITTED 17/26] ada: Add contracts to Ada.Strings.Unbounded and adapt implementation

2024-08-02 Thread Marc Poulhiès
From: Yannick Moy 

Add complete functional contracts to all subprograms in
Ada.Strings.Unbounded, except Count, following the specification from
Ada RM A.4.5. These contracts are similar to the contracts found in
Ada.Strings.Fixed and Ada.Strings.Bounded.

A difference is that type Unbounded_String is controlled, thus we avoid
performing copies of a parameter Source with Source'Old, and instead
apply 'Old attribute on the enclosing call, such as Length(Source)'Old.

As Unbounded_String is controlled, the implementation is not in SPARK.
Instead, we have separately proved a slightly different implementation
for which Unbounded_String is not controlled, against the same
specification. This ensures that the specification is consistent.

To minimize differences between this test from the SPARK testsuite and
the actual implementation (the one in a-strunb.adb), and to avoid
overflows in the actual implementation, some code is slightly rewritten.
Delete and Insert are modified to return the correct result in all
cases allowed by the standard.

The same contracts are added to the version in a-strunb__shared.ads and
similar implementation patches are applied to the body
a-strunb__shared.adb. In particular, tests are added to avoid overflows
on strings for which the last index is Natural'Last, and the computations
that involve Sum to guarantee that an exception is raised in case of
overflow are rewritten to guarantee correct detection and no intermediate
overflows (and such tests are applied consistently between the procedure
and the function when both exist).

gcc/ada/

* libgnat/a-strunb.adb (Sum, Saturated_Sum, Saturated_Mul): Adapt
function signatures to more precise types that allow proof.
(function "&"): Conditionally assign a slice to avoid possible
overflow which only occurs when the assignment is a noop (because
the slice is empty in that case).
(Append): Same.
(function "*"): Retype K to avoid a possible overflow. Add early
return on null length for proof.
(Delete): Fix implementation to return the correct result in all
cases allowed by the Ada standard.
(Insert): Same. Also avoid possible overflows.
(Length): Rewrite as expression function for proof.
(Overwrite): Avoid possible overflows.
(Slice): Same.
(To_String): Rewrite as expression function for proof.
* libgnat/a-strunb.ads: Extend Assertion_Policy to new contracts
used. Add complete functional contracts to all subprograms of the
public API except Count.
* libgnat/a-strunb__shared.adb (Sum): Adapt function signature to
more precise types that allow proof.
(function "&"): Conditionally assign a slice to avoid possible
overflow.
(function "*"): Retype K to avoid a possible overflow.
(Delete): Fix implementation to return the correct result in all
cases allowed by the Ada standard.
(Insert): Avoid possible overflows.
(Overwrite): Avoid possible overflows.
(Replace_Slice): Same.
(Slice): Same.
(To_String): Rewrite as expression function for proof.
* libgnat/a-strunb__shared.ads: Extend Assertion_Policy to new
contracts used. Add complete functional contracts to all
subprograms of the public API except Count. Mark public part of
spec as in SPARK.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/libgnat/a-strunb.adb |  110 +--
 gcc/ada/libgnat/a-strunb.ads | 1039 --
 gcc/ada/libgnat/a-strunb__shared.adb |  150 ++--
 gcc/ada/libgnat/a-strunb__shared.ads | 1029 +++--
 4 files changed, 2068 insertions(+), 260 deletions(-)

diff --git a/gcc/ada/libgnat/a-strunb.adb b/gcc/ada/libgnat/a-strunb.adb
index c3d4c71271b..163906ed5cd 100644
--- a/gcc/ada/libgnat/a-strunb.adb
+++ b/gcc/ada/libgnat/a-strunb.adb
@@ -30,22 +30,21 @@
 --
 
 with Ada.Strings.Fixed;
-with Ada.Strings.Search;
 with Ada.Unchecked_Deallocation;
 
 package body Ada.Strings.Unbounded is
 
-   function Sum (Left : Natural; Right : Integer) return Natural with Inline;
+   function Sum (Left, Right : Natural) return Natural with Inline;
--  Returns summary of Left and Right, raise Constraint_Error on overflow
 
function Mul (Left, Right : Natural) return Natural with Inline;
--  Returns multiplication of Left and Right, raise Constraint_Error on
--  overflow.
 
-   function Saturated_Sum (Left : Natural; Right : Integer) return Natural;
+   function Saturated_Sum (Left, Right : Natural) return Natural;
--  Returns summary of Left and Right or Natural'Last on overflow
 
-   function Saturated_Mul (Left, Right : Natural) return Natural;
+   function Saturated_Mul (Left, Right : Positive) return Positive;
--  Returns multiplication of Left and Right or Natural

[COMMITTED 22/26] ada: Refactor negated conjuncts

2024-08-02 Thread Marc Poulhiès
From: Piotr Trojanek 

Code cleanup; semantics is unaffected.

gcc/ada/

* exp_util.adb (Insert_Actions): Move negation in front of
complex conjunctions.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_util.adb | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index bd8bbb39d9c..bde50687597 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -8146,12 +8146,13 @@ package body Exp_Util is
  --  not already set can lead to gigi assertion failures that
  --  are presumably due to malformed trees, so don't do that.
 
- and then (Nkind (P) /= N_Iterated_Component_Association
-or else not Is_List_Member (N)
-or else
-  List_Containing (N) /= Discrete_Choices (P))
- and then (Nkind (P) /= N_Component_Association
-or else Present (Loop_Actions (P)))
+ and then
+   not (Nkind (P) = N_Iterated_Component_Association
+  and then Is_List_Member (N)
+  and then List_Containing (N) = Discrete_Choices (P))
+ and then
+   not (Nkind (P) = N_Component_Association
+  and then No (Loop_Actions (P)))
then
   if Is_Empty_List (Loop_Actions (P)) then
  Set_Loop_Actions (P, Ins_Actions);
-- 
2.45.2



[COMMITTED 24/26] ada: Remove unused null branch

2024-08-02 Thread Marc Poulhiès
From: Piotr Trojanek 

Code cleanup; semantics is unaffected.

gcc/ada/

* exp_util.adb (Insert_Actions): Remove null ELSE branch.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/exp_util.adb | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index bde50687597..ef8c91dfe94 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -8186,9 +8186,6 @@ package body Exp_Util is
   end if;
 
   return;
-
-   else
-  null;
end if;
 
 --  Special case: an attribute denoting a procedure call
-- 
2.45.2



[COMMITTED 26/26] ada: Fix handling of SPARK_Mode on standalone child subprogram

2024-08-02 Thread Marc Poulhiès
From: Yannick Moy 

SPARK_Mode aspect was not properly propagated to the body of
a standalone child subprogram from the generated spec for that subprogram,
leading GNATprove to not analyze this body. Now fixed.

gcc/ada/

* aspects.adb (Find_Aspect): Take into account the case of a node
of kind N_Defining_Program_Unit_Name.
* sem_ch10.adb (Analyze_Compilation_Unit): Copy the SPARK aspect
from the spec to the body. Delay semantic analysis after that
point to ensure that SPARK_Mode is properly analyzed.

Tested on x86_64-pc-linux-gnu, committed on master.

---
 gcc/ada/aspects.adb  |  8 +++-
 gcc/ada/sem_ch10.adb | 12 +++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/aspects.adb b/gcc/ada/aspects.adb
index b7262c56f3f..4c8ab7b4a33 100644
--- a/gcc/ada/aspects.adb
+++ b/gcc/ada/aspects.adb
@@ -190,13 +190,19 @@ package body Aspects is
   --  Note that not all aspects are added to the chain of representation
   --  items. In such cases, search the list of aspect specifications. First
   --  find the declaration node where the aspects reside. This is usually
-  --  the parent or the parent of the parent.
+  --  the parent or the parent of the parent, after getting through the
+  --  additional indirection of the N_Defining_Program_Unit_Name if needed.
 
   if No (Parent (Owner)) then
  return Empty;
   end if;
 
   Decl := Parent (Owner);
+
+  if Nkind (Decl) = N_Defining_Program_Unit_Name then
+ Decl := Parent (Decl);
+  end if;
+
   if not Permits_Aspect_Specifications (Decl) then
  Decl := Parent (Decl);
 
diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index 73e5388affd..e56fe30adae 100644
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -1046,17 +1046,27 @@ package body Sem_Ch10 is
  Set_Library_Unit (N, Lib_Unit);
  Set_Parent_Spec (Unit (Lib_Unit), Cunit (Unum));
  Make_Child_Decl_Unit (N);
- Semantics (Lib_Unit);
 
  --  Now that a separate declaration exists, the body
  --  of the child unit does not act as spec any longer.
 
  Set_Acts_As_Spec (N, False);
  Move_Aspects (From => Unit_Node, To => Unit (Lib_Unit));
+
+ --  Ensure that the generated corresponding spec and
+ --  original body share the same SPARK_Mode pragma or
+ --  aspect. As a result, both have the same SPARK_Mode
+ --  attributes, and the global SPARK_Mode value is
+ --  correctly set for local subprograms.
+
+ Copy_SPARK_Mode_Aspect (Unit (Lib_Unit), To => Unit_Node);
+
  Set_Is_Child_Unit (Defining_Entity (Unit_Node));
  Set_Debug_Info_Needed (Defining_Entity (Unit (Lib_Unit)));
  Set_Comes_From_Source_Default (SCS);
 
+ Semantics (Lib_Unit);
+
  --  Restore Context_Items to the body
 
  Set_Context_Items (N, Context_Items (Lib_Unit));
-- 
2.45.2



Re: [committed] libstdc++: Remove unnecessary uses of

2024-08-02 Thread Jonathan Wakely
On Fri, 2 Aug 2024 at 02:29, Andrew Pinski  wrote:
>
> On Thu, Aug 1, 2024 at 2:14 PM Jonathan Wakely  wrote:
> >
> > This will probably need a gcc-15/porting_to.html entry at some point.
> > Every time we remove transitive includes of  it breaks
> > somebody!
>
> Yes including testcases, libstdc++-prettyprinters/shared_ptr.cc does
> not compile due to this change even:

Oops, looks like I missed the UNRESOLVED lines in the log by only
searching for FAIL.

Fixed with the attached patch, pushed to trunk.
commit 06201faa6376cade5a286850370dd070c1573531
Author: Jonathan Wakely 
Date:   Fri Aug 2 08:27:09 2024

libstdc++: Add missing  to test

libstdc++-v3/ChangeLog:

* testsuite/libstdc++-prettyprinters/shared_ptr.cc: Include
.

diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc 
b/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc
index a9910e6a56d..5ff206a145b 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/shared_ptr.cc
@@ -20,6 +20,7 @@
 
 #include 
 #include 
+#include 
 
 template
 void


RE: [PATCH] i386: Fix comment/naming for APX NDD constraints

2024-08-02 Thread Liu, Hongtao



> -Original Message-
> From: Kong, Lingling 
> Sent: Friday, August 2, 2024 2:43 PM
> To: gcc-patches@gcc.gnu.org
> Cc: Liu, Hongtao ; H. J. Lu 
> Subject: [PATCH] i386: Fix comment/naming for APX NDD constraints
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> Ok for trunk?
> 
> gcc/ChangeLog:
> 
> * config/i386/constraints.md: Fixed the comment/naming
> for je/jM/jO.
> * config/i386/predicates.md (apx_ndd_memory_operand):
> Renamed and fixed the comment.
> (apx_evex_memory_operand): New name.
> (apx_ndd_add_memory_operand): Ditto.
> (apx_evex_add_memory_operand): Ditto.
> ---
>  gcc/config/i386/constraints.md | 12 ++--
> gcc/config/i386/predicates.md  | 21 +++--
>  2 files changed, 17 insertions(+), 16 deletions(-)
> 
> diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
> index 18389c47800..e03d0e1b45b 100644
> --- a/gcc/config/i386/constraints.md
> +++ b/gcc/config/i386/constraints.md
> @@ -463,14 +463,14 @@
>   "TARGET_APX_EGPR && !TARGET_AVX ? GENERAL_GPR16 : GENERAL_REGS")
> 
>  (define_memory_constraint "je"
> -  "@internal Memory operand for APX NDD ADD."
> -  (match_operand 0 "apx_ndd_add_memory_operand"))
> +  "@internal Memory operand for APX EVEX ADD for NDD or NF."
> +  (match_operand 0 "apx_evex_add_memory_operand"))
> 
>  (define_memory_constraint "jM"
> -  "@internal Memory operand, with APX NDD check."
> -  (match_operand 0 "apx_ndd_memory_operand"))
> +  "@internal Memory operand, with APX EVEX check for NDD or NF."
> +  (match_operand 0 "apx_evex_memory_operand"))
> 
>  (define_memory_constraint "jO"
> -  "@internal Offsettable memory operand, with APX NDD check."
> -  (and (match_operand 0 "apx_ndd_memory_operand")
> +  "@internal Offsettable memory operand, with APX EVEX check for NDD or
> NF."
> +  (and (match_operand 0 "apx_evex_memory_operand")
>(match_test "offsettable_nonstrict_memref_p (op)"))) diff --git
> a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index
> 680594871de..8cab10550e8 100644
> --- a/gcc/config/i386/predicates.md
> +++ b/gcc/config/i386/predicates.md
> @@ -2264,11 +2264,11 @@
>return true;
>  })
> 
> -;; Return true if OP is a memory operand that can be also used in APX -;; NDD
> patterns with immediate operand.  With non-default address space, -;;
> segment register or address size prefix, APX NDD instruction length
> +;; Return true if OP is a memory operand that can be also used in APX
> +EVEX for ;; NDD or NF patterns with immediate operand.  With
APX EVEX-encoded patterns(i.e. APX NDD/NF) with ...
> +non-default address space, ;; segment register or address size prefix,
> +APX EVEX instruction length
>  ;; can exceed the 15 byte size limit.
> -(define_predicate "apx_ndd_memory_operand"
> +(define_predicate "apx_evex_memory_operand"
>(match_operand 0 "memory_operand")
>  {
>/* OK if immediate operand size < 4 bytes.  */ @@ -2312,19 +2312,20 @@
>return true;
>  })
> 
> -;; Return true if OP is a memory operand which can be used in APX NDD -;;
> ADD with register source operand.  UNSPEC_GOTNTPOFF memory operand -;;
> is allowed with APX NDD ADD only if R_X86_64_CODE_6_GOTTPOFF works.
> -(define_predicate "apx_ndd_add_memory_operand"
> +;; Return true if OP is a memory operand which can be used in APX EVEX
EVEX-encoded ADD patterns(.i.e APX NDD/NF) with ...
> +ADD for ;; NDD or NF with register source operand.  UNSPEC_GOTNTPOFF
> +memory operand is ;; allowed with APX EVEX ADD only if
> R_X86_64_CODE_6_GOTTPOFF works.
> +(define_predicate "apx_evex_add_memory_operand"
>(match_operand 0 "memory_operand")
>  {
> -  /* OK if "add %reg1, name@gottpoff(%rip), %reg2" is supported.  */
> +  /* OK if "add %reg1, name@gottpoff(%rip), %reg2" or
> +   "{nf} add name@gottpoff(%rip), %reg1" are supported.  */
>if (HAVE_AS_R_X86_64_CODE_6_GOTTPOFF)
>  return true;
> 
>op = XEXP (op, 0);
> 
> -  /* Disallow APX NDD ADD with UNSPEC_GOTNTPOFF.  */
> +  /* Disallow APX EVEX ADD with UNSPEC_GOTNTPOFF.  */
APX EVEX-encoded ADD, others LGTM.
>if (GET_CODE (op) == CONST
>&& GET_CODE (XEXP (op, 0)) == UNSPEC
>&& XINT (XEXP (op, 0), 1) == UNSPEC_GOTNTPOFF)
> --
> 2.31.1


Re: [PATCH] aarch64: Add support for AdvSIMD faminmax

2024-08-02 Thread Kyrylo Tkachov
Hi Saurabh,

> On 1 Aug 2024, at 11:14, Saurabh Jha wrote:
> 
> External email: Use caution opening links or attachments
> 
> 
> The AArch64 FEAT_FAMINMAX extension is optional from Armv9.2-a and
> mandatory from Armv9.5-a. It introduces instructions for computing the
> floating point absolute maximum and minimum of the two vectors element-wise.
> 
> This patch does three things:
> 1. Introduces AdvSIMD faminmax intrinsics.
> 2. Adds code generation support for famax and famin in terms of the
>   existing operators.
> 3. Move report_missing_extension and reported_missing_extension_p to
>   make it more usable.
> 
> The intrinsics of this extension are implemented as the following
> builtin functions:
> * vamax_f16
> * vamaxq_f16
> * vamax_f32
> * vamaxq_f32
> * vamaxq_f64
> * vamin_f16
> * vaminq_f16
> * vamin_f32
> * vaminq_f32
> * vaminq_f64
> 
> For code generation, famax/famin is equivalent to first taking fabs of
> the operands and then taking fmax/fmin of the results of fabs.
>famax/famin (a, b) = fmax/fmin (fabs (a), fabs (b))
> This is correct because NaN/Inf handling of famax/famin and fmax/fmin
> are same. We cannot use fmaxnm/fminnm here as Nan/Inf are handled
> differently in them.
> 

Thank you for the explanation.


> We moved the definition of `report_missing_extension` from
> gcc/config/aarch64/aarch64-sve-builtins.cc to
> gcc/config/aarch64/aarch64-builtins.cc and its declaration to
> gcc/config/aarch64/aarch64-builtins.h. We also moved the declaration
> of `reported_missing_extension_p` from
> gcc/config/aarch64/aarch64-sve-builtins.cc
> to gcc/config/aarch64/aarch64-builtins.cc, closer to the definition of
> `report_missing_extension`. In the exsiting code structure, this leads
> to `report_missing_extension` being usable from both normal builtins
> and sve builtins.

Thanks, this looks much better.


> 
> gcc/ChangeLog:
> 
>* config/aarch64/aarch64-builtins.cc
>(enum aarch64_builtins): New enum values for faminmax builtins.
>(aarch64_init_faminmax_builtins): New function to declare new builtins.
>(handle_arm_neon_h): Modify to call aarch64_init_faminmax_builtins.
>(aarch64_general_check_builtin_call): Modify to check whether 
> +faminmax flag is being used and printing error message if not being used.
>(aarch64_expand_builtin_faminmax): New function to emit instructions 
> of this extension.
>(aarch64_general_expand_builtin): Modify to call 
> aarch64_expand_builtin_faminmax.
>(report_missing_extension): Move from 
> config/aarch64/aarch64-sve-builtins.cc.
>* config/aarch64/aarch64-builtins.h
>(report_missing_extension): Declaration for this function so
> that it can be used wherever this header is included.
>(reported_missing_extension_p): Move from
> config/aarch64/aarch64-sve-builtins.cc
>* config/aarch64/aarch64-option-extensions.def
>(AARCH64_OPT_EXTENSION): Introduce new flag for this extension.
>* config/aarch64/aarch64-simd.md
>(aarch64_): Introduce instruction pattern for this 
> extension.
>* config/aarch64/aarch64-sve-builtins.cc
>(reported_missing_extension_p): Move to 
> config/aarch64/aarch64-builtins.cc
>(report_missing_extension): Move to
> config/aarch64/aarch64-builtins.cc.
>* config/aarch64/aarch64.h
>(TARGET_FAMINMAX): Introduce new flag for this extension.
>* config/aarch64/iterators.md: Introduce new iterators for this 
> extension.
>* config/arm/types.md: Introduce neon_fp_aminmax attributes.
>* doc/invoke.texi: Document extension in AArch64 Options.
> 
> gcc/testsuite/ChangeLog:
> 
>* gcc.target/aarch64/simd/faminmax-builtins-no-flag.c: New test.
>* gcc.target/aarch64/simd/faminmax-builtins.c: New test.
>* gcc.target/aarch64/simd/faminmax-codegen-no-flag.c: New test.
>* gcc.target/aarch64/simd/faminmax-codegen.c: New test.

The aarch64 backend parts look good, but I think the tests could be improved. 
Sorry for missing it out in the first review.


> 
> ---
> Hi,
> 
> Regression tested for aarch64-none-linux-gnu and found no regressions.
> 
> This patch is a revised version of an earlier patch
> https://gcc.gnu.org/pipermail/gcc-patches/2024-July/657914.html but has
> more scope than that. That's why I didn't add "v2" in the subject line.
> 
> Ok for master? I don't have commit access so can someone please commit
> on my behalf?
> 
> Regards,
> Saurabh
> ---
> gcc/config/aarch64/aarch64-builtins.cc| 173 +-
> gcc/config/aarch64/aarch64-builtins.h |   5 +-
> .../aarch64/aarch64-option-extensions.def |   2 +
> gcc/config/aarch64/aarch64-simd.md|  12 ++
> gcc/config/aarch64/aarch64-sve-builtins.cc|  22 ---
> gcc/config/aarch64/aarch64.h  |   4 +
> gcc/config/aarch64/iterators.md   |   8 +
> gcc/config/arm/types.md   |   6 +
> gcc/doc/invoke.texi

Re: [PATCH] fortran: Fix a pasto in gfc_check_dependency

2024-08-02 Thread Jakub Jelinek
On Thu, Aug 01, 2024 at 09:03:39PM +0200, Mikael Morin wrote:
> Le 01/08/2024 à 12:00, Jakub Jelinek a écrit :
> > Hi!
> > 
> > A static analyzer found what seems like a pasto in the PR45019 changes,
> > the second branch of || only accesses sym2 while the first one sym1 except
> > for this one spot.
> > 
> > Not sure I'm able to construct a testcase for this though.
> > 
> What is reported exactly by the static analyzer?

I'm not sure I'm allowed to cite it, it is some proprietary static analyzer
and I got that indirectly.  But if I paraphrase it, the diagnostics was
a possible pasto.  The static analyzer likely doesn't see that
sym1->attr.target implies attr1.target and sym2->attr.target implies
attr2.target.

> This looks like dead code to me.

Seems it wasn't originally dead when it was added in PR45019, but then the
PR62278 change made it dead.
But the function actually returns 0 rather than 1 that PR45019 meant.
So I bet in addition to fixing the pasto we should move that conditional
from where it is right now to the return 0; location after
check_data_pointer_types calls.

What I wonder is why the testcase doesn't actually fail.

And the pasto fix would guess fix
aliasing_dummy_5.f90 with
arg(2:3) = arr(1:2)
instead of
arr(2:3) = arg(1:2)
if the original testcase would actually fail.

> > In any case, bootstrapped/regtested on x86_64-linux and i686-linux
> > successfully, ok for trunk?
> > 
> > 2024-08-01  Jakub Jelinek  
> > 
> > * dependency.cc (gfc_check_dependency): Fix a pasto, check
> > sym1->as->type for AS_ASSUMED_SHAPE rather than sym2->as->type.
> > Formatting fix.
> > 
> > --- gcc/fortran/dependency.cc.jj2024-07-01 11:28:22.705237968 +0200
> > +++ gcc/fortran/dependency.cc   2024-07-31 20:53:34.471588828 +0200
> > @@ -1368,7 +1368,7 @@ gfc_check_dependency (gfc_expr *expr1, g
> >   if ((attr1.pointer || attr1.target) && (attr2.pointer || 
> > attr2.target))
> > {
> >   if (check_data_pointer_types (expr1, expr2)
> > -   && check_data_pointer_types (expr2, expr1))
> > + && check_data_pointer_types (expr2, expr1))
> > return 0;
> >   return 1;
> > @@ -1380,7 +1380,7 @@ gfc_check_dependency (gfc_expr *expr1, g
> >   if (sym1->attr.target && sym2->attr.target
> 
> if both target attributes are true here, both attr1.target and attr2.target
> are true as well, so the conditional before is true and this branch is
> skipped.
> 
> >   && ((sym1->attr.dummy && !sym1->attr.contiguous
> >&& (!sym1->attr.dimension
> > -  || sym2->as->type == AS_ASSUMED_SHAPE))
> > +  || sym1->as->type == AS_ASSUMED_SHAPE))
> >   || (sym2->attr.dummy && !sym2->attr.contiguous
> >   && (!sym2->attr.dimension
> >   || sym2->as->type == AS_ASSUMED_SHAPE

Jakub



Re: [PATCH] fortran: Fix a pasto in gfc_check_dependency

2024-08-02 Thread Tobias Burnus

[static analyzer]
Jakub Jelinek wrote:

[…] it is some proprietary static analyzer


I want to point out that a under utilized static analyzer keeps scanning 
GCC: Coverity Scan.


If someone has the time, I think it would be worthwhile to have a look 
at the reports. There are a bunch of persons having access to it – and 
more can be added (I think I can grant access). Thus, is someone of the 
GCC developers has interest + time …


Tobias


Re: [RFC] RISC-V: Add support for Profiles RVA/B23.

2024-08-02 Thread Jiawei



在 2024/8/1 21:54, Christoph Müllner 写道:

On Mon, Jul 29, 2024 at 5:26 AM Jiawei  wrote:

This patch adds support for RISC-V RVA23 and RVB23 Profiles[1],
which depend on the base RISC-V Profiles support[2].

[1] 
https://github.com/riscv/riscv-profiles/releases/tag/rva23-v0.4-rvb23-v0.1-internal-review
[2] https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658082.html


gcc/ChangeLog:

 * common/config/riscv/riscv-common.cc: New Profiles.

gcc/testsuite/ChangeLog:

 * gcc.target/riscv/attribute-22.c: New test.
 * gcc.target/riscv/attribute-23.c: New test.

---
  gcc/common/config/riscv/riscv-common.cc   | 20 +++
  gcc/testsuite/gcc.target/riscv/attribute-22.c | 11 ++
  gcc/testsuite/gcc.target/riscv/attribute-23.c | 10 ++
  3 files changed, 41 insertions(+)
  create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-22.c
  create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-23.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 23ae07fe2f3..e6e8adf5e1b 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -323,6 +323,9 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
{"zicclsm",  ISA_SPEC_CLASS_NONE, 1, 0},
{"ziccrse",  ISA_SPEC_CLASS_NONE, 1, 0},

+  {"zimop",  ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zcmop",  ISA_SPEC_CLASS_NONE, 1, 0},
+

Independent of the fact that this will be delayed until ratification:
I would prefer to have this in a separate patch as Zimop and Zcmop are
dependencies.
Since Zimop and Zcmop are already ratified, this does not have a
dependency for the profiles ratification.


Ok, I will split it into another patch, thanks!

Jiawei





{"zicntr", ISA_SPEC_CLASS_NONE, 2, 0},
{"zihpm",  ISA_SPEC_CLASS_NONE, 2, 0},

@@ -467,6 +470,23 @@ static const riscv_profiles riscv_profiles_table[] =
 "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
 "_zicboz_zfhmin_zkt"},

+  /* RVA23 contains all mandatory base ISA for RVA22U64 and the new extension
+ 'v,zihintntl,zvfhmin,zvbb,zvkt,zicond,zimop,zcmop,zfa,zawrs' as mandatory
+ extensions.  */
+  {"RVA23U64", "rv64imafdcv_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa"
+   "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
+   "_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zicond_zimop_zcmop_zcb"
+   "_zfa_zawrs"},
+
+
+  /* RVB23 contains all mandatory base ISA for RVA22U64 and the new extension
+ 'zihintntl,zicond,zimop,zcmop,zfa,zawrs' as mandatory
+ extensions.  */
+  {"RVB23U64", "rv64imafdc_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa"
+   "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
+   "_zicboz_zfhmin_zkt_zihintntl_zicond_zimop_zcmop_zcb"
+   "_zfa_zawrs"},
+
/* Currently we do not define S/M mode Profiles in gcc part.  */

/* Terminate the list.  */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-22.c 
b/gcc/testsuite/gcc.target/riscv/attribute-22.c
new file mode 100644
index 000..0bbb3242ddd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-22.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=RVA23U64 -mabi=lp64" } */
+
+void foo(){}
+
+/* { dg-final { scan-assembler ".attribute arch, 
\"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0"
+"_b1p0_v1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0"
+_ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0"
+_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcd1p0_zcmop1p0"
+_zba1p0_zbb1p0_zbs1p0_zkt1p0_zvbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0"
+_zvfhmin1p0_zvkb1p0_zvkt1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0\"" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-23.c 
b/gcc/testsuite/gcc.target/riscv/attribute-23.c
new file mode 100644
index 000..459b5641ca3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-23.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=RVB23U64 -mabi=lp64" } */
+
+void foo(){}
+
+/* { dg-final { scan-assembler ".attribute arch, 
\"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0"
+"_b1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0"
+"_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0_za64rs1p0"
+"_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcd1p0_zcmop1p0_zba1p0"
+"_zbb1p0_zbs1p0_zkt1p0\"" } } */
--
2.25.1





Re: [PATCH] aarch64: Fuse CMP+CSEL and CMP+CSET for -mcpu=neoverse-v2

2024-08-02 Thread Jennifer Schmitz
Dear Richard,
Thanks for the feedback! I made the changes as suggested. Here is the updated 
patch, bootstrapped and tested again.
Best,
Jennifer


0001-AArch64-Fuse-CMP-CSEL-and-CMP-CSET-for-mcpu-neoverse.patch
Description: Binary data

> On 31 Jul 2024, at 21:21, Richard Sandiford  wrote:
> 
> External email: Use caution opening links or attachments
> 
> 
> Jennifer Schmitz  writes:
>> Thanks for the feedback! I updated the patch based on your comments, more 
>> detailed comments inline below. The updated version was bootstrapped and 
>> tested again, no regression.
>> Best,
>> Jennifer
>> 
>> From 89936b7bc2de7a1e4bc55c3a1e8d5e6ac0de579d Mon Sep 17 00:00:00 2001
>> From: Jennifer Schmitz 
>> Date: Wed, 24 Jul 2024 06:13:59 -0700
>> Subject: [PATCH] AArch64: Fuse CMP+CSEL and CMP+CSET for -mcpu=neoverse-v2
>> 
>> According to the Neoverse V2 Software Optimization Guide (section 4.14), the
>> instruction pairs CMP+CSEL and CMP+CSET can be fused, which had not been
>> implemented so far. This patch implements and tests the two fusion pairs.
>> 
>> The patch was bootstrapped and regtested on aarch64-linux-gnu, no regression.
>> There was also no non-noise impact on SPEC CPU2017 benchmark.
>> OK for mainline?
>> 
>> Signed-off-by: Jennifer Schmitz 
>> 
>> gcc/
>> 
>>  * config/aarch64/aarch64.cc (aarch_macro_fusion_pair_p): Implement
>>  fusion logic.
>>  * config/aarch64/aarch64-fusion-pairs.def (cmp+csel): New entry.
>>  (cmp+cset): Likewise.
>>  * config/aarch64/tuning_models/neoversev2.h: Enable logic in
>>  field fusible_ops.
>> 
>> gcc/testsuite/
>> 
>>  * gcc.target/aarch64/fuse_cmp_csel.c: New test.
>>  * gcc.target/aarch64/fuse_cmp_cset.c: Likewise.
>> ---
>> gcc/config/aarch64/aarch64-fusion-pairs.def   |  2 ++
>> gcc/config/aarch64/aarch64.cc | 20 +++
>> gcc/config/aarch64/tuning_models/neoversev2.h |  5 ++-
>> .../gcc.target/aarch64/fuse_cmp_csel.c| 33 +++
>> .../gcc.target/aarch64/fuse_cmp_cset.c| 31 +
>> 5 files changed, 90 insertions(+), 1 deletion(-)
>> create mode 100644 gcc/testsuite/gcc.target/aarch64/fuse_cmp_csel.c
>> create mode 100644 gcc/testsuite/gcc.target/aarch64/fuse_cmp_cset.c
>> 
>> diff --git a/gcc/config/aarch64/aarch64-fusion-pairs.def 
>> b/gcc/config/aarch64/aarch64-fusion-pairs.def
>> index 9a43b0c8065..bf5e85ba8fe 100644
>> --- a/gcc/config/aarch64/aarch64-fusion-pairs.def
>> +++ b/gcc/config/aarch64/aarch64-fusion-pairs.def
>> @@ -37,5 +37,7 @@ AARCH64_FUSION_PAIR ("aes+aesmc", AES_AESMC)
>> AARCH64_FUSION_PAIR ("alu+branch", ALU_BRANCH)
>> AARCH64_FUSION_PAIR ("alu+cbz", ALU_CBZ)
>> AARCH64_FUSION_PAIR ("addsub_2reg_const1", ADDSUB_2REG_CONST1)
>> +AARCH64_FUSION_PAIR ("cmp+csel", CMP_CSEL)
>> +AARCH64_FUSION_PAIR ("cmp+cset", CMP_CSET)
>> 
>> #undef AARCH64_FUSION_PAIR
>> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
>> index e0cf382998c..d42c153443e 100644
>> --- a/gcc/config/aarch64/aarch64.cc
>> +++ b/gcc/config/aarch64/aarch64.cc
>> @@ -27345,6 +27345,26 @@ aarch_macro_fusion_pair_p (rtx_insn *prev, rtx_insn 
>> *curr)
>>   && reg_referenced_p (SET_DEST (prev_set), PATTERN (curr)))
>> return true;
>> 
>> +  /* Fuse CMP and CSEL/CSET.  */
>> +  if (prev_set && curr_set
>> +  && GET_CODE (SET_SRC (prev_set)) == COMPARE
>> +  && SCALAR_INT_MODE_P (GET_MODE (XEXP (SET_SRC (prev_set), 0)))
>> +  && reg_referenced_p (SET_DEST (prev_set), PATTERN (curr)))
>> +{
>> +  enum attr_type prev_type = get_attr_type (prev);
>> +  if ((prev_type == TYPE_ALUS_SREG || prev_type == TYPE_ALUS_IMM)
>> +&& (aarch64_fusion_enabled_p (AARCH64_FUSE_CMP_CSEL)
>> +&& GET_CODE (SET_SRC (curr_set)) == IF_THEN_ELSE
>> +&& REG_P (XEXP (SET_SRC (curr_set), 1))
>> +&& REG_P (XEXP (SET_SRC (curr_set), 2))
> 
> Gah, I'd meant to say this in a previous review, but now realise
> that I forgot.  I think these REG_Ps can be relaxed to:
> 
>   && aarch64_reg_or_zero (XEXP (SET_SRC (curr_set), N), VOIDmode)
> 
> since CSEL can take w/xzr.
Done.
> 
>> +&& SCALAR_INT_MODE_P (GET_MODE (XEXP (SET_SRC (curr_set), 1
>> +|| (aarch64_fusion_enabled_p (AARCH64_FUSE_CMP_CSET)
>> +&& GET_RTX_CLASS (GET_CODE (SET_SRC (curr_set)))
>> +   == RTX_COMPARE
>> +&& REG_P (SET_DEST (curr_set
>> + return true;
>> +}
> 
> It looks like there might be a missing pair of brackets here.  AFAICT,
> the current bracketing works out as:
> 
>  if ((prev_type conditions)
>  && (CMP_CSEL conditions)
> || (CMP_CSET conditions))
> 
> and since || binds less tightly than &&, I think the CMP_CSET condition
> doesn't include the prev_type restriction.  Enclosing everything after
> the first && in an extra set of brackets would fix that.
> 
Done.
> 
> 
> OK with those changes from my POV (no need for another round of review,
> u

[PATCH v1] aarch64: Add fp8 scalar types

2024-08-02 Thread Claudio Bantaloukas

The ACLE defines a new scalar type, __mfp8. This is an opaque 8bit types that
can only be used by fp8 intrinsics. Additionally, the mfloat8_t type is made
available in arm_neon.h and arm_sve.h as an alias of the same.

This implementation uses an INTEGER_TYPE, with precision 8 to represent
__mfp8. Conversions to int and other types are disabled via the
TARGET_INVALID_CONVERSION hook.
Additionally, operations that are typically available to integer types are
disabled via TARGET_INVALID_UNARY_OP and TARGET_INVALID_BINARY_OP hooks.

gcc/ChangeLog:

* config/aarch64/aarch64-builtins.cc (aarch64_mfp8_type_node): Add node
for __mfp8 type.
(aarch64_mfp8_ptr_type_node): Add node for __mfp8 pointer type.
(aarch64_init_fp8_types): New function to initialise fp8 types and
register with language backends.
* config/aarch64/aarch64.cc (aarch64_invalid_conversion): Add function
implementing TARGET_INVALID_CONVERSION hook that blocks conversion to
and from __mfp8 type.
(aarch64_invalid_unary_op): Add function implementing TARGET_UNARY_OP
hook that blocks operations on __mfp8 other than &.
(aarch64_invalid_binary_op): Extend TARGET_BINARY_OP hook to disallow
operations on __mfp8 type.
(TARGET_INVALID_CONVERSION): Add define.
(TARGET_INVALID_UNARY_OP): Likewise.
* config/aarch64/aarch64.h (aarch64_mfp8_type_node): Add node for __mfp8
type.
(aarch64_mfp8_ptr_type_node): Add node for __mfp8 pointer type.
* config/aarch64/arm_neon.h (mfloat8_t): Add typedef.
* config/aarch64/arm_sve.h (mfloat8_t): Likewise.

gcc/testsuite/ChangeLog:

* gcc.target/aarch64/fp8_scalar_1.c: New tests in C.
* gcc.target/aarch64/fp8_scalar_typecheck_1.c: Likewise.
* gcc.target/aarch64/fp8_scalar_typecheck_2.C: New tests in C++.
---

Hi, 
Is this ok for master? I do not have commit rights yet, if ok, can someone 
commit it on my behalf?

Regression tested with aarch64-unknown-linux-gnu.

Thanks,
Claudio Bantaloukas

 gcc/config/aarch64/aarch64-builtins.cc|  23 ++
 gcc/config/aarch64/aarch64.cc |  60 +++
 gcc/config/aarch64/aarch64.h  |   5 +
 gcc/config/aarch64/arm_neon.h |   2 +
 gcc/config/aarch64/arm_sve.h  |   1 +
 .../gcc.target/aarch64/fp8_scalar_1.c | 108 ++
 .../aarch64/fp8_scalar_typecheck_1.c  | 329 
 .../aarch64/fp8_scalar_typecheck_2.C  | 354 ++
 8 files changed, 882 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/fp8_scalar_1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/fp8_scalar_typecheck_1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/fp8_scalar_typecheck_2.C

diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc
index 30669f8aa18..22d60df396f 100644
--- a/gcc/config/aarch64/aarch64-builtins.cc
+++ b/gcc/config/aarch64/aarch64-builtins.cc
@@ -961,6 +961,11 @@ static GTY(()) tree aarch64_simd_intOI_type_node = NULL_TREE;
 static GTY(()) tree aarch64_simd_intCI_type_node = NULL_TREE;
 static GTY(()) tree aarch64_simd_intXI_type_node = NULL_TREE;
 
+/* The user-visible __mfp8 type, and a pointer to that type.  Used
+   across the back-end.  */
+tree aarch64_mfp8_type_node = NULL_TREE;
+tree aarch64_mfp8_ptr_type_node = NULL_TREE;
+
 /* The user-visible __fp16 type, and a pointer to that type.  Used
across the back-end.  */
 tree aarch64_fp16_type_node = NULL_TREE;
@@ -1721,6 +1726,22 @@ aarch64_init_builtin_rsqrt (void)
   }
 }
 
+static void
+aarch64_init_fp8_types (void)
+{
+  aarch64_mfp8_type_node = make_node (INTEGER_TYPE);
+  TYPE_PRECISION (aarch64_mfp8_type_node) = 8;
+  TYPE_MIN_VALUE (aarch64_mfp8_type_node)
+  = TYPE_MIN_VALUE (unsigned_char_type_node);
+  TYPE_MAX_VALUE (aarch64_mfp8_type_node)
+  = TYPE_MAX_VALUE (unsigned_char_type_node);
+  layout_type (aarch64_mfp8_type_node);
+  SET_TYPE_MODE (aarch64_mfp8_type_node, QImode);
+
+  lang_hooks.types.register_builtin_type (aarch64_mfp8_type_node, "__mfp8");
+  aarch64_mfp8_ptr_type_node = build_pointer_type (aarch64_mfp8_type_node);
+}
+
 /* Initialize the backend types that support the user-visible __fp16
type, also initialize a pointer to that type, to be used when
forming HFAs.  */
@@ -2128,6 +2149,8 @@ aarch64_general_init_builtins (void)
 {
   aarch64_init_fpsr_fpcr_builtins ();
 
+  aarch64_init_fp8_types ();
+
   aarch64_init_fp16_types ();
 
   aarch64_init_bf16_types ();
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 9810f2c0390..e774b95e430 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -22450,6 +22450,35 @@ aarch64_mangle_type (const_tree type)
   return NULL;
 }
 
+/* Implement TARGET_INVALID_CONVERSION.
+
+Return the diagnostic message when it is invalid to convert from fromtype to
+totype, or N

Re: [PATCH] MATCH: add abs support for half float

2024-08-02 Thread Kugan Vivekanandarajah


> On 1 Aug 2024, at 10:46 pm, Richard Biener  wrote:
> 
> External email: Use caution opening links or attachments
> 
> 
> On Thu, Aug 1, 2024 at 5:31 AM Kugan Vivekanandarajah
>  wrote:
>> 
>> 
>> On Mon, Jul 29, 2024 at 10:11 AM Andrew Pinski  wrote:
>>> 
>>> On Mon, Jul 29, 2024 at 12:57 AM Kugan Vivekanandarajah
>>>  wrote:
 
 On Thu, Jul 25, 2024 at 10:19 PM Richard Biener
  wrote:
> 
> On Thu, Jul 25, 2024 at 4:42 AM Kugan Vivekanandarajah
>  wrote:
>> 
>> On Tue, Jul 23, 2024 at 11:56 PM Richard Biener
>>  wrote:
>>> 
>>> On Tue, Jul 23, 2024 at 10:27 AM Kugan Vivekanandarajah
>>>  wrote:
 
 On Tue, Jul 23, 2024 at 10:35 AM Andrew Pinski  
 wrote:
> 
> On Mon, Jul 22, 2024 at 5:26 PM Kugan Vivekanandarajah
>  wrote:
>> 
>> Revised based on the comment and moved it into existing patterns as.
>> 
>> gcc/ChangeLog:
>> 
>> * match.pd: Extend A CMP 0 ? A : -A into (type)A CMP 0 ? A : -A.
>> Extend A CMP 0 ? A : -A into (type) A CMP 0 ? A : -A.
>> 
>> gcc/testsuite/ChangeLog:
>> 
>> * gcc.dg/tree-ssa/absfloat16.c: New test.
> 
> The testcase needs to make sure it runs only for targets that support
> float16 so like:
> 
> /* { dg-require-effective-target float16 } */
> /* { dg-add-options float16 } */
 Added in the attached version.
>>> 
>>> + /* (type)A >=/> 0 ? A : -Asame as abs (A) */
>>>  (for cmp (ge gt)
>>>   (simplify
>>> -   (cnd (cmp @0 zerop) @1 (negate @1))
>>> -(if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
>>> -&& !TYPE_UNSIGNED (TREE_TYPE(@0))
>>> -&& bitwise_equal_p (@0, @1))
>>> +   (cnd (cmp (convert?@0 @1) zerop) @2 (negate @2))
>>> +(if (!HONOR_SIGNED_ZEROS (TREE_TYPE (@1))
>>> +&& !TYPE_UNSIGNED (TREE_TYPE (@1))
>>> +&& ((VECTOR_TYPE_P (type)
>>> + && tree_nop_conversion_p (TREE_TYPE (@0), TREE_TYPE (@1)))
>>> +   || (!VECTOR_TYPE_P (type)
>>> +   && (TYPE_PRECISION (TREE_TYPE (@1))
>>> +   <= TYPE_PRECISION (TREE_TYPE (@0)
>>> +&& bitwise_equal_p (@1, @2))
>>> 
>>> I wonder about the bitwise_equal_p which tests @1 against @2 now
>>> with the convert still applied to @1 - that looks odd.  You are allowing
>>> sign-changing conversions but doesn't that change ge/gt behavior?
>>> Also why are sign/zero-extensions not OK for vector types?
>> Thanks for the review.
>> My main motivation here is for _Float16  as below.
>> 
>> _Float16 absfloat16 (_Float16 x)
>> {
>>  float _1;
>>  _Float16 _2;
>>  _Float16 _4;
>>   [local count: 1073741824]:
>>  _1 = (float) x_3(D);
>>  if (_1 < 0.0)
>>goto ; [41.00%]
>>  else
>>goto ; [59.00%]
>>   [local count: 440234144]:\
>>  _4 = -x_3(D);
>>   [local count: 1073741824]:
>>  # _2 = PHI <_4(3), x_3(D)(2)>
>>  return _2;
>> }
>> 
>> This is why I added  bitwise_equal_p test of @1 against @2 with
>> TYPE_PRECISION checks.
>> I agree that I will have to check for sign-changing conversions.
>> 
>> Just to keep it simple, I disallowed vector types. I am not sure if
>> this would  hit vec types. I am happy to handle this if that is
>> needed.
> 
> I think with __builtin_convertvector you should be able to construct
> a testcase that does
 Thanks.
 
 For the pattern,
 ```
 /* A >=/> 0 ? A : -Asame as abs (A) */
 (for cmp (ge gt)
  (simplify
   (cnd (cmp @0 zerop) @1 (negate @1))
(if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
 && !TYPE_UNSIGNED (TREE_TYPE(@0))
 && bitwise_equal_p (@0, @1))
 (if (TYPE_UNSIGNED (type))
  (absu:type @0)
  (abs @0)
 ```
 the vector type doesn't seem right. For example, if we have a 4
 element vector with some negative and positive, I don't think  it
 makes sense. Also, we dont seem to generate  (cmp @0 zerop). Am I
 missing it completely?
>>> 
>>> Looks like I missed adding some vector testcases anyways here is one
>>> to get this, note it is C++ due to the C front-end not support `?:`
>>> for vectors yet (there is a patch).
>>> ```
>>> #define vect8 __attribute__((vector_size(8)))
>>> vect8 int f(vect8 int a)
>>> {
>>>  vect8 int na = -a;
>>>  return (a > 0) ? a : na;
>>> }
>>> ```
>>> At -O2 before forwprop1, we have:
>>> ```
>>>  vector(2) intD.9 a_2(D) = aD.2796;
>>>  vector(2) intD.9 naD.2799;
>>>  vector(2)  _1;
>>>  vector(2) intD.9 _4;
>>> 
>>>  na_3 = -a_2(D);
>>>  _1 = a_2(D) > { 0, 0 };
>>>  _4 = VEC_COND_EXPR <_1, a_2(D), na_3>;
>>> ```
>>> And forwprop using match is able to do:
>>> ```
>>> Applying pattern match.pd:6306, gimple-match-10.cc:19843
>>> gimple_simpli

Re: [PATCH 2/2 v3] libstdc++: add std::is_virtual_base_of

2024-08-02 Thread Giuseppe D'Angelo

Hello,

On 31/07/2024 00:55, Jonathan Wakely wrote:

If __cpp_lib_is_virtual_base_of depends on __has_builtin, then that
will do the right thing for #ifdef __cpp_lib_is_virtual_base_of in
.


Third time's the charm, I hope; clang trunk seems to like this.

Thank you,
--
Giuseppe D'Angelo
From 7e81a94810692b1db3835227f3bc84464aef5df9 Mon Sep 17 00:00:00 2001
From: Giuseppe D'Angelo 
Date: Mon, 29 Jul 2024 19:23:54 +0200
Subject: [PATCH 2/2] libstdc++: add std::is_virtual_base_of

Added by P2985R0 for C++26. This simply exposes the compiler
builtin, and adds the feature-testing macro.

libstdc++-v3/ChangeLog:

	* include/bits/version.def: Added the feature-testing macro.
	* include/bits/version.h: Regenerated.
	* include/std/type_traits: Add support for
	std::is_virtual_base_of and std::is_virtual_base_of_v,
	implemented in terms of the compiler builtin.
	* testsuite/20_util/is_virtual_base_of/value.cc: New test.

Signed-off-by: Giuseppe D'Angelo 
---
 libstdc++-v3/include/bits/version.def |  9 +
 libstdc++-v3/include/bits/version.h   | 10 ++
 libstdc++-v3/include/std/type_traits  | 14 
 .../20_util/is_virtual_base_of/value.cc   | 34 +++
 4 files changed, 67 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc

diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def
index 42cdef2f526..6b8a5b89f29 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1814,6 +1814,15 @@ ftms = {
   };
 };
 
+ftms = {
+  name = is_virtual_base_of;
+  values = {
+v = 202406;
+cxxmin = 26;
+extra_cond = "__has_builtin(__builtin_is_virtual_base_of)";
+  };
+};
+
 // Standard test specifications.
 stds[97] = ">= 199711L";
 stds[03] = ">= 199711L";
diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h
index 1eaf3733bc2..d884b019601 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -2023,4 +2023,14 @@
 #endif /* !defined(__cpp_lib_ranges_concat) && defined(__glibcxx_want_ranges_concat) */
 #undef __glibcxx_want_ranges_concat
 
+#if !defined(__cpp_lib_is_virtual_base_of)
+# if (__cplusplus >  202302L) && (__has_builtin(__builtin_is_virtual_base_of))
+#  define __glibcxx_is_virtual_base_of 202406L
+#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_is_virtual_base_of)
+#   define __cpp_lib_is_virtual_base_of 202406L
+#  endif
+# endif
+#endif /* !defined(__cpp_lib_is_virtual_base_of) && defined(__glibcxx_want_is_virtual_base_of) */
+#undef __glibcxx_want_is_virtual_base_of
+
 #undef __glibcxx_want_all
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index c39a3792537..99656d863fa 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -51,6 +51,7 @@
 #define __glibcxx_want_is_pointer_interconvertible
 #define __glibcxx_want_is_scoped_enum
 #define __glibcxx_want_is_swappable
+#define __glibcxx_want_is_virtual_base_of
 #define __glibcxx_want_logical_traits
 #define __glibcxx_want_reference_from_temporary
 #define __glibcxx_want_remove_cvref
@@ -1539,6 +1540,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 : public __bool_constant<__is_base_of(_Base, _Derived)>
 { };
 
+#ifdef __cpp_lib_is_virtual_base_of // C++ >= 26
+  /// is_virtual_base_of
+  /// @since C++26
+  template
+struct is_virtual_base_of
+: public bool_constant<__builtin_is_virtual_base_of(_Base, _Derived)>
+{ };
+#endif
+
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible)
   template
 struct is_convertible
@@ -3619,6 +3629,10 @@ template 
 #endif
 template 
   inline constexpr bool is_base_of_v = __is_base_of(_Base, _Derived);
+#ifdef __cpp_lib_is_virtual_base_of // C++ >= 26
+template 
+  inline constexpr bool is_virtual_base_of_v = __builtin_is_virtual_base_of(_Base, _Derived);
+#endif
 #if _GLIBCXX_USE_BUILTIN_TRAIT(__is_convertible)
 template 
   inline constexpr bool is_convertible_v = __is_convertible(_From, _To);
diff --git a/libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc b/libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc
new file mode 100644
index 000..5d83de0683e
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_virtual_base_of/value.cc
@@ -0,0 +1,34 @@
+// { dg-do compile { target c++26 } }
+
+#include 
+
+#if !defined(__cpp_lib_is_virtual_base_of) || __cpp_lib_is_virtual_base_of < 202406L
+#error "__cpp_lib_is_virtual_base_of should have been defined to 202406L or more"
+#endif
+
+class B { };
+class X : virtual public B { };
+class Y : virtual public B { };
+class Z : public B { };
+class AA : public X, public Y, public Z { };
+
+template
+constexpr bool test()
+{
+  constexpr bool t1 = std::is_virtual_base_of::value;
+  constexpr bool t2 = std::is_virtual_base_of_v;
+  static_assert(t1 == t2);
+  return t1;
+}
+
+void test01()
+{
+  static_assert(!test());
+  s

Re: [PATCH 2/2 v3] libstdc++: add std::is_virtual_base_of

2024-08-02 Thread Jonathan Wakely
On Fri, 2 Aug 2024 at 10:35, Giuseppe D'Angelo wrote:
>
> Hello,
>
> On 31/07/2024 00:55, Jonathan Wakely wrote:
> > If __cpp_lib_is_virtual_base_of depends on __has_builtin, then that
> > will do the right thing for #ifdef __cpp_lib_is_virtual_base_of in
> > .
>
> Third time's the charm, I hope; clang trunk seems to like this.

Yup, this looks good now, thanks!

Once your patch to add the built-in is approved, we can add this.



Re: [RFC/RFA] [PATCH 08/12] Add a new pass for naive CRC loops detection

2024-08-02 Thread Richard Biener
On Wed, Jul 31, 2024 at 10:15 AM Mariam Arutunian
 wrote:
>
>  This patch adds a new compiler pass aimed at identifying naive CRC 
> implementations,
> characterized by the presence of a loop calculating a CRC (polynomial long 
> division).
>  Upon detection of a potential CRC, the pass prints an informational message.
>
>  Performs CRC optimization if optimization level is >= 2,
> besides optimizations for size and if fno_gimple_crc_optimization given.
>
>  This pass is added for the detection and optimization of naive CRC 
> implementations,
> improving the efficiency of CRC-related computations.
>
>   This patch includes only initial fast checks for filtering out non-CRCs,
> detected possible CRCs verification and optimization parts will be provided 
> in subsequent patches.

+fgimple-crc-optimization

Please do not put IL names in flags exposed to users, this should be
-foptimize-crc

+This flag is enabled by default at @option{-O2} and higher
+if @option{-Os} is not also specified.

Please leave out "if @option{-Os} is not also specified".  I wonder why
for example if the CPU has a CRC instruction and the polynomial matches
we would disable this when optimizing for size?  A CRC instruction should
be smaller?

+/* This pass performs CRC optimization.  */
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "tree.h"
+#include "gimple.h"
+#include "tree-pass.h"
+#include "ssa.h"
+#include "gimple-iterator.h"
+#include "tree-cfg.h"
+#include "tree-ssa-loop-niter.h"

please try to prune the set of #include (I guess you've
copied this from elsewhere).

+ /* Don't continue searching if encountered the loop's beginning.  */
+ if (bb_loop_header_p (gimple_bb (stmt)))
+   return nullptr;

gimple_bb (stmt) == m_crc_loop->header

it looks like this loop ignores other uses of xored_crc, like in
calls?  Shouldn't
there be a

else if (!is_gimple_debug (stmt))
   return nullptr;

in the FOR_EACH_IMM_USE_FAST loop?

It looks like loop_may_calculate_crc walks all loops XOR stmts and
for each xor_calculates_crc you call set_bbs_stmts_not_visited.
This looks like it would be quadratic in complexity considering a loop
with 1000s of XOR stmts _not_ computing a CRC?  This would be
solved by aborting the search when the first found XOR is not
a CRC for example.  Or by doing the initialization only once.

It also seems that in xor_calculates_crc finding the
shift after the XOR is much cheaper than the one before
as that collects dependent stmts (but we unset visited on all
stmts _again_).  May I suggest to use a bitmap of SSA def
SSA_NAME_VERSIONs instead of using the gimple visited flag?

You are collecting a possibly very large use-def chain but
only very simple checks are later done on it.

Richard.

>  gcc/
>
>* Makefile.in (OBJS): Add gimple-crc-optimization.o.
>* common.opt (fgimple-crc-optimization): New option.
>* common.opt.urls: Regenerate to add
>fgimple-crc-optimization.
>* doc/invoke.texi (-fgimple-crc-optimization): Add documentation.
>* gimple-crc-optimization.cc: New file.
>* gimple.cc (set_phi_stmts_not_visited): New function.
>(set_gimple_stmts_not_visited): Likewise.
>(set_bbs_stmts_not_visited): Likewise.
>* gimple.h (set_gimple_stmts_not_visited): New extern function 
> declaration.
>(set_phi_stmts_not_visited): New extern function declaration.
>(set_bbs_stmts_not_visited): New extern function declaration.
>* opts.cc (default_options_table): Add OPT_fgimple_crc_optimization.
>(enable_fdo_optimizations): Enable gimple-crc-optimization.
>* passes.def (pass_crc_optimization): Add new pass.
>* timevar.def (TV_GIMPLE_CRC_OPTIMIZATION): New timevar.
>* tree-pass.h (make_pass_crc_optimization): New extern function 
> declaration.
>
> Signed-off-by: Mariam Arutunian 


Re: [RFC/RFA] [PATCH v2 09/12] Add symbolic execution support.

2024-08-02 Thread Richard Biener
On Wed, Jul 31, 2024 at 12:42 PM Mariam Arutunian
 wrote:
>
> Gives an opportunity to execute the code on bit level,
>assigning symbolic values to the variables which don't have initial values.
>Supports only CRC specific operations.
>
>Example:
>
>uint8_t crc;
>uint8_t pol = 1;
>crc = crc ^ pol;
>
>during symbolic execution crc's value will be:
>crc(8), crc(7), ... crc(1), crc(0) ^ 1

There seem to be quite some functions without a function comment.

I see

+enum value_type {
+  SYMBOLIC_BIT,
+  BIT,
+  BIT_XOR_EXPRESSION,
+  BIT_AND_EXPRESSION,
+  BIT_OR_EXPRESSION,
+  BIT_COMPLEMENT_EXPRESSION,
+  SHIFT_RIGHT_EXPRESSION,
+  SHIFT_LEFT_EXPRESSION,
+  ADD_EXPRESSION,
+  SUB_EXPRESSION,
+  BIT_CONDITION
+};

is there a specific reason to make the expressions not use enum tree_code?

The main API (?) has

+  /* Does bit-level XOR operation for given variables.  */
+  bool do_xor (tree arg1, tree arg2, tree dest);
+
+  /* Does bit-level AND operation for given variables.  */
+  bool do_and (tree arg1, tree arg2, tree dest);
+
+  /* Does bit-level OR operation for given variables.  */
+  bool do_or (tree arg1, tree arg2, tree dest);
+
...

that could better be

  bool do (enum tree_code, tree, tree, tree);

so symbolic execution of a set of GIMPLE stmts would not require
"indirection"?

How is this all used and what are the constraints?  It does look like
a generic framework which means documentation in the internals
manual would be useful to be had.

We have some crude symbolic execution in gimple-ssa-store-merging.cc
for the purpose of detecting byte-swaps.  That operates on a byte level.
It is quite efficient.  I assume that the new symbolic execution framework
could be used to replace that or am I mis-characterizing what it does?

Richard.


>Author: Matevos Mehrabyan 
>
>  gcc/
>
>* Makefile.in (OBJS): Add sym-exec/expression.o,
>sym-exec/state.o, sym-exec/condition.o.
>* configure (sym-exec): New subdir.
>
>  gcc/sym-exec/
>
>* condition.cc: New file.
>* condition.h: New file.
>* expression-is-a-helper.h: New file.
>* expression.cc: New file.
>* expression.h: New file.
>* state.cc: New file.
>* state.h: New file.
>
>Signed-off-by: Mariam Arutunian 


[PATCH, v2] libstdc++: Preserve signbit of nan when converting float to double [PR113578]

2024-08-02 Thread Jonathan Wakely
Rivos CI found a problem in the v1 patch (see the PR comments). This
should solve it, by using 'constexpr' not _GLIBCXX17_CONSTEXPR. That
requires diagnostic pragmas to suppress -Wc++17-extensions and isn't
possible at all in C++98 mode, so just use the slightly less efficient
__builtin_signbit(__f) ? _To(-1.0) : _To(+1.0)
code for C++98.

I also noticed that the definition of __sign needed to be outside the
#if group.

Tested x86_64-linux.

-- >8 --

LWG 117 specifies that inserting a float into an ostream should cast it
to double, because there's no std::num_put::put member that takes a
float. However, on RISC-V converting a NaN float to double loses the
sign, which means that negative NaN floats are printed as positive.

This has been reported as LWG 4101 and there is good support for fixing
the standard to preserve the sign bit when printing negative NaN values.

This change uses copysign((double)f, (double)std::bit_cast(f)) to
get a double that preserves the sign. The bit_cast gives us an integer
with the same signbit, and casting that to the target type preserves
the signbit. We don't care about the value, as copysign only uses the
signbit.

The inserters for extended floating-point types need the same treatment,
so add a new _S_cast_flt helper to do the signbit-preserving conversion
generically.

So far only RISC-V has been confirmed to need this treatment, but we
might need to extend it to other targets later.

libstdc++-v3/ChangeLog:

PR libstdc++/113578
* include/std/ostream (_S_cast_flt): New static member function
to restore signbit after casting to double or long double.
(operator<<(float), operator<<(_Float16), operator<<(_Float32))
(operator<<(_Float64), operator(_Float128))
(operator<<(__bfloat16_t)): Use _S_cast_flt.
testsuite/27_io/basic_ostream/inserters_arithmetic/lwg4101.cc:
New test.

Co-authored-by: Andrew Waterman 
---
 libstdc++-v3/include/std/ostream  | 43 ---
 .../inserters_arithmetic/lwg4101.cc   | 14 ++
 2 files changed, 51 insertions(+), 6 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/lwg4101.cc

diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream
index 12be6c4fd17..09572f8389c 100644
--- a/libstdc++-v3/include/std/ostream
+++ b/libstdc++-v3/include/std/ostream
@@ -233,7 +233,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 117. basic_ostream uses nonexistent num_put member functions.
-   return _M_insert(static_cast(__f));
+   return _M_insert(_S_cast_flt(__f));
   }
 
   __ostream_type&
@@ -246,7 +246,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __ostream_type&
   operator<<(_Float16 __f)
   {
-   return _M_insert(static_cast(__f));
+   return _M_insert(_S_cast_flt(__f));
   }
 #endif
 
@@ -255,7 +255,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __ostream_type&
   operator<<(_Float32 __f)
   {
-   return _M_insert(static_cast(__f));
+   return _M_insert(_S_cast_flt(__f));
   }
 #endif
 
@@ -264,7 +264,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __ostream_type&
   operator<<(_Float64 __f)
   {
-   return _M_insert(static_cast(__f));
+   return _M_insert(_S_cast_flt(__f));
   }
 #endif
 
@@ -273,7 +273,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __ostream_type&
   operator<<(_Float128 __f)
   {
-   return _M_insert(static_cast(__f));
+   return _M_insert(_S_cast_flt(__f));
   }
 #endif
 
@@ -282,7 +282,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   __ostream_type&
   operator<<(__gnu_cxx::__bfloat16_t __f)
   {
-   return _M_insert(static_cast(__f));
+   return _M_insert(_S_cast_flt(__f));
   }
 #endif
 
@@ -473,7 +473,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   _M_write(const char_type* __s, streamsize __n)
   { std::__ostream_insert(*this, __s, __n); }
 #endif
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++17-extensions" // for if-constexpr
+  template
+   static _To
+   _S_cast_flt(_From __f)
+   {
+ _To __d = static_cast<_To>(__f);
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4101: LWG 117 loses the sign for negative NaN on some arches.
+#if defined __riscv
+ _To __sign;
+#if __cpp_constexpr && __has_builtin(__builtin_bit_cast)
+ if constexpr (sizeof(__f) == sizeof(short))
+   __sign = static_cast<_To>(__builtin_bit_cast(short, __f));
+ else if constexpr (sizeof(__f) == sizeof(int))
+   __sign = static_cast<_To>(__builtin_bit_cast(int, __f));
+ else if constexpr (sizeof(__f) == sizeof(long long))
+   __sign = static_cast<_To>(__builtin_bit_cast(long long, __f));
+ else
+#endif
+ __sign = __builtin_signbit(__f) ? _To(-1.0) : _To(+1.0);
+
+ if _GLIBCXX17_CONSTEXPR (__is_same(_To, double))
+  

Re: [PATCH] MATCH: add abs support for half float

2024-08-02 Thread Richard Biener
On Fri, Aug 2, 2024 at 11:20 AM Kugan Vivekanandarajah
 wrote:
>
>
>
> > On 1 Aug 2024, at 10:46 pm, Richard Biener  
> > wrote:
> >
> > External email: Use caution opening links or attachments
> >
> >
> > On Thu, Aug 1, 2024 at 5:31 AM Kugan Vivekanandarajah
> >  wrote:
> >>
> >>
> >> On Mon, Jul 29, 2024 at 10:11 AM Andrew Pinski  wrote:
> >>>
> >>> On Mon, Jul 29, 2024 at 12:57 AM Kugan Vivekanandarajah
> >>>  wrote:
> 
>  On Thu, Jul 25, 2024 at 10:19 PM Richard Biener
>   wrote:
> >
> > On Thu, Jul 25, 2024 at 4:42 AM Kugan Vivekanandarajah
> >  wrote:
> >>
> >> On Tue, Jul 23, 2024 at 11:56 PM Richard Biener
> >>  wrote:
> >>>
> >>> On Tue, Jul 23, 2024 at 10:27 AM Kugan Vivekanandarajah
> >>>  wrote:
> 
>  On Tue, Jul 23, 2024 at 10:35 AM Andrew Pinski  
>  wrote:
> >
> > On Mon, Jul 22, 2024 at 5:26 PM Kugan Vivekanandarajah
> >  wrote:
> >>
> >> Revised based on the comment and moved it into existing patterns 
> >> as.
> >>
> >> gcc/ChangeLog:
> >>
> >> * match.pd: Extend A CMP 0 ? A : -A into (type)A CMP 0 ? A : -A.
> >> Extend A CMP 0 ? A : -A into (type) A CMP 0 ? A : -A.
> >>
> >> gcc/testsuite/ChangeLog:
> >>
> >> * gcc.dg/tree-ssa/absfloat16.c: New test.
> >
> > The testcase needs to make sure it runs only for targets that 
> > support
> > float16 so like:
> >
> > /* { dg-require-effective-target float16 } */
> > /* { dg-add-options float16 } */
>  Added in the attached version.
> >>>
> >>> + /* (type)A >=/> 0 ? A : -Asame as abs (A) */
> >>>  (for cmp (ge gt)
> >>>   (simplify
> >>> -   (cnd (cmp @0 zerop) @1 (negate @1))
> >>> -(if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
> >>> -&& !TYPE_UNSIGNED (TREE_TYPE(@0))
> >>> -&& bitwise_equal_p (@0, @1))
> >>> +   (cnd (cmp (convert?@0 @1) zerop) @2 (negate @2))
> >>> +(if (!HONOR_SIGNED_ZEROS (TREE_TYPE (@1))
> >>> +&& !TYPE_UNSIGNED (TREE_TYPE (@1))
> >>> +&& ((VECTOR_TYPE_P (type)
> >>> + && tree_nop_conversion_p (TREE_TYPE (@0), TREE_TYPE 
> >>> (@1)))
> >>> +   || (!VECTOR_TYPE_P (type)
> >>> +   && (TYPE_PRECISION (TREE_TYPE (@1))
> >>> +   <= TYPE_PRECISION (TREE_TYPE (@0)
> >>> +&& bitwise_equal_p (@1, @2))
> >>>
> >>> I wonder about the bitwise_equal_p which tests @1 against @2 now
> >>> with the convert still applied to @1 - that looks odd.  You are 
> >>> allowing
> >>> sign-changing conversions but doesn't that change ge/gt behavior?
> >>> Also why are sign/zero-extensions not OK for vector types?
> >> Thanks for the review.
> >> My main motivation here is for _Float16  as below.
> >>
> >> _Float16 absfloat16 (_Float16 x)
> >> {
> >>  float _1;
> >>  _Float16 _2;
> >>  _Float16 _4;
> >>   [local count: 1073741824]:
> >>  _1 = (float) x_3(D);
> >>  if (_1 < 0.0)
> >>goto ; [41.00%]
> >>  else
> >>goto ; [59.00%]
> >>   [local count: 440234144]:\
> >>  _4 = -x_3(D);
> >>   [local count: 1073741824]:
> >>  # _2 = PHI <_4(3), x_3(D)(2)>
> >>  return _2;
> >> }
> >>
> >> This is why I added  bitwise_equal_p test of @1 against @2 with
> >> TYPE_PRECISION checks.
> >> I agree that I will have to check for sign-changing conversions.
> >>
> >> Just to keep it simple, I disallowed vector types. I am not sure if
> >> this would  hit vec types. I am happy to handle this if that is
> >> needed.
> >
> > I think with __builtin_convertvector you should be able to construct
> > a testcase that does
>  Thanks.
> 
>  For the pattern,
>  ```
>  /* A >=/> 0 ? A : -Asame as abs (A) */
>  (for cmp (ge gt)
>   (simplify
>    (cnd (cmp @0 zerop) @1 (negate @1))
> (if (!HONOR_SIGNED_ZEROS (TREE_TYPE(@0))
>  && !TYPE_UNSIGNED (TREE_TYPE(@0))
>  && bitwise_equal_p (@0, @1))
>  (if (TYPE_UNSIGNED (type))
>   (absu:type @0)
>   (abs @0)
>  ```
>  the vector type doesn't seem right. For example, if we have a 4
>  element vector with some negative and positive, I don't think  it
>  makes sense. Also, we dont seem to generate  (cmp @0 zerop). Am I
>  missing it completely?
> >>>
> >>> Looks like I missed adding some vector testcases anyways here is one
> >>> to get this, note it is C++ due to the C front-end not support `?:`
> >>> for vectors yet (there is a patch).
> >>> ```
> >>> #define vect8 __attribute__((vector_size(8)))
> >>> vect8 int f(vect8 int a)
> >>> {
> >>>  vect8 int na = -a;
> >>>  return (a > 0) ? a : na;
> >>> }
> >>> ```
> >>> At -O2 before forwprop1, we have:
>

[pushed] c++, coroutines: Fix a typo in checking for void expression types.

2024-08-02 Thread Iain Sandoe
tested on x86_64-darwin and linux, pushed to trunk as obvious, thanks,
Iain

--- 8< ---

The current code fails to check for void expression types because it does
not lookup the type.  Fixed thus.

gcc/cp/ChangeLog:

* coroutines.cc (replace_continue): Look up expression type.

Signed-off-by: Iain Sandoe 
---
 gcc/cp/coroutines.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 91bbe6b0a0e..9c1e5f0c5d7 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3433,7 +3433,7 @@ replace_continue (tree *stmt, int *do_subtree, void *d)
   tree expr = *stmt;
   if (TREE_CODE (expr) == CLEANUP_POINT_EXPR)
 expr = TREE_OPERAND (expr, 0);
-  if (CONVERT_EXPR_P (expr) && VOID_TYPE_P (expr))
+  if (CONVERT_EXPR_P (expr) && VOID_TYPE_P (TREE_TYPE (expr)))
 expr = TREE_OPERAND (expr, 0);
   STRIP_NOPS (expr);
   if (!STATEMENT_CLASS_P (expr))
-- 
2.39.2 (Apple Git-143)



[pushed] c++, coroutines: Remove unused suspend point state [NFC].

2024-08-02 Thread Iain Sandoe
Tested on x86_64-darwin, pushed to trunk as obvious, thanks
Iain

--- 8< ---

We maintain state on the progress of await analysis in an object that
is passed to the various tree walks used.  Some of the state had become
stale (i.e. unused members).  Remove those and provide a CTOR so that
updates are localised.

Remove the file scope hash_map used to collect the final state for the
actor function and make that part of the suspend point state.

gcc/cp/ChangeLog:

* coroutines.cc (struct susp_frame_data): Remove unused members,
provide a CTOR.
(morph_fn_to_coro): Use susp_frame_data CTOR, and make the suspend
state hash map local to the morph function.

Signed-off-by: Iain Sandoe 
---
 gcc/cp/coroutines.cc | 56 +---
 1 file changed, 27 insertions(+), 29 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 9c1e5f0c5d7..78a72047846 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1988,12 +1988,11 @@ struct suspend_point_info
   tree await_field_id;
 };
 
-static hash_map *suspend_points;
-
 struct await_xform_data
 {
   tree actor_fn;   /* Decl for context.  */
   tree actor_frame;
+  hash_map *suspend_points;
 };
 
 /* When we built the await expressions, we didn't know the coro frame
@@ -2003,7 +2002,7 @@ struct await_xform_data
 static tree
 transform_await_expr (tree await_expr, await_xform_data *xform)
 {
-  suspend_point_info *si = suspend_points->get (await_expr);
+  suspend_point_info *si = xform->suspend_points->get (await_expr);
   location_t loc = EXPR_LOCATION (await_expr);
   if (!si)
 {
@@ -2227,6 +2226,7 @@ coro_get_frame_dtor (tree coro_fp, tree orig, tree 
frame_size,
 static void
 build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
tree orig, hash_map *local_var_uses,
+   hash_map *suspend_points,
vec *param_dtor_list,
tree resume_idx_var, unsigned body_count, tree frame_size)
 {
@@ -2407,7 +2407,7 @@ build_actor_fn (location_t loc, tree coro_frame_type, 
tree actor, tree fnbody,
   /* Now we know the real promise, and enough about the frame layout to
  decide where to put things.  */
 
-  await_xform_data xform = {actor, actor_frame};
+  await_xform_data xform = {actor, actor_frame, suspend_points};
 
   /* Transform the await expressions in the function body.  Only do each
  await tree once!  */
@@ -2642,7 +2642,8 @@ build_init_or_final_await (location_t loc, bool is_final)
function.  */
 
 static bool
-register_await_info (tree await_expr, tree aw_type, tree aw_nam)
+register_await_info (tree await_expr, tree aw_type, tree aw_nam,
+hash_map *suspend_points)
 {
   bool seen;
   suspend_point_info &s
@@ -2663,21 +2664,26 @@ register_await_info (tree await_expr, tree aw_type, 
tree aw_nam)
 struct susp_frame_data
 {
   /* Function-wide.  */
-  tree *field_list; /* The current coroutine frame field list.  */
-  tree handle_type; /* The self-handle type for this coroutine.  */
-  tree fs_label;/* The destination for co_returns.  */
+  tree fs_label;   /* The destination for co_returns.  */
+  hash_map *suspend_points; /* Not owned.  */
   vec *block_stack; /* Track block scopes.  */
   vec *bind_stack;  /* Track current bind expr.  */
-  unsigned await_number;/* Which await in the function.  */
-  unsigned cond_number; /* Which replaced condition in the fn. 
 */
+  unsigned await_number = 0;/* Which await in the function.  */
+  unsigned cond_number = 0; /* Which replaced condition in the fn. 
 */
+
   /* Temporary values for one statement or expression being analyzed.  */
-  hash_set captured_temps; /* The suspend captured these temps.  */
-  vec *to_replace;  /* The VAR decls to replace.  */
-  hash_set *truth_aoif_to_expand; /* The set of TRUTH exprs to expand.  
*/
-  unsigned saw_awaits;  /* Count of awaits in this statement  */
-  bool captures_temporary;  /* This expr captures temps by ref.  */
-  bool needs_truth_if_exp;  /* We must expand a truth_if expression.  */
-  bool has_awaiter_init;/* We must handle initializing an awaiter.  */
+  hash_set *truth_aoif_to_expand = nullptr; /* The set of TRUTH exprs to 
expand.  */
+  unsigned saw_awaits = 0;  /* Count of awaits in this statement  
*/
+  bool captures_temporary = false;  /* This expr captures temps by ref.  */
+  bool needs_truth_if_exp = false;  /* We must expand a truth_if 
expression.  */
+  bool has_awaiter_init = false;/* We must handle initializing an 
awaiter.  */
+
+  susp_frame_data (tree _final_susp, hash_map *_spt)
+: fs_label (_final_susp), suspend_points (_spt)
+  {
+block_stack = make_tree_vector ();
+bind_stack = make_tree_vector ();
+  }
 };
 
 /* If this is an await expression, then count it (both uniquely within the
@@ -2708,7 +2714,7 @@ register_awaits (tree *stm

[PATCH] libstdc++: add default template parameters to algorithms

2024-08-02 Thread Giuseppe D'Angelo

Hello,

The attached patch adds support for P2248R8 + P3217R0 (Enabling 
list-initialization for algorithms, C++26). The big question is whether 
this keeps the code readable enough without introducing too much 
#ifdef-ery, so any feedback is appreciated.


Thanks,

--
Giuseppe D'Angelo
From 9f1a84548ecea9859c1f8d70c533e4e5a0701870 Mon Sep 17 00:00:00 2001
From: Giuseppe D'Angelo 
Date: Fri, 2 Aug 2024 00:23:04 +0200
Subject: [PATCH] libstdc++: add default template parameters to algorithms

This implements P2248R8 + P3217R0, both approved for C++26.
The changes are mostly mechanical; the struggle is to keep readability
with the pre-P2248 signatures:

* for containers, the change is simple and localized enough to justify
an ifdef on the feature testing macro;

* for "classic" algorithms and the parallel versions, introduce a
dedicated macro;

* range algorithms are more tricky as they usually require reordering
of the template parameters, and sometimes the introduction of new
constraints. The idea was to avoid too much surgery and try and keep
the code clean w.r.t. the pre-P2248 versions, even if sometimes this
means duplicating the template heads.

libstdc++-v3/ChangeLog:

	* include/Makefile.am: Add the new header.
	* include/Makefile.in: Regenerate.
	* include/bits/iterator_concepts.h: Add projected_value_t.
	* include/bits/algorithmfwd.h: Add the default template
	parameter to the relevant forward declarations.
	* include/pstl/glue_algorithm_defs.h: Likewise.
	* include/bits/ranges_algo.h: Add the default template parameter
	to range-based algorithms.
	* include/bits/ranges_algobase.h: Likewise.
	* include/bits/ranges_util.h: Likewise.
	* include/bits/version.def: Add the new feature-testing macro.
	* include/bits/version.h (defined): Regenerate.
	* include/std/algorithm: Pull the feature-testing macro.
	* include/std/ranges: Likewise.
	* include/std/deque: Pull the feature-testing macro, add the default for std::erase.
	* include/std/forward_list: Likewise.
	* include/std/list: Likewise.
	* include/std/string: Likewise.
	* include/std/vector: Likewise.
	* include/bits/stl_algorithm_default.h: New file. Adds a macro
	to help with adding the default to the "classic STL" algorithms.
	* testsuite/23_containers/default_template_value.cc: New test.
	* testsuite/25_algorithms/default_template_value.cc: New test.

Signed-off-by: Giuseppe D'Angelo 
---
 libstdc++-v3/include/Makefile.am  |   1 +
 libstdc++-v3/include/Makefile.in  |   1 +
 libstdc++-v3/include/bits/algorithmfwd.h  |  62 +++--
 libstdc++-v3/include/bits/iterator_concepts.h |   9 +
 libstdc++-v3/include/bits/ranges_algo.h   | 227 --
 libstdc++-v3/include/bits/ranges_algobase.h   |  20 ++
 libstdc++-v3/include/bits/ranges_util.h   |  13 +
 .../include/bits/stl_algorithm_default.h  |  45 
 libstdc++-v3/include/bits/version.def |   8 +
 libstdc++-v3/include/bits/version.h   |  10 +
 .../include/pstl/glue_algorithm_defs.h|  23 +-
 libstdc++-v3/include/std/algorithm|   1 +
 libstdc++-v3/include/std/deque|   7 +-
 libstdc++-v3/include/std/forward_list |   7 +-
 libstdc++-v3/include/std/list |   7 +-
 libstdc++-v3/include/std/ranges   |   1 +
 libstdc++-v3/include/std/string   |   7 +-
 libstdc++-v3/include/std/vector   |   7 +-
 .../23_containers/default_template_value.cc   |  40 +++
 .../25_algorithms/default_template_value.cc   | 142 +++
 20 files changed, 589 insertions(+), 49 deletions(-)
 create mode 100644 libstdc++-v3/include/bits/stl_algorithm_default.h
 create mode 100644 libstdc++-v3/testsuite/23_containers/default_template_value.cc
 create mode 100644 libstdc++-v3/testsuite/25_algorithms/default_template_value.cc

diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 422a0f4bd0a..9da3f930dba 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -149,6 +149,7 @@ bits_freestanding = \
 	${bits_srcdir}/sat_arith.h \
 	${bits_srcdir}/stl_algo.h \
 	${bits_srcdir}/stl_algobase.h \
+	${bits_srcdir}/stl_algorithm_default.h \
 	${bits_srcdir}/stl_construct.h \
 	${bits_srcdir}/stl_function.h \
 	${bits_srcdir}/stl_iterator.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 9fd4ab4848c..2f39f484ab6 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -504,6 +504,7 @@ bits_freestanding = \
 	${bits_srcdir}/sat_arith.h \
 	${bits_srcdir}/stl_algo.h \
 	${bits_srcdir}/stl_algobase.h \
+	${bits_srcdir}/stl_algorithm_default.h \
 	${bits_srcdir}/stl_construct.h \
 	${bits_srcdir}/stl_function.h \
 	${bits_srcdir}/stl_iterator.h \
diff --git a/libstdc++-v3/include/bits/algorithmfwd.h b/libstdc++-v3/include/bits/algorithmfwd.h
index 34bf9921f43..2b93f35985f 100644
--- a/libstdc++-v3/include/bits/algorithmfwd.h
+++ b/libstdc++-v3/include/bits/

[pushed] c++, coroutines: Provide a CTOR for a callback object [NFC].

2024-08-02 Thread Iain Sandoe
Tested on x86_64-darwin, pushed to trunk as obvious, thanks
Iain

--- 8< ---

This provides and uses a CTOR to initialize the object used in
tree walks to track local variable uses.  This makes the idiom
used consistent.

gcc/cp/ChangeLog:

* coroutines.cc (struct local_vars_frame_data): Add a
CTOR.
(morph_fn_to_coro): Use CTOR for local_vars_frame_data
instead of brace init.

Signed-off-by: Iain Sandoe 
---
 gcc/cp/coroutines.cc | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 78a72047846..af03f5e0f74 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3989,10 +3989,14 @@ struct local_vars_frame_data
 {
   tree *field_list;
   hash_map *local_var_uses;
-  unsigned int nest_depth, bind_indx;
-  location_t loc;
-  bool saw_capture;
-  bool local_var_seen;
+  unsigned int nest_depth = 0;
+  unsigned int bind_indx = 0;
+  location_t loc = UNKNOWN_LOCATION;
+  bool saw_capture = false;
+  bool local_var_seen = false;
+
+  local_vars_frame_data (tree *_fl, hash_map *_lvu)
+: field_list (_fl), local_var_uses (_lvu) {}
 };
 
 /* A tree-walk callback that processes one bind expression noting local
@@ -4577,8 +4581,6 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
   /* Build our dummy coro frame layout.  */
   coro_frame_type = begin_class_definition (coro_frame_type);
 
-  /* The fields for the coro frame.  */
-  tree field_list = NULL_TREE;
 
   /* We need to know, and inspect, each suspend point in the function
  in several places.  It's convenient to place this map out of line
@@ -4592,10 +4594,13 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
   cp_walk_tree (&fnbody, await_statement_walker, &body_aw_points, NULL);
 
   /* 4. Now make space for local vars, this is conservative again, and we
- would expect to delete unused entries later.  */
+ would expect to delete unused entries later.  Compose the frame entries
+ list.  */
+
+  /* The fields for the coro frame.  */
+  tree field_list = NULL_TREE;
   hash_map local_var_uses;
-  local_vars_frame_data local_vars_data
-= {&field_list, &local_var_uses, 0, 0, fn_start, false, false};
+  local_vars_frame_data local_vars_data (&field_list, &local_var_uses);
   cp_walk_tree (&fnbody, register_local_var_uses, &local_vars_data, NULL);
 
   /* Tie off the struct for now, so that we can build offsets to the
-- 
2.39.2 (Apple Git-143)



[PATCH] c++, coroutines: Simplify separation of the user function body and ramp.

2024-08-02 Thread Iain Sandoe
This fixes a (so far unreported) bug where we would handle noexcept ramps
correctly, but omit exception specs - take this opportunity to simplify.
Tested on x86_64-darwin, OK for trunk?  
thanks
Iain

--- 8< ---

We need to separate the original user-authored function body from the
definition of the ramp function (which is what is called instead).
The function body tree is either in DECL_SAVED_TREE or the first operand
of current_eh_spec_block (for functions with an EH spec).
This version simplifies the process by extrating the second case directly
instead of inspecting the DECL_SAVED_TREE trees to discover it.

gcc/cp/ChangeLog:

* coroutines.cc (use_eh_spec_block): New.
(split_coroutine_body_from_ramp): New.
(morph_fn_to_coro): Use split_coroutine_body_from_ramp().

Signed-off-by: Iain Sandoe 
---
 gcc/cp/coroutines.cc | 97 
 1 file changed, 52 insertions(+), 45 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index af03f5e0f74..fc80a4ec24c 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -4437,6 +4437,50 @@ coro_rewrite_function_body (location_t fn_start, tree 
fnbody, tree orig,
   return update_body;
 }
 
+static bool
+use_eh_spec_block (tree fn)
+{
+  return (flag_exceptions && flag_enforce_eh_specs
+ && !type_throw_all_p (TREE_TYPE (fn)));
+}
+
+/* Extract the body of the function we are going to outline, leaving
+   to original function decl ready to build the ramp.  */
+
+static tree
+split_coroutine_body_from_ramp (tree fndecl, tree eh_spec_block)
+{
+  tree body;
+  /* Once we've tied off the original user-authored body in fn_body.
+ Start the replacement synthesized ramp body.  */
+
+  if (use_eh_spec_block (fndecl))
+{
+  body = pop_stmt_list (TREE_OPERAND (eh_spec_block, 0));
+  TREE_OPERAND (eh_spec_block, 0) = push_stmt_list ();
+}
+  else
+{
+  body = pop_stmt_list (DECL_SAVED_TREE (fndecl));
+  DECL_SAVED_TREE (fndecl) = push_stmt_list ();
+}
+
+  /* We can't validly get here with an empty statement list, since there's no
+ way for the FE to decide it's a coroutine in the absence of any code.  */
+  gcc_checking_assert (body != NULL_TREE);
+
+  /* If we have an empty or erroneous function body, do not try to transform it
+ since that would potentially wrap errors.  */
+  tree body_start = expr_first (body);
+  if (body_start == NULL_TREE || body_start == error_mark_node)
+{
+  /* Restore the original state.  */
+  add_stmt (body);
+  return NULL_TREE;
+}
+  return body;
+}
+
 /* Here we:
a) Check that the function and promise type are valid for a
   coroutine.
@@ -4483,57 +4527,22 @@ morph_fn_to_coro (tree orig, tree *resumer, tree 
*destroyer)
   /* Discard the body, we can't process it further.  */
   pop_stmt_list (DECL_SAVED_TREE (orig));
   DECL_SAVED_TREE (orig) = push_stmt_list ();
+  /* Match the expected nesting when an eh block is in use.  */
+  if (use_eh_spec_block (orig))
+   current_eh_spec_block = begin_eh_spec_block ();
   return false;
 }
 
-  /* We can't validly get here with an empty statement list, since there's no
- way for the FE to decide it's a coroutine in the absence of any code.  */
-  tree fnbody = pop_stmt_list (DECL_SAVED_TREE (orig));
-  gcc_checking_assert (fnbody != NULL_TREE);
-
   /* We don't have the locus of the opening brace - it's filled in later (and
  there doesn't really seem to be any easy way to get at it).
  The closing brace is assumed to be input_location.  */
   location_t fn_start = DECL_SOURCE_LOCATION (orig);
-  gcc_rich_location fn_start_loc (fn_start);
-
-  /* Initial processing of the function-body.
- If we have no expressions or just an error then punt.  */
-  tree body_start = expr_first (fnbody);
-  if (body_start == NULL_TREE || body_start == error_mark_node)
-{
-  DECL_SAVED_TREE (orig) = push_stmt_list ();
-  append_to_statement_list (fnbody, &DECL_SAVED_TREE (orig));
-  /* Suppress warnings about the missing return value.  */
-  suppress_warning (orig, OPT_Wreturn_type);
-  return false;
-}
-
-  /* So, we've tied off the original user-authored body in fn_body.
-
- Start the replacement synthesized ramp body as newbody.
- If we encounter a fatal error we might return a now-empty body.
 
- Note, the returned ramp body is not 'popped', to be compatible with
- the way that decl.cc handles regular functions, the scope pop is done
- in the caller.  */
-
-  tree newbody = push_stmt_list ();
-  DECL_SAVED_TREE (orig) = newbody;
-
-  /* If our original body is noexcept, then that's what we apply to our
- generated ramp, transfer any MUST_NOT_THOW_EXPR to that.  */
-  bool is_noexcept = TREE_CODE (body_start) == MUST_NOT_THROW_EXPR;
-  if (is_noexcept)
-{
-  /* The function body we will continue with is the single operand to
-the must-not-thro

Re: [PATCH v1] aarch64: Add fp8 scalar types

2024-08-02 Thread Richard Sandiford
Claudio Bantaloukas  writes:
> The ACLE defines a new scalar type, __mfp8. This is an opaque 8bit types that
> can only be used by fp8 intrinsics. Additionally, the mfloat8_t type is made
> available in arm_neon.h and arm_sve.h as an alias of the same.
>
> This implementation uses an INTEGER_TYPE, with precision 8 to represent
> __mfp8. Conversions to int and other types are disabled via the
> TARGET_INVALID_CONVERSION hook.
> Additionally, operations that are typically available to integer types are
> disabled via TARGET_INVALID_UNARY_OP and TARGET_INVALID_BINARY_OP hooks.
>
> gcc/ChangeLog:
>
>   * config/aarch64/aarch64-builtins.cc (aarch64_mfp8_type_node): Add node
>   for __mfp8 type.
>   (aarch64_mfp8_ptr_type_node): Add node for __mfp8 pointer type.
>   (aarch64_init_fp8_types): New function to initialise fp8 types and
>   register with language backends.
>   * config/aarch64/aarch64.cc (aarch64_invalid_conversion): Add function
>   implementing TARGET_INVALID_CONVERSION hook that blocks conversion to
>   and from __mfp8 type.
>   (aarch64_invalid_unary_op): Add function implementing TARGET_UNARY_OP
>   hook that blocks operations on __mfp8 other than &.
>   (aarch64_invalid_binary_op): Extend TARGET_BINARY_OP hook to disallow
>   operations on __mfp8 type.
>   (TARGET_INVALID_CONVERSION): Add define.
>   (TARGET_INVALID_UNARY_OP): Likewise.
>   * config/aarch64/aarch64.h (aarch64_mfp8_type_node): Add node for __mfp8
>   type.
>   (aarch64_mfp8_ptr_type_node): Add node for __mfp8 pointer type.
>   * config/aarch64/arm_neon.h (mfloat8_t): Add typedef.
>   * config/aarch64/arm_sve.h (mfloat8_t): Likewise.
>
> gcc/testsuite/ChangeLog:
>
>   * gcc.target/aarch64/fp8_scalar_1.c: New tests in C.
>   * gcc.target/aarch64/fp8_scalar_typecheck_1.c: Likewise.
>   * gcc.target/aarch64/fp8_scalar_typecheck_2.C: New tests in C++.

C++ tests should go in g++.target instead.

I think the new type needs to be mangled explicitly, so that the
overloads in:

  int foo(__mfp8) { return 1; }
  int foo(unsigned char) { return 2; }
  int bar(__mfp8 x) { return foo(x); }

are distinct.  It'd also be good to have a constexpr version of foo
in the tests, to make sure that the right overload is chosen.

> ---
>
> Hi, 
> Is this ok for master? I do not have commit rights yet, if ok, can someone 
> commit it on my behalf?
>
> Regression tested with aarch64-unknown-linux-gnu.
>
> Thanks,
> Claudio Bantaloukas
>
>  gcc/config/aarch64/aarch64-builtins.cc|  23 ++
>  gcc/config/aarch64/aarch64.cc |  60 +++
>  gcc/config/aarch64/aarch64.h  |   5 +
>  gcc/config/aarch64/arm_neon.h |   2 +
>  gcc/config/aarch64/arm_sve.h  |   1 +
>  .../gcc.target/aarch64/fp8_scalar_1.c | 108 ++
>  .../aarch64/fp8_scalar_typecheck_1.c  | 329 
>  .../aarch64/fp8_scalar_typecheck_2.C  | 354 ++
>  8 files changed, 882 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/fp8_scalar_1.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/fp8_scalar_typecheck_1.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/fp8_scalar_typecheck_2.C
>
> [...]
> @@ -1721,6 +1726,22 @@ aarch64_init_builtin_rsqrt (void)
>}
>  }
>  
> +static void
> +aarch64_init_fp8_types (void)

The function should have a comment before it.

> +{
> +  aarch64_mfp8_type_node = make_node (INTEGER_TYPE);
> +  TYPE_PRECISION (aarch64_mfp8_type_node) = 8;
> +  TYPE_MIN_VALUE (aarch64_mfp8_type_node)
> +  = TYPE_MIN_VALUE (unsigned_char_type_node);
> +  TYPE_MAX_VALUE (aarch64_mfp8_type_node)
> +  = TYPE_MAX_VALUE (unsigned_char_type_node);

If we're using the unsigned range, we should also set TYPE_UNSIGNED.
That said...

> +  layout_type (aarch64_mfp8_type_node);

...it looks like the code above could be replaced by:

  aarch64_mfp8_type_node = make_unsigned_type (8);

which would also give TYPE_MIN_VALUE and TYPE_MAX_VALUE the "right" types.

I was surprised that the tests worked so well with just a standard
integer type, without having to use build_distinct_type_copy.
But since they do, I agree we shouldn't use build_distinct_type_copy
unless a specific reason comes up.

> +  SET_TYPE_MODE (aarch64_mfp8_type_node, QImode);
> +
> +  lang_hooks.types.register_builtin_type (aarch64_mfp8_type_node, "__mfp8");
> +  aarch64_mfp8_ptr_type_node = build_pointer_type (aarch64_mfp8_type_node);
> +}
> +
>  /* Initialize the backend types that support the user-visible __fp16
> type, also initialize a pointer to that type, to be used when
> forming HFAs.  */
> @@ -2128,6 +2149,8 @@ aarch64_general_init_builtins (void)
>  {
>aarch64_init_fpsr_fpcr_builtins ();
>  
> +  aarch64_init_fp8_types ();
> +
>aarch64_init_fp16_types ();
>  
>aarch64_init_bf16_types ();
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc

Re: [PATCH 8/8]AArch64: take gather/scatter decode overhead into account

2024-08-02 Thread Richard Sandiford
Tamar Christina  writes:
>> -Original Message-
>> From: Tamar Christina 
>> Sent: Thursday, August 1, 2024 9:51 AM
>> To: Richard Sandiford 
>> Cc: Kyrylo Tkachov ; gcc-patches@gcc.gnu.org; nd
>> ; Richard Earnshaw ; Marcus
>> Shawcroft ; ktkac...@gcc.gnu.org
>> Subject: RE: [PATCH 8/8]AArch64: take gather/scatter decode overhead into
>> account
>>
>> > -Original Message-
>> > From: Richard Sandiford 
>> > Sent: Wednesday, July 31, 2024 7:17 PM
>> > To: Tamar Christina 
>> > Cc: Kyrylo Tkachov ; gcc-patches@gcc.gnu.org; nd
>> > ; Richard Earnshaw ; Marcus
>> > Shawcroft ; ktkac...@gcc.gnu.org
>> > Subject: Re: [PATCH 8/8]AArch64: take gather/scatter decode overhead into
>> > account
>> >
>> > Tamar Christina  writes:
>> > > @@ -289,6 +293,12 @@ struct sve_vec_cost : simd_vec_cost
>> > >const int gather_load_x32_cost;
>> > >const int gather_load_x64_cost;
>> > >
>> > > +  /* Additional loop initialization cost of using a gather load 
>> > > instruction.  The
>> x32
>> >
>> > Sorry for the trivia, but: long line.
>>
>> Yeah, noticed it after I sent out the patch 😊
>>
>> >
>> > > + value is for loads of 32-bit elements and the x64 value is for 
>> > > loads of
>> > > + 64-bit elements.  */
>> > > +  const int gather_load_x32_init_cost;
>> > > +  const int gather_load_x64_init_cost;
>> > > +
>> > >/* The per-element cost of a scatter store.  */
>> > >const int scatter_store_elt_cost;
>> > >  };
>> > > [...]
>> > > @@ -17291,6 +17295,20 @@ aarch64_vector_costs::add_stmt_cost (int
>> count,
>> > vect_cost_for_stmt kind,
>> > >   stmt_cost = aarch64_detect_vector_stmt_subtype (m_vinfo, kind,
>> > >   stmt_info, vectype,
>> > >   where, stmt_cost);
>> > > +
>> > > +  /* Check if we've seen an SVE gather/scatter operation and which 
>> > > size.  */
>> > > +  if (kind == scalar_load
>> > > +   && aarch64_sve_mode_p (TYPE_MODE (vectype))
>> > > +   && STMT_VINFO_MEMORY_ACCESS_TYPE (stmt_info) ==
>> > VMAT_GATHER_SCATTER)
>> > > + {
>> > > +   const sve_vec_cost *sve_costs = aarch64_tune_params.vec_costs->sve;
>> >
>> > I think we need to check whether this is nonnull, since not all tuning
>> > targets provide SVE costs.
>>
>> Will do, but I thought since this was in a block that checked
>> aarch64_use_new_vector_costs_p ()
>> that the SVE costs were required.  What does that predicate mean then?
>
> Ah nevermind, just realized it just means to apply the new vector cost 
> routines,
> I hadn't realized that we supported new costing for non-SVE models as well.
>
> Will add the check.

Yeah, the eventual plan was to remove aarch64_use_new_vector_costs_p
and make everything use the same path (without any changes to the
tuning structures being needed).  But it's never bubbled high enough
up the to-do list.

The reason for adding aarch64_use_new_vector_costs_p originally was
because the associated cost changes were made late in a release cycle,
and I didn't want to change the code for anything that didn't actively
need the new costs.

Thanks,
Richard


RE: Support streaming of poly_int for offloading when it's degree <= accel's NUM_POLY_INT_COEFFS

2024-08-02 Thread Prathamesh Kulkarni


> -Original Message-
> From: Jakub Jelinek 
> Sent: Wednesday, July 31, 2024 8:46 PM
> To: Prathamesh Kulkarni 
> Cc: Richard Biener ; Richard Sandiford
> ; gcc-patches@gcc.gnu.org
> Subject: Re: Support streaming of poly_int for offloading when it's
> degree <= accel's NUM_POLY_INT_COEFFS
> 
> External email: Use caution opening links or attachments
> 
> 
> On Wed, Jul 31, 2024 at 02:58:34PM +, Prathamesh Kulkarni wrote:
> > There are a couple of issues in the patch:
> > (1) The patch streams out NUM_POLY_INT_COEFFS at beginning of
> > mode_table, which should work for bp_unpack_poly_value, (since AFAIK,
> > it's only called by lto_input_mode_table). However, I am not sure if
> we will always call lto_input_mode_table before streaming in poly_int64
> / poly_uint64 ? Or should we stream out host NUM_POLY_INT_COEFFS at a
> different place in LTO bytecode ?
> 
> The poly_ints unpacked in lto_input_mode_table obviously are done after
> that.
> If you use it for streaming in from other sections, you need to check if
> they can't be read before the mode table.
> And, you don't really need to stream out/in the number for non-
> offloading LTO, that should use just NUM_POLY_INT_COEFFS.
> 
> > --- a/gcc/data-streamer-in.cc
> > +++ b/gcc/data-streamer-in.cc
> > @@ -183,9 +183,7 @@ poly_uint64
> >  streamer_read_poly_uint64 (class lto_input_block *ib)  {
> >poly_uint64 res;
> > -  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
> > -res.coeffs[i] = streamer_read_uhwi (ib);
> > -  return res;
> > +  POLY_INT_READ_COMMON(res, streamer_read_uhwi (ib))
> 
> Why is this macro and not an inline function or inline function template
> oor inline function calling a lambda?
> Even if it has to be a macro (I don't see why), it should be defined
> such that you need to add ; at the end, ideally not include the return
> res; in there because it is just too weird if used like that (or make it
> return what will be returned and use return POLY_INT_READ_COMMON...) and
> there needs to be a space in between COMMON and (.
> 
> > @@ -194,9 +192,7 @@ poly_int64
> >  streamer_read_poly_int64 (class lto_input_block *ib)  {
> >poly_int64 res;
> > -  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
> > -res.coeffs[i] = streamer_read_hwi (ib);
> > -  return res;
> > +  POLY_INT_READ_COMMON(res, streamer_read_hwi (ib))
> >  }
> 
> Ditto.
> > +   __typeof(x.coeffs[0]) val = streamer_read_coeff;
> \
> 
> You certainly can't use a GCC extension like __typeof here.
> Plus missing space.
> 
> > +   if (val != 0)
> \
> > + fatal_error (input_location,
> \
> > +  "Degree of % exceeds "
> \
> 
> Diagnostics shouldn't start with uppercase letter.
> 
> > +  "% (%d)",
> \
> > +  NUM_POLY_INT_COEFFS);
> \
> > + }
> \
> > +}
> \
> > +
> \
> > +  return x;
> \
> > +}
> > +
> > --- a/gcc/poly-int.h
> > +++ b/gcc/poly-int.h
> > @@ -354,6 +354,10 @@ struct poly_result
> > ? (void) ((RES).coeffs[I] = VALUE) \
> > : (void) ((RES).coeffs[I].~C (), new (&(RES).coeffs[I]) C
> > (VALUE)))
> >
> > +/* Number of bits needed to represent maximum value of
> > +   NUM_POLY_INT_COEFFS defined by any target.  */ #define
> > +MAX_NUM_POLY_INT_COEFFS_BITS (2)
> 
> Why (2) and not just 2?
> There should be some static_assert to make sure it is a maximum for any
> target.
> 
> > +   if (!integer_zerop (val))
> > + fatal_error (input_location,
> > +  "Degree of % exceeds "
> 
> Again.
Hi Jakub,
Thanks for the suggestions. The attached patch streams out NUM_POLY_INT_COEFFS 
only if offloading is enabled,
defines poly_int_read_common to be variadic template, and asserts that 
host_num_poly_int_coeffs is streamed-in
before reading poly_int (AFAIU, the only user of streamer_read_poly_int64 
currently is ipa-modref pass).

Patch passes LTO bootstrap+test on aarch64-linux-gnu and in-progress on 
x86_64-linux-gnu. To test this patch with
offloading enabled, I have so far just been testing libgomp (make 
check-target-libgomp). Should I be testing any
additional parts of the testsuite for offloading ?

Does the attached patch look in the right direction ?

Signed-off-by: Prathamesh Kulkarni 

Thanks,
Prathamesh
> > +  "%");
> > + }
> > +}
> >  }
> 
> Jakub

Partially support streaming of poly_int for offloading.

The patch streams out host NUM_POLY_INT_COEFFS, and changes
streaming in as follows:

if (host_num_poly_int_coeffs <= NUM_POLY_INT_COEFFS)
{
  for (i = 0; i < host_num_poly_int_coeffs; i++)
poly_int.coeffs[i] = stream_in coeff;
  for (; i < NUM_POLY_INT_COEFFS; i++)
poly_int.coeffs[i] = 0;
}
else
{
  for (i = 0; i < NUM_POLY_INT_COEFFS; i++)
poly_int.coeffs[i] = stream_in coeff;

  /* Ensure that degree of poly_int <= accel NUM_POLY_INT_COEFFS.  */ 
  for (; i < host_num_poly_int_coeffs; i++)
{
  val = stream_in coeff;
  if (val != 0)
error ();

Re: Support streaming of poly_int for offloading when it's degree <= accel's NUM_POLY_INT_COEFFS

2024-08-02 Thread Jakub Jelinek
On Fri, Aug 02, 2024 at 11:58:19AM +, Prathamesh Kulkarni wrote:
> diff --git a/gcc/data-streamer-in.cc b/gcc/data-streamer-in.cc
> index 7dce2928ef0..7b9d8cc0129 100644
> --- a/gcc/data-streamer-in.cc
> +++ b/gcc/data-streamer-in.cc
> @@ -182,10 +182,8 @@ streamer_read_hwi (class lto_input_block *ib)
>  poly_uint64
>  streamer_read_poly_uint64 (class lto_input_block *ib)
>  {
> -  poly_uint64 res;
> -  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
> -res.coeffs[i] = streamer_read_uhwi (ib);
> -  return res;
> +  return poly_int_read_common::coeff_type>
> +  (streamer_read_uhwi, ib);

Can't you use
  using coeff_type = poly_int_traits ::coeff_type;
  return poly_int_read_common  (streamer_read_uhwi, ib);
?
The call arguments on different line from the actual function name are
ugly.

> --- a/gcc/data-streamer.cc
> +++ b/gcc/data-streamer.cc
> @@ -28,6 +28,12 @@ along with GCC; see the file COPYING3.  If not see
>  #include "cgraph.h"
>  #include "data-streamer.h"
>  
> +/* For offloading -- While streaming-out, host NUM_POLY_INT_COEFFS is
> +   stored at beginning of mode_table. While streaming-in, the value is read 
> in
> +   host_num_poly_int_coeffs.  */
> +
> +unsigned host_num_poly_int_coeffs = 0;

I think it would be better to guard this with
#ifdef ACCEL_COMPILER.

> +template
> +poly_int
> +poly_int_read_common (F read_coeff, Args ...args)
> +{
> +  poly_int x;
> +  unsigned i;
> +
> +#ifndef ACCEL_COMPILER
> +  host_num_poly_int_coeffs = NUM_POLY_INT_COEFFS;
> +#endif

And instead of modifying a global var again and again do
#ifdef ACCEL_COMPILER
  const unsigned num_poly_int_coeffs = host_num_poly_int_coeffs;
  gcc_assert (num_poly_int_coeffs > 0);
#else
  const unsigned num_poly_int_coeffs = NUM_POLY_INT_COEFFS;
#endif
and use num_poly_int_coeffs in the functions.

Jakub



Re: [PATCH] libstdc++: add default template parameters to algorithms

2024-08-02 Thread Jonathan Wakely
On Fri, 2 Aug 2024 at 11:45, Giuseppe D'Angelo wrote:
>
> Hello,
>
> The attached patch adds support for P2248R8 + P3217R0 (Enabling
> list-initialization for algorithms, C++26). The big question is whether
> this keeps the code readable enough without introducing too much
> #ifdef-ery, so any feedback is appreciated.

Putting the extra args on the algorithmfwd.h declarations is a nice
way to avoid any clutter on the definitions. I think that is very
readable.
Another option would be to not touch those forward declarations, but
add new ones with the defaults:

#if __glibcxx_default_template_type_for_algorithm_values
// new declarations with default template args ...
#endif

But I think what you've done is good.

For ranges_algo.h I'm almost tempted to say we should just treat this
as a DR, to avoid the #ifdef-ery. Almost.
Is there any reason we can't rearrange the template parameters fo
C++20 and C++23 mode? I don't think users are allowed to use explicit
template argument lists for invoke e.g. ranges::find.operator() so it should be unobservable if we change the order for C++20
(and just don't add the default args until C++26). That might reduce
the differences to just a line or two for each CPO.

I think there's a misunderstanding about how this works:
+#define __glibcxx_want_default_template_type_for_algorithm_values
+#include 

For every standard __cpp_lib_foo feature test macro there is also an
internal __glibcxx_foo macro. The standard __cpp_lib_foo one should
*only* be defined in the headers that the standard documents to define
the macro (and in , which happens automatically). That
happens when you define __glibcxx_want_foo before including
, so that must only be done in the standard headers
that should define the __cpp_lib_foo version.

For this feature, the standard says:
#define __cpp_lib_default_template_type_for_algorithm_values MML  // also in
// , ,
// , , , , 
So you should put the __glibcxx_want_xxx macro in the headers named
above, but directly in the standard  header (and ,
etc.) not in  or any other internal detail headers.

It's wrong to use __glibcxx_want_foo in  and in
your new header.
The internal headers like  should use the
__glibcxx_foo macro, not the __cpp_lib_foo one. The __glibcxx_foo one
is defined without the "want" macro, so is always defined when the
feature is supported. That means you can test the __glibcxx_foo macro
after including  *without* saying you "want" the
standard __cpp_lib_foo macro.

I don't think that stuff is documented yet, so I'll put something like
the text above into the manual.

Minor comments:

+#if __glibcxx_default_template_type_for_algorithm_values // C++ >= 26
+  template _Proj>
+using projected_value_t = remove_cvref_t&>>;
+#endif

Please add a line break before the '=' to keep this line shorter.

+#if __glibcxx_default_template_type_for_algorithm_values
+template _Sent,
+ typename _Proj = identity, typename _Tp =
projected_value_t<_Iter, _Proj>>
+#else

And a line break after 'identity,' here please.


The new header has incorrect copyright info:
+// Copyright (C) 2007-2024 Free Software Foundation, Inc.
The dates are wrong, and you're contributing it under the DCO so
please use this form (with no dates):
// Copyright The GNU Toolchain Authors.
This is what I've been doing for all new files I add over the last few years.
The GPL and warranty text should remain, just change the copyright line.

**BUT** I don't think we should add a new header just for that anyway.
Hitting the filesystem to open a new header has a cost, and it's just
defining one macro anyway.
Could the macro just go in  ? Or stl_iterator_base_types?
Normally I'd say to put that kind of widely-used macro in
 but that doesn't work here because it depends on
the feature test macro in  which is included later.



Re: [PATCH] libstdc++: add default template parameters to algorithms

2024-08-02 Thread Jonathan Wakely
On Fri, 2 Aug 2024 at 13:17, Jonathan Wakely  wrote:
>
> On Fri, 2 Aug 2024 at 11:45, Giuseppe D'Angelo wrote:
> >
> > Hello,
> >
> > The attached patch adds support for P2248R8 + P3217R0 (Enabling
> > list-initialization for algorithms, C++26). The big question is whether
> > this keeps the code readable enough without introducing too much
> > #ifdef-ery, so any feedback is appreciated.
>
> Putting the extra args on the algorithmfwd.h declarations is a nice
> way to avoid any clutter on the definitions. I think that is very
> readable.
> Another option would be to not touch those forward declarations, but
> add new ones with the defaults:
>
> #if __glibcxx_default_template_type_for_algorithm_values
> // new declarations with default template args ...
> #endif
>
> But I think what you've done is good.
>
> For ranges_algo.h I'm almost tempted to say we should just treat this
> as a DR, to avoid the #ifdef-ery. Almost.
> Is there any reason we can't rearrange the template parameters fo
> C++20 and C++23 mode? I don't think users are allowed to use explicit
> template argument lists for invoke e.g. ranges::find.operator() Proj> so it should be unobservable if we change the order for C++20
> (and just don't add the default args until C++26). That might reduce
> the differences to just a line or two for each CPO.
>
> I think there's a misunderstanding about how this works:
> +#define __glibcxx_want_default_template_type_for_algorithm_values
> +#include 
>
> For every standard __cpp_lib_foo feature test macro there is also an
> internal __glibcxx_foo macro. The standard __cpp_lib_foo one should
> *only* be defined in the headers that the standard documents to define
> the macro (and in , which happens automatically). That
> happens when you define __glibcxx_want_foo before including
> , so that must only be done in the standard headers
> that should define the __cpp_lib_foo version.
>
> For this feature, the standard says:
> #define __cpp_lib_default_template_type_for_algorithm_values MML  // also 
> in
> // , ,
> // , , , , 
> So you should put the __glibcxx_want_xxx macro in the headers named
> above, but directly in the standard  header (and ,
> etc.) not in  or any other internal detail headers.
>
> It's wrong to use __glibcxx_want_foo in  and in
> your new header.
> The internal headers like  should use the
> __glibcxx_foo macro, not the __cpp_lib_foo one. The __glibcxx_foo one
> is defined without the "want" macro, so is always defined when the
> feature is supported. That means you can test the __glibcxx_foo macro
> after including  *without* saying you "want" the
> standard __cpp_lib_foo macro.
>
> I don't think that stuff is documented yet, so I'll put something like
> the text above into the manual.

Oh also, the editor renamed the feature test macro to
__cpp_lib_algorithm_default_value_type so it fits on the page ;-)
Your patch should use that, not the one in the proposal.

The merged wording also removes the redundant 'typename' from the
default arguments, but I think we might still need that for Clang
compat. I'm not sure when Clang fully implemented "down with
typename", but it was still causing issues some time last year.



Re: [PATCH] arm: Fix testism with mve/ivopts-3.c testcase

2024-08-02 Thread Christophe Lyon




On 8/1/24 14:54, Christophe Lyon wrote:



On 8/1/24 12:02, Andre Vieira (lists) wrote:



On 01/08/2024 10:09, Christophe Lyon wrote:


It seems your attachment contains only the commit message but lacks 
the actual patch?




I blame lack of coffee...

Thanks.


The patch LGTM.  It seems patchwork didn't recognize it, so Linaro CI 
will not run.




FWIW this probably even counts as obvious?

Thanks,

Christophe


Thanks,

Christophe


[PATCH] vect: Multistep float->int conversion only with no trapping math

2024-08-02 Thread Juergen Christ
Do not convert floats to ints in multiple step if trapping math is
enabled.  This might hide some inexact signals.

Also use correct sign (the sign of the target integer type) for the
intermediate steps.  This only affects undefined behaviour (casting
floats to unsigned datatype where the float is negative).

gcc/ChangeLog:

* tree-vect-stmts.cc (vectorizable_conversion): multi-step
  float to int conversion only with trapping math and correct
  sign.

Signed-off-by: Juergen Christ 

Bootstrapped and tested on x84 and s390.  Ok for trunk?

---
 gcc/tree-vect-stmts.cc | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index fdcda0d2abae..2ddd13383193 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -5448,7 +5448,8 @@ vectorizable_conversion (vec_info *vinfo,
break;
 
  cvt_type
-   = build_nonstandard_integer_type (GET_MODE_BITSIZE (rhs_mode), 0);
+   = build_nonstandard_integer_type (GET_MODE_BITSIZE (rhs_mode),
+ TYPE_UNSIGNED (lhs_type));
  cvt_type = get_same_sized_vectype (cvt_type, vectype_in);
  if (cvt_type == NULL_TREE)
goto unsupported;
@@ -5505,10 +5506,11 @@ vectorizable_conversion (vec_info *vinfo,
   if (GET_MODE_SIZE (lhs_mode) >= GET_MODE_SIZE (rhs_mode))
goto unsupported;
 
-  if (code == FIX_TRUNC_EXPR)
+  if (code == FIX_TRUNC_EXPR && !flag_trapping_math)
{
  cvt_type
-   = build_nonstandard_integer_type (GET_MODE_BITSIZE (rhs_mode), 0);
+   = build_nonstandard_integer_type (GET_MODE_BITSIZE (rhs_mode),
+ TYPE_UNSIGNED (lhs_type));
  cvt_type = get_same_sized_vectype (cvt_type, vectype_in);
  if (cvt_type == NULL_TREE)
goto unsupported;
-- 
2.43.5



[PATCH] middle-end/111821 - compile-time/memory-hog with large copy

2024-08-02 Thread Richard Biener
The following fixes a compile-time/memory-hog when performing a
large aggregate copy to a small object allocated to a register.
While store_bit_field_1 called by store_integral_bit_field will
do nothign for accesses outside of the target the loop over the
source in store_integral_bit_field will still code-generate
the read parts for all words in the source.  The following copies
the noop condition from store_bit_field_1 and terminates the
loop when it runs forward or avoid code-generating the read parts
when not.

Bootstrapped and tested on x86_64-unknown-linux-gnu, OK?

Thanks,
Richard.

PR middle-end/111821
* expmed.cc (store_integral_bit_field): Terminate the
word-wise copy loop when we get out of the destination
and do a forward copy.  Skip the word if it would be
outside of the destination in case of a backward copy.

* gcc.dg/torture/pr111821.c: New testcase.
---
 gcc/expmed.cc   | 12 
 gcc/testsuite/gcc.dg/torture/pr111821.c |  9 +
 2 files changed, 21 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr111821.c

diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index 154964bd068..2ca93e30e8f 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -986,6 +986,18 @@ store_integral_bit_field (rtx op0, opt_scalar_int_mode 
op0_mode,
= backwards ^ reverse
  ? MAX ((int) bitsize - (i + 1) * BITS_PER_WORD, 0)
  : i * BITS_PER_WORD;
+
+ /* No further action is needed if the target is a register and if
+this field lies completely outside that register.  */
+ if (REG_P (op0) && known_ge (bitnum + bit_offset,
+  GET_MODE_BITSIZE (GET_MODE (op0
+   {
+ if (backwards ^ reverse)
+   continue;
+ /* For forward operation we are finished.  */
+ return true;
+   }
+
  /* Starting word number in the value.  */
  const unsigned int wordnum
= backwards
diff --git a/gcc/testsuite/gcc.dg/torture/pr111821.c 
b/gcc/testsuite/gcc.dg/torture/pr111821.c
new file mode 100644
index 000..eec6eed6c8e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr111821.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+
+typedef union { char a[__INT_MAX__ / 4]; } T;
+unsigned short f(const void *p)
+{
+  unsigned short v;
+  *(T *)(void *)(&v) = *(const T *)p;
+  return v;
+}
-- 
2.43.0


Re: [PATCH] fortran: Support optional dummy as BACK argument of MINLOC/MAXLOC.

2024-08-02 Thread Mikael Morin

Le 01/08/2024 à 21:02, Thomas Koenig a écrit :

Hi Mikael,


+  gcc_assert (backexpr->expr_type == EXPR_VARIABLE);


drop it, downgrade to checking, or is it worth?

Whether it is worth it, I don't know; it's protecting the access to 
backexpr->symtree a few lines down, idependently of the implementation 
of maybe_absent_optional_variable.


I expect the compiler to optimize it away, so I can surely make it a 
checking-only assert.


I would also lean towards checking only.

OK with that change (or, if you really prefer, as submitted is also
fine).

Thanks for the patch!  It's good to see so much progress...

Best regards

 Thomas


Thanks to you and Bernhard.
This is what I'm going to push.From 40122a405386a8b67c11bbaad523ffce5c1c7855 Mon Sep 17 00:00:00 2001
From: Mikael Morin 
Date: Fri, 2 Aug 2024 14:24:34 +0200
Subject: [PATCH] fortran: Support optional dummy as BACK argument of
 MINLOC/MAXLOC.

Protect the evaluation of BACK with a check that the reference is non-null
in case the expression is an optional dummy, in the inline code generated
for MINLOC and MAXLOC.

This change contains a revert of the non-testsuite part of commit
r15-1994-ga55d24b3cf7f4d07492bb8e6fcee557175b47ea3, which factored the
evaluation of BACK out of the loop using the scalarizer.  It was a bad idea,
because delegating the argument evaluation to the scalarizer makes it
cumbersome to add a null pointer check next to the evaluation.

Instead, evaluate BACK at the beginning, before scalarization, add a check
that the argument is present if necessary, and evaluate the resulting
expression to a variable, before using the variable in the inline code.

gcc/fortran/ChangeLog:

	* trans-intrinsic.cc (maybe_absent_optional_variable): New function.
	(gfc_conv_intrinsic_minmaxloc): Remove BACK from scalarization and
	evaluate it before.  Add a check that BACK is not null if the
	expression is an optional dummy.  Save the resulting expression to a
	variable.  Use the variable in the generated inline code.

gcc/testsuite/ChangeLog:

	* gfortran.dg/maxloc_6.f90: New test.
	* gfortran.dg/minloc_7.f90: New test.
---
 gcc/fortran/trans-intrinsic.cc |  83 +-
 gcc/testsuite/gfortran.dg/maxloc_6.f90 | 366 +
 gcc/testsuite/gfortran.dg/minloc_7.f90 | 366 +
 3 files changed, 801 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/gfortran.dg/maxloc_6.f90
 create mode 100644 gcc/testsuite/gfortran.dg/minloc_7.f90

diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc
index 180d0d7a88c..150cb9ff963 100644
--- a/gcc/fortran/trans-intrinsic.cc
+++ b/gcc/fortran/trans-intrinsic.cc
@@ -5209,6 +5209,50 @@ gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
 }
 
 
+/* Tells whether the expression E is a reference to an optional variable whose
+   presence is not known at compile time.  Those are variable references without
+   subreference; if there is a subreference, we can assume the variable is
+   present.  We have to special case full arrays, which we represent with a fake
+   "full" reference, and class descriptors for which a reference to data is not
+   really a subreference.  */
+
+bool
+maybe_absent_optional_variable (gfc_expr *e)
+{
+  if (!(e && e->expr_type == EXPR_VARIABLE))
+return false;
+
+  gfc_symbol *sym = e->symtree->n.sym;
+  if (!sym->attr.optional)
+return false;
+
+  gfc_ref *ref = e->ref;
+  if (ref == nullptr)
+return true;
+
+  if (ref->type == REF_ARRAY
+  && ref->u.ar.type == AR_FULL
+  && ref->next == nullptr)
+return true;
+
+  if (!(sym->ts.type == BT_CLASS
+	&& ref->type == REF_COMPONENT
+	&& ref->u.c.component == CLASS_DATA (sym)))
+return false;
+
+  gfc_ref *next_ref = ref->next;
+  if (next_ref == nullptr)
+return true;
+
+  if (next_ref->type == REF_ARRAY
+  && next_ref->u.ar.type == AR_FULL
+  && next_ref->next == nullptr)
+return true;
+
+  return false;
+}
+
+
 /* Remove unneeded kind= argument from actual argument list when the
result conversion is dealt with in a different place.  */
 
@@ -5321,11 +5365,11 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
   tree nonempty;
   tree lab1, lab2;
   tree b_if, b_else;
+  tree back;
   gfc_loopinfo loop;
   gfc_actual_arglist *actual;
   gfc_ss *arrayss;
   gfc_ss *maskss;
-  gfc_ss *backss;
   gfc_se arrayse;
   gfc_se maskse;
   gfc_expr *arrayexpr;
@@ -5391,10 +5435,29 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
 && maskexpr->symtree->n.sym->attr.dummy
 && maskexpr->symtree->n.sym->attr.optional;
   backexpr = actual->next->next->expr;
-  if (backexpr)
-backss = gfc_get_scalar_ss (gfc_ss_terminator, backexpr);
+
+  gfc_init_se (&backse, NULL);
+  if (backexpr == nullptr)
+back = logical_false_node;
+  else if (maybe_absent_optional_variable (backexpr))
+{
+  /* This should have been checked already by
+	 maybe_abse

Re: [PATCH] RISC-V: Improve length attributes for atomic insn sequences

2024-08-02 Thread Jeff Law




On 8/1/24 10:25 PM, Patrick O'Neill wrote:

gcc/ChangeLog:

* config/riscv/sync-rvwmo.md: Add conditional length attributes.
* config/riscv/sync-ztso.md: Ditto.
* config/riscv/sync.md: Fix incorrect insn length attributes and
reformat existing conditional checks.

OK
jeff



Re: [PATCH] genemit: Fix handling of explicit parallels for clobbers [PR116058]

2024-08-02 Thread Jeff Law




On 8/1/24 7:51 PM, Andrew Pinski wrote:

In a define_insn, you could use either an explicit parallel for
the insns or genrecog/genemit will add one for you.
The problem when genemit is processing the pattern for clobbers
(to create the function add_clobbers), genemit hadn't add the implicit
parallel yet but at the same time forgot to ignore that there
could be an explicit parallel there.
This means in some cases (like in the sh backend), add_clobbers
and recog had a different idea if there was clobbers on the insn.
This fixes the problem by looking through the explicit parallel
for the instruction in genemit.

Bootstrapped and tested on x86_64-linux-gnu.

PR middle-end/116058

gcc/ChangeLog:

* genemit.cc (struct clobber_pat): Change pattern to be rtvec.
Add code field.
(gen_insn): Look through an explicit parallel if there was one.
Update store to new clobber_pat.
(output_add_clobbers): Update call to gen_exp for the changed
clobber_pat.

Richard S. effectively ack'd in the BZ.  So Ok for the trunk.

jeff



Re: [PATCH] c++, coroutines: Simplify separation of the user function body and ramp.

2024-08-02 Thread Jason Merrill

On 8/2/24 6:50 AM, Iain Sandoe wrote:

This fixes a (so far unreported) bug where we would handle noexcept ramps
correctly, but omit exception specs - take this opportunity to simplify.
Tested on x86_64-darwin, OK for trunk?
thanks
Iain

--- 8< ---

We need to separate the original user-authored function body from the
definition of the ramp function (which is what is called instead).
The function body tree is either in DECL_SAVED_TREE or the first operand
of current_eh_spec_block (for functions with an EH spec).
This version simplifies the process by extrating the second case directly


typo


instead of inspecting the DECL_SAVED_TREE trees to discover it.

gcc/cp/ChangeLog:

* coroutines.cc (use_eh_spec_block): New.
(split_coroutine_body_from_ramp): New.
(morph_fn_to_coro): Use split_coroutine_body_from_ramp().

Signed-off-by: Iain Sandoe 
---
  gcc/cp/coroutines.cc | 97 
  1 file changed, 52 insertions(+), 45 deletions(-)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index af03f5e0f74..fc80a4ec24c 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -4437,6 +4437,50 @@ coro_rewrite_function_body (location_t fn_start, tree 
fnbody, tree orig,
return update_body;
  }
  
+static bool

+use_eh_spec_block (tree fn)
+{
+  return (flag_exceptions && flag_enforce_eh_specs
+ && !type_throw_all_p (TREE_TYPE (fn)));
+}


Rather than (partially) duplicate this function, let's make the one in 
decl.cc non-static.



+/* Extract the body of the function we are going to outline, leaving
+   to original function decl ready to build the ramp.  */
+
+static tree
+split_coroutine_body_from_ramp (tree fndecl, tree eh_spec_block)


Rather than pass current_eh_spec_block into this function through a 
parameter, why not refer to it directly?


Jason



Re: [PATCH] lra: emit caller-save register spills before call insn [PR116028]

2024-08-02 Thread Jeff Law




On 8/1/24 4:12 AM, Surya Kumari Jangala wrote:

lra: emit caller-save register spills before call insn [PR116028]

LRA emits insns to save caller-save registers in the
inheritance/splitting pass. In this pass, LRA builds EBBs (Extended
Basic Block) and traverses the insns in the EBBs in reverse order from
the last insn to the first insn. When LRA sees a write to a pseudo (that
has been assigned a caller-save register), and there is a read following
the write, with an intervening call insn between the write and read,
then LRA generates a spill immediately after the write and a restore
immediately before the read. The spill is needed because the call insn
will clobber the caller-save register.

If there is a write insn and a call insn in two separate BBs but
belonging to the same EBB, the spill insn gets generated in the BB
containing the write insn. If the write insn is in the entry BB, then
the spill insn that is generated in the entry BB prevents shrink wrap
from happening. This is because the spill insn references the stack
pointer and hence the prolog gets generated in the entry BB itself.

This patch ensures that the spill insn is generated before the call insn
instead of after the write. This is also more efficient as the spill now
occurs only in the path containing the call.

2024-08-01  Surya Kumari Jangala  

gcc/
PR rtl-optimization/PR116028
* lra-constraints.cc (split_reg): Spill register before call
insn.
(latest_call_insn): New variable.
(inherit_in_ebb): Track the latest call insn.

gcc/testsuite/
PR rtl-optimization/PR116028
* gcc.dg/ira-shrinkwrap-prep-1.c: Remove xfail for powerpc.
* gcc.dg/pr10474.c: Remove xfail for powerpc.
Implementation looks fine.  I would suggest a comment indicating why 
we're inserting before last_call_insn.  Otherwise someone in the future 
would have to find the patch submission to know why we're handling that 
case specially.


OK with that additional comment.

Thanks,
jeff


Re: [PATCH v2] RISC-V: Add --with-cmodel configure option

2024-08-02 Thread Jeff Law




On 8/1/24 11:11 PM, Hau Hsu wrote:

Sometimes we want to use default cmodel other than medlow. Add a GCC
configure option for that.

gcc/ChangeLog:

 * config.gcc (riscv*-*-*): Add support for --with-cmodel configure option.
 * config/riscv/riscv.h (TARGET_RISCV_DEFAULT_CMODEL): Define default 
cmodel.
 * configure: Regenerate.
 * configure.ac: Add --with-cmodel configure option.
 * doc/install.texi: Document --with-cmodel configure option.
 * doc/invoke.texi (-mcmodel): Mention --with-cmodel configure option.
I thought Palmer had submitted an equivalent patch a while back, but I 
can't seem to find it.



It looks like pre-commit testing has flagged this as failing to build on 
arm/aarch64.  I'm not as familiar with that system, so I don't know 
exactly what it's complaining about other than the configuration step 
for GCC failed.



https://patchwork.sourceware.org/project/gcc/patch/20240802051151.3658614-1-hau@sifive.com/

# reset_artifacts:
-10
# true:
0
# build_abe gcc:
# FAILED
# First few build errors in logs:
# 00:01:36 make[1]: *** [Makefile:4646: configure-gcc] Error 1
# 00:01:36 make: *** [Makefile:1065: all] Error 2






[PATCH v2] c++/coroutines: check for members we use in handle_types [PR105475]

2024-08-02 Thread Arsen Arsenović
Jason Merrill  writes:

> I don't think these names need to mention "baselink", but I'm not strongly
> against it.

It doesn't fit with the rest of the codebase either, so I'll rename
them.

> A few other tweaks below:
>
>> @@ -90,6 +90,7 @@ struct GTY((for_user)) coroutine_info
>> tree self_h_proxy;  /* A handle instance that is used as the proxy for 
>> the
>>   one that will eventually be allocated in the coroutine
>>   frame.  */
>> +  tree from_address_bl;  /* handle_type from_address function (BASELINK).  
>> */
>
> Inserting this here breaks the "Likewise" reference in the next line.

Ah, true.  Swapped it with the next line.

>> tree promise_proxy; /* Likewise, a proxy promise instance.  */
>> tree return_void;   /* The expression for p.return_void() if it exists.  
>> */
>> location_t first_coro_keyword; /* The location of the keyword that made 
>> this
>> @@ -389,7 +389,105 @@ find_coro_handle_template_decl (location_t kw)
>>   return handle_decl;
>>   }
>>   -/* Instantiate the handle template for a given promise type.  */
>> +/* Get and validate HANDLE_TYPE#address.  The resulting function, if any, 
>> will
>
> :: instead of #

Fixed.

>> +   be a non-overloaded member function that takes no arguments and returns
>> +   void*.  If that is not the case, signals an error and returns NULL_TREE. 
>>  */
>> +
>> +static tree
>> +get_handle_type_address_bl (location_t kw, tree handle_type)
>> +{
>> +  tree addr_getter = lookup_member (handle_type, coro_address_identifier, 1,
>> +0, tf_warning_or_error);
>> +  if (!addr_getter || addr_getter == error_mark_node)
>> +{
>> +  error_at (kw, "could not find %qE in %qT",
>> +coro_address_identifier, handle_type);
>
> How about using qualified_name_lookup_error?

That seems to work, if the following usage is correct:

  tree addr_getter = lookup_member (handle_type, coro_address_identifier, 1,
0, tf_warning_or_error);
  if (!addr_getter || addr_getter == error_mark_node)
{
  qualified_name_lookup_error (handle_type, coro_address_identifier,
   error_mark_node, kw);
  // notably the error_mark_node above, since it seems that
  // qualified_name_lookup_error accesses DECL.
  return NULL_TREE;
}

>> +  gcc_assert (TREE_CODE (addr_getter) == BASELINK);
>
> This looks like it will ICE on an invalid handle type (e.g. where "address" is
> a type or data member) instead of giving an error.

Ah, good point.  I'll fix that and add the testcases for it.

>> +  tree fn_t = TREE_TYPE (addr_getter);
>> +  if (TREE_CODE (fn_t) != METHOD_TYPE)
>> +{
>> +  error_at (kw, "%qE must be a non-overloaded method", addr_getter);
>> +  return NULL_TREE;
>> +}
>> +
>> +  tree arg = TYPE_ARG_TYPES (fn_t);
>> +  /* Given that this is a method, we have an argument to skip (the this
>> + pointer).  */
>> +  gcc_checking_assert (TREE_CHAIN (arg));
>
> This assert seems redundant with the following checks.
>
>> +  arg = TREE_CHAIN (arg);
>> +
>> +  /* Check that from_addr has the argument list ().  */
>> +  if (!arg
>> +  || !same_type_p (TREE_VALUE (arg), void_type_node)
>> +  || TREE_CHAIN (arg))
>> +{
>> +  error_at (kw, "%qE must take no arguments", addr_getter);
>> +  return NULL_TREE;
>> +}
>
> I think this could just be
>
> if (arg != void_list_node)
>
> as we share the terminal void between all non-varargs function types.

Yes, seems so.  I've addressed both comments above.

>> +  tree ret_t = TREE_TYPE (fn_t);
>> +  if (!same_type_p (ret_t, ptr_type_node))
>> +{
>> +  error_at (kw, "%qE must return %qT, not %qT",
>> +addr_getter, ptr_type_node, ret_t);
>> +  return NULL_TREE;
>> +}
>
> Do you also want to check that it has public access?

lookup_member checks access already, and we can recover from that error
AFAICT, so it might be best to leave it.

(I think leaving the check out permits the user to craft particular
invalid code, e.g. when they place a coroutine inside a class inheriting
from coroutine handle but make the methods protected, but as long as the
compiler does not crash, I think this is good enough - I don't think we
ought to verify here that the declaration matches the spec)

>> @@ -454,10 +552,15 @@ ensure_coro_initialized (location_t loc)
>>   /*  We can also instantiate the void coroutine_handle<>  */
>> void_coro_handle_type =
>> -instantiate_coro_handle_for_promise_type (loc, NULL_TREE);
>> +instantiate_coro_handle_for_promise_type (loc, void_type_node);
>> if (void_coro_handle_type == NULL_TREE)
>>  return false;
>>   +  void_coro_handle_address =
>> +get_handle_type_address_bl (loc, void_coro_handle_type);
>
> The = should be at the beginning of the second line for both variables.

Fixed.

>> @@ -2365,8 +2480,9 @@ build_actor_fn (location_t loc,

Re: [PATCH] fortran: Fix a pasto in gfc_check_dependency

2024-08-02 Thread Mikael Morin

Le 02/08/2024 à 10:12, Jakub Jelinek a écrit :

On Thu, Aug 01, 2024 at 09:03:39PM +0200, Mikael Morin wrote:

Le 01/08/2024 à 12:00, Jakub Jelinek a écrit :

Hi!

A static analyzer found what seems like a pasto in the PR45019 changes,
the second branch of || only accesses sym2 while the first one sym1 except
for this one spot.

Not sure I'm able to construct a testcase for this though.


What is reported exactly by the static analyzer?


I'm not sure I'm allowed to cite it, it is some proprietary static analyzer
and I got that indirectly.  But if I paraphrase it, the diagnostics was
a possible pasto.  The static analyzer likely doesn't see that
sym1->attr.target implies attr1.target and sym2->attr.target implies
attr2.target.


This looks like dead code to me.


Seems it wasn't originally dead when it was added in PR45019, but then the
PR62278 change made it dead.

nods


But the function actually returns 0 rather than 1 that PR45019 meant.
So I bet in addition to fixing the pasto we should move that conditional
from where it is right now to the return 0; location after
check_data_pointer_types calls.

No, the function check_data_pointer_types returns true if there is no 
aliasing, according to its function comment, so after both calls 
everything is safe and returning anything but 0 is overly pessimistic.


I'm inclined to just remove the dead code.

By the way, looking for a testcase exercising gfc_check_dependency, I 
found an example showing check_data_pointer_types is not up to its 
promise.  This is https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116196



What I wonder is why the testcase doesn't actually fail.


From https://gcc.gnu.org/bugzilla/show_bug.cgi?id=45019#c7 :

I think the patch below looks fine, however, if I set a break point, the function 
"gfc_check_dependency" is never called for test program.


So the dependency.c part of the patch is not exercised by the testcase.


And the pasto fix would guess fix
aliasing_dummy_5.f90 with
 arg(2:3) = arr(1:2)
instead of
 arr(2:3) = arg(1:2)
if the original testcase would actually fail.


Mmh, aren't they both actually the same?



Re: [PATCH] aarch64: Fuse CMP+CSEL and CMP+CSET for -mcpu=neoverse-v2

2024-08-02 Thread Richard Sandiford
Jennifer Schmitz  writes:
> Dear Richard,
> Thanks for the feedback! I made the changes as suggested. Here is the updated 
> patch, bootstrapped and tested again.
> Best,
> Jennifer

LGTM, thanks.  Pushed to trunk with some minor reindentation:

  if ((prev_type == TYPE_ALUS_SREG || prev_type == TYPE_ALUS_IMM)
  && ((aarch64_fusion_enabled_p (AARCH64_FUSE_CMP_CSEL)
   && GET_CODE (SET_SRC (curr_set)) == IF_THEN_ELSE
   && aarch64_reg_or_zero (XEXP (SET_SRC (curr_set), 1), VOIDmode)
   && aarch64_reg_or_zero (XEXP (SET_SRC (curr_set), 2), VOIDmode)
   && SCALAR_INT_MODE_P (GET_MODE (XEXP (SET_SRC (curr_set), 1
  || (aarch64_fusion_enabled_p (AARCH64_FUSE_CMP_CSET)
  && GET_RTX_CLASS (GET_CODE (SET_SRC (curr_set)))
 == RTX_COMPARE
  && REG_P (SET_DEST (curr_set)
return true;

Richard

>
>
>
>> On 31 Jul 2024, at 21:21, Richard Sandiford  
>> wrote:
>> 
>> External email: Use caution opening links or attachments
>> 
>> 
>> Jennifer Schmitz  writes:
>>> Thanks for the feedback! I updated the patch based on your comments, more 
>>> detailed comments inline below. The updated version was bootstrapped and 
>>> tested again, no regression.
>>> Best,
>>> Jennifer
>>> 
>>> From 89936b7bc2de7a1e4bc55c3a1e8d5e6ac0de579d Mon Sep 17 00:00:00 2001
>>> From: Jennifer Schmitz 
>>> Date: Wed, 24 Jul 2024 06:13:59 -0700
>>> Subject: [PATCH] AArch64: Fuse CMP+CSEL and CMP+CSET for -mcpu=neoverse-v2
>>> 
>>> According to the Neoverse V2 Software Optimization Guide (section 4.14), the
>>> instruction pairs CMP+CSEL and CMP+CSET can be fused, which had not been
>>> implemented so far. This patch implements and tests the two fusion pairs.
>>> 
>>> The patch was bootstrapped and regtested on aarch64-linux-gnu, no 
>>> regression.
>>> There was also no non-noise impact on SPEC CPU2017 benchmark.
>>> OK for mainline?
>>> 
>>> Signed-off-by: Jennifer Schmitz 
>>> 
>>> gcc/
>>> 
>>>  * config/aarch64/aarch64.cc (aarch_macro_fusion_pair_p): Implement
>>>  fusion logic.
>>>  * config/aarch64/aarch64-fusion-pairs.def (cmp+csel): New entry.
>>>  (cmp+cset): Likewise.
>>>  * config/aarch64/tuning_models/neoversev2.h: Enable logic in
>>>  field fusible_ops.
>>> 
>>> gcc/testsuite/
>>> 
>>>  * gcc.target/aarch64/fuse_cmp_csel.c: New test.
>>>  * gcc.target/aarch64/fuse_cmp_cset.c: Likewise.
>>> ---
>>> gcc/config/aarch64/aarch64-fusion-pairs.def   |  2 ++
>>> gcc/config/aarch64/aarch64.cc | 20 +++
>>> gcc/config/aarch64/tuning_models/neoversev2.h |  5 ++-
>>> .../gcc.target/aarch64/fuse_cmp_csel.c| 33 +++
>>> .../gcc.target/aarch64/fuse_cmp_cset.c| 31 +
>>> 5 files changed, 90 insertions(+), 1 deletion(-)
>>> create mode 100644 gcc/testsuite/gcc.target/aarch64/fuse_cmp_csel.c
>>> create mode 100644 gcc/testsuite/gcc.target/aarch64/fuse_cmp_cset.c
>>> 
>>> diff --git a/gcc/config/aarch64/aarch64-fusion-pairs.def 
>>> b/gcc/config/aarch64/aarch64-fusion-pairs.def
>>> index 9a43b0c8065..bf5e85ba8fe 100644
>>> --- a/gcc/config/aarch64/aarch64-fusion-pairs.def
>>> +++ b/gcc/config/aarch64/aarch64-fusion-pairs.def
>>> @@ -37,5 +37,7 @@ AARCH64_FUSION_PAIR ("aes+aesmc", AES_AESMC)
>>> AARCH64_FUSION_PAIR ("alu+branch", ALU_BRANCH)
>>> AARCH64_FUSION_PAIR ("alu+cbz", ALU_CBZ)
>>> AARCH64_FUSION_PAIR ("addsub_2reg_const1", ADDSUB_2REG_CONST1)
>>> +AARCH64_FUSION_PAIR ("cmp+csel", CMP_CSEL)
>>> +AARCH64_FUSION_PAIR ("cmp+cset", CMP_CSET)
>>> 
>>> #undef AARCH64_FUSION_PAIR
>>> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
>>> index e0cf382998c..d42c153443e 100644
>>> --- a/gcc/config/aarch64/aarch64.cc
>>> +++ b/gcc/config/aarch64/aarch64.cc
>>> @@ -27345,6 +27345,26 @@ aarch_macro_fusion_pair_p (rtx_insn *prev, 
>>> rtx_insn *curr)
>>>   && reg_referenced_p (SET_DEST (prev_set), PATTERN (curr)))
>>> return true;
>>> 
>>> +  /* Fuse CMP and CSEL/CSET.  */
>>> +  if (prev_set && curr_set
>>> +  && GET_CODE (SET_SRC (prev_set)) == COMPARE
>>> +  && SCALAR_INT_MODE_P (GET_MODE (XEXP (SET_SRC (prev_set), 0)))
>>> +  && reg_referenced_p (SET_DEST (prev_set), PATTERN (curr)))
>>> +{
>>> +  enum attr_type prev_type = get_attr_type (prev);
>>> +  if ((prev_type == TYPE_ALUS_SREG || prev_type == TYPE_ALUS_IMM)
>>> +&& (aarch64_fusion_enabled_p (AARCH64_FUSE_CMP_CSEL)
>>> +&& GET_CODE (SET_SRC (curr_set)) == IF_THEN_ELSE
>>> +&& REG_P (XEXP (SET_SRC (curr_set), 1))
>>> +&& REG_P (XEXP (SET_SRC (curr_set), 2))
>> 
>> Gah, I'd meant to say this in a previous review, but now realise
>> that I forgot.  I think these REG_Ps can be relaxed to:
>> 
>>   && aarch64_reg_or_zero (XEXP (SET_SRC (curr_set), N), VOIDmode)
>> 
>> since CSEL can take w/xzr.
> Done.
>> 
>>> +&& SCALAR_INT_MODE_P (GET_MODE (XEXP

Re: [PATCH] fortran: Fix a pasto in gfc_check_dependency

2024-08-02 Thread Jakub Jelinek
On Fri, Aug 02, 2024 at 04:58:09PM +0200, Mikael Morin wrote:
> > But the function actually returns 0 rather than 1 that PR45019 meant.
> > So I bet in addition to fixing the pasto we should move that conditional
> > from where it is right now to the return 0; location after
> > check_data_pointer_types calls.
> > 
> No, the function check_data_pointer_types returns true if there is no
> aliasing, according to its function comment, so after both calls everything
> is safe and returning anything but 0 is overly pessimistic.

My (limited) understanding is that the original PR is about some corner case
in the standard wording where in order to allow aliasing of TARGET vars with
POINTER vars it also makes valid the weirdo stuff in the testcase.

And so should return 1 which means that they possibly alias.

> > And the pasto fix would guess fix
> > aliasing_dummy_5.f90 with
> >  arg(2:3) = arr(1:2)
> > instead of
> >  arr(2:3) = arg(1:2)
> > if the original testcase would actually fail.
> > 
> Mmh, aren't they both actually the same?

It is just bad choice of variable/argument names, I also originally thought
they are the same, but they aren't.
arr is a variable in the parent routine which is passed to the arg dummy,
both have TARGET attribute and one of them is assumed shape and so that
"the dummy argument has the TARGET attribute, the dummy argument does not have 
IN-
TENT (IN), the dummy argument is a scalar object or an assumed-shape array 
without the
CONTIGUOUS attribute, and the actual argument is a target other than an array 
section
with a vector subscript."
means that
"Action that affects the value of the entity or any subobject of it shall be 
taken
only through the dummy argument"
is not true and so one can doesn't need to access the object just through
arg, but can access it as arr as well and those two can alias.

Jakub



[PATCH] RISC-V: Minimal support for Zimop extension.

2024-08-02 Thread Jiawei
https://github.com/riscv/riscv-isa-manual/blob/main/src/zimop.adoc

gcc/ChangeLog:

* common/config/riscv/riscv-common.cc: New extension.
* config/riscv/riscv.opt: New mask.

gcc/testsuite/ChangeLog:

* gcc.target/riscv/arch-42.c: New test.
* gcc.target/riscv/arch-43.c: New test.

---
 gcc/common/config/riscv/riscv-common.cc  | 8 
 gcc/config/riscv/riscv.opt   | 7 +++
 gcc/testsuite/gcc.target/riscv/arch-42.c | 5 +
 gcc/testsuite/gcc.target/riscv/arch-43.c | 5 +
 4 files changed, 25 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/arch-42.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/arch-43.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 1944c7785c4..62c6e1dab1f 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -97,6 +97,8 @@ static const riscv_implied_info_t riscv_implied_info[] =
   {"zabha", "zaamo"},
   {"zacas", "zaamo"},
 
+  {"zcmop", "zca"},
+
   {"b", "zba"},
   {"b", "zbb"},
   {"b", "zbs"},
@@ -319,6 +321,9 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
   {"zicclsm",  ISA_SPEC_CLASS_NONE, 1, 0},
   {"ziccrse",  ISA_SPEC_CLASS_NONE, 1, 0},
 
+  {"zimop", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zcmop", ISA_SPEC_CLASS_NONE, 1, 0},
+
   {"zicntr", ISA_SPEC_CLASS_NONE, 2, 0},
   {"zihpm",  ISA_SPEC_CLASS_NONE, 2, 0},
 
@@ -1629,6 +1634,9 @@ static const riscv_ext_flag_table_t 
riscv_ext_flag_table[] =
   {"zicbop", &gcc_options::x_riscv_zicmo_subext, MASK_ZICBOP},
   {"zic64b", &gcc_options::x_riscv_zicmo_subext, MASK_ZIC64B},
 
+  {"zimop",&gcc_options::x_riscv_mop_subext, MASK_ZIMOP},
+  {"zcmop",&gcc_options::x_riscv_mop_subext, MASK_ZCMOP},
+
   {"zve32x",   &gcc_options::x_target_flags, MASK_VECTOR},
   {"zve32f",   &gcc_options::x_target_flags, MASK_VECTOR},
   {"zve64x",   &gcc_options::x_target_flags, MASK_VECTOR},
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 2e340e5324f..a8758abc918 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -406,6 +406,13 @@ Mask(ZICBOP) Var(riscv_zicmo_subext)
 
 Mask(ZIC64B) Var(riscv_zicmo_subext)
 
+TargetVariable
+int riscv_mop_subext
+
+Mask(ZIMOP) Var(riscv_mop_subext)
+
+Mask(ZCMOP) Var(riscv_mop_subext)
+
 TargetVariable
 int riscv_zf_subext
 
diff --git a/gcc/testsuite/gcc.target/riscv/arch-42.c 
b/gcc/testsuite/gcc.target/riscv/arch-42.c
new file mode 100644
index 000..83f78d28dbe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-42.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64i_zimop -mabi=lp64" } */
+int foo()
+{
+}
diff --git a/gcc/testsuite/gcc.target/riscv/arch-43.c 
b/gcc/testsuite/gcc.target/riscv/arch-43.c
new file mode 100644
index 000..4a300a165fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/arch-43.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64i_zcmop -mabi=lp64" } */
+int foo()
+{
+}
-- 
2.25.1



Re: [RFC] RISC-V: Add support for Profiles RVA/B23.

2024-08-02 Thread Jiawei



在 2024/8/1 21:54, Christoph Müllner 写道:

On Mon, Jul 29, 2024 at 5:26 AM Jiawei  wrote:

This patch adds support for RISC-V RVA23 and RVB23 Profiles[1],
which depend on the base RISC-V Profiles support[2].

[1] 
https://github.com/riscv/riscv-profiles/releases/tag/rva23-v0.4-rvb23-v0.1-internal-review
[2] https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658082.html


gcc/ChangeLog:

 * common/config/riscv/riscv-common.cc: New Profiles.

gcc/testsuite/ChangeLog:

 * gcc.target/riscv/attribute-22.c: New test.
 * gcc.target/riscv/attribute-23.c: New test.

---
  gcc/common/config/riscv/riscv-common.cc   | 20 +++
  gcc/testsuite/gcc.target/riscv/attribute-22.c | 11 ++
  gcc/testsuite/gcc.target/riscv/attribute-23.c | 10 ++
  3 files changed, 41 insertions(+)
  create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-22.c
  create mode 100644 gcc/testsuite/gcc.target/riscv/attribute-23.c

diff --git a/gcc/common/config/riscv/riscv-common.cc 
b/gcc/common/config/riscv/riscv-common.cc
index 23ae07fe2f3..e6e8adf5e1b 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -323,6 +323,9 @@ static const struct riscv_ext_version 
riscv_ext_version_table[] =
{"zicclsm",  ISA_SPEC_CLASS_NONE, 1, 0},
{"ziccrse",  ISA_SPEC_CLASS_NONE, 1, 0},

+  {"zimop",  ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zcmop",  ISA_SPEC_CLASS_NONE, 1, 0},
+

Independent of the fact that this will be delayed until ratification:
I would prefer to have this in a separate patch as Zimop and Zcmop are
dependencies.
Since Zimop and Zcmop are already ratified, this does not have a
dependency for the profiles ratification.


Thanks for your advice, implemented Zimop extension  in new patch

https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659280.html





{"zicntr", ISA_SPEC_CLASS_NONE, 2, 0},
{"zihpm",  ISA_SPEC_CLASS_NONE, 2, 0},

@@ -467,6 +470,23 @@ static const riscv_profiles riscv_profiles_table[] =
 "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
 "_zicboz_zfhmin_zkt"},

+  /* RVA23 contains all mandatory base ISA for RVA22U64 and the new extension
+ 'v,zihintntl,zvfhmin,zvbb,zvkt,zicond,zimop,zcmop,zfa,zawrs' as mandatory
+ extensions.  */
+  {"RVA23U64", "rv64imafdcv_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa"
+   "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
+   "_zicboz_zfhmin_zkt_zvfhmin_zvbb_zvkt_zihintntl_zicond_zimop_zcmop_zcb"
+   "_zfa_zawrs"},
+
+
+  /* RVB23 contains all mandatory base ISA for RVA22U64 and the new extension
+ 'zihintntl,zicond,zimop,zcmop,zfa,zawrs' as mandatory
+ extensions.  */
+  {"RVB23U64", "rv64imafdc_zicsr_zicntr_zihpm_ziccif_ziccrse_ziccamoa"
+   "_zicclsm_zic64b_za64rs_zihintpause_zba_zbb_zbs_zicbom_zicbop"
+   "_zicboz_zfhmin_zkt_zihintntl_zicond_zimop_zcmop_zcb"
+   "_zfa_zawrs"},
+
/* Currently we do not define S/M mode Profiles in gcc part.  */

/* Terminate the list.  */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-22.c 
b/gcc/testsuite/gcc.target/riscv/attribute-22.c
new file mode 100644
index 000..0bbb3242ddd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-22.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-march=RVA23U64 -mabi=lp64" } */
+
+void foo(){}
+
+/* { dg-final { scan-assembler ".attribute arch, 
\"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0"
+"_b1p0_v1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0"
+_ziccrse1p0_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0"
+_za64rs1p0_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcd1p0_zcmop1p0"
+_zba1p0_zbb1p0_zbs1p0_zkt1p0_zvbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0"
+_zvfhmin1p0_zvkb1p0_zvkt1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0\"" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-23.c 
b/gcc/testsuite/gcc.target/riscv/attribute-23.c
new file mode 100644
index 000..459b5641ca3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-23.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-march=RVB23U64 -mabi=lp64" } */
+
+void foo(){}
+
+/* { dg-final { scan-assembler ".attribute arch, 
\"rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0"
+"_b1p0_zic64b1p0_zicbom1p0_zicbop1p0_zicboz1p0_ziccamoa1p0_ziccif1p0_zicclsm1p0_ziccrse1p0"
+"_zicntr2p0_zicond1p0_zicsr2p0_zihintntl1p0_zihintpause2p0_zihpm2p0_zimop1p0_za64rs1p0"
+"_zaamo1p0_zalrsc1p0_zawrs1p0_zfa1p0_zfhmin1p0_zca1p0_zcb1p0_zcd1p0_zcmop1p0_zba1p0"
+"_zbb1p0_zbs1p0_zkt1p0\"" } } */
--
2.25.1





Re: [PATCH] arm: Fix testism with mve/ivopts-3.c testcase

2024-08-02 Thread Andre Vieira (lists)

Yeah true... committed.

On 01/08/2024 13:54, Christophe Lyon wrote:



On 8/1/24 12:02, Andre Vieira (lists) wrote:



On 01/08/2024 10:09, Christophe Lyon wrote:


It seems your attachment contains only the commit message but lacks 
the actual patch?




I blame lack of coffee...

Thanks.


The patch LGTM.  It seems patchwork didn't recognize it, so Linaro CI 
will not run.


Thanks,

Christophe


Re: [PATCH 01/15] arm: [MVE intrinsics] improve comment for orrq shape

2024-08-02 Thread Andre Vieira (lists)

Hi Christophe,

Maybe this patch was based on an older source, but the comment now reads:

/* _t vfoo[t0](_t, _t)
   _t vfoo[_n_t0](_t, _t)

   Where the _n form only supports s16/s32/u16/u32 types as for vorrq.

   Example: vorrq.
   int16x8_t [__arm_]vorrq[_s16](int16x8_t a, int16x8_t b)
   int16x8_t [__arm_]vorrq_m[_s16](int16x8_t inactive, int16x8_t a, 
int16x8_t b, mve_pred16_t p)
   int16x8_t [__arm_]vorrq_x[_s16](int16x8_t a, int16x8_t b, 
mve_pred16_t p)

   int16x8_t [__arm_]vorrq[_n_s16](int16x8_t a, const int16_t imm)
   int16x8_t [__arm_]vorrq_m_n[_s16](int16x8_t a, const int16_t imm, 
mve_pred16_t p)  */


So it already says it only supports _n for 16/32-bit signed and unsigned 
integers.  I don't have a problem with your changes necessarily, but it 
does seem a bit double. Anyway, no strong objection, just making sure we 
are really wanting to emphasize further that there are no _n for FP or 
8-bit types.


On 11/07/2024 22:42, Christophe Lyon wrote:

Add a comment about the lack of "n" forms for floating-point nor 8-bit
integers, to make it clearer why we use build_16_32 for MODE_n.

2024-07-11  Christophe Lyon  

gcc/
* config/arm/arm-mve-builtins-shapes.cc (binary_orrq_def): Improve 
comment.
---
  gcc/config/arm/arm-mve-builtins-shapes.cc | 7 ++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/gcc/config/arm/arm-mve-builtins-shapes.cc 
b/gcc/config/arm/arm-mve-builtins-shapes.cc
index ba20c6a8f73..e01939469e3 100644
--- a/gcc/config/arm/arm-mve-builtins-shapes.cc
+++ b/gcc/config/arm/arm-mve-builtins-shapes.cc
@@ -865,7 +865,12 @@ SHAPE (binary_opt_n)
 int16x8_t [__arm_]vorrq_m[_s16](int16x8_t inactive, int16x8_t a, int16x8_t 
b, mve_pred16_t p)
 int16x8_t [__arm_]vorrq_x[_s16](int16x8_t a, int16x8_t b, mve_pred16_t p)
 int16x8_t [__arm_]vorrq[_n_s16](int16x8_t a, const int16_t imm)
-   int16x8_t [__arm_]vorrq_m_n[_s16](int16x8_t a, const int16_t imm, 
mve_pred16_t p)  */
+   int16x8_t [__arm_]vorrq_m_n[_s16](int16x8_t a, const int16_t imm, 
mve_pred16_t p)
+
+   No "_n" forms for floating-point, nor 8-bit integers:
+   float16x8_t [__arm_]vorrq[_f16](float16x8_t a, float16x8_t b)
+   float16x8_t [__arm_]vorrq_m[_f16](float16x8_t inactive, float16x8_t a, 
float16x8_t b, mve_pred16_t p)
+   float16x8_t [__arm_]vorrq_x[_f16](float16x8_t a, float16x8_t b, 
mve_pred16_t p)  */
  struct binary_orrq_def : public overloaded_base<0>
  {
bool


[Committed] RISC-V: Improve length attributes for atomic insn sequences

2024-08-02 Thread Patrick O'Neill

On 8/2/24 07:10, Jeff Law wrote:



On 8/1/24 10:25 PM, Patrick O'Neill wrote:

gcc/ChangeLog:

* config/riscv/sync-rvwmo.md: Add conditional length attributes.
* config/riscv/sync-ztso.md: Ditto.
* config/riscv/sync.md: Fix incorrect insn length attributes and
reformat existing conditional checks.

OK
jeff


Committed.

Patrick



Re: [PATCH 03/15] arm: [MVE intrinsics] Cleanup arm-mve-builtins-functions.h

2024-08-02 Thread Andre Vieira (lists)

Hi,

This looks great to me, only one small suggestion, but take it or leave 
it I think it's a matter of preference.


On 11/07/2024 22:42, Christophe Lyon wrote:


+   /* No predicate, no suffix.  */
if (e.type_suffix (0).integer_p)
  if (e.type_suffix (0).unsigned_p)
-   code = code_for_mve_q_m (m_unspec_for_m_uint, 
m_unspec_for_m_uint, e.vector_mode (0));
+   code = code_for_mve_q (m_unspec_for_uint, m_unspec_for_uint, 
mode);
  else
-   code = code_for_mve_q_m (m_unspec_for_m_sint, 
m_unspec_for_m_sint, e.vector_mode (0));
+   code = code_for_mve_q (m_unspec_for_sint, m_unspec_for_sint, 
mode);
else
- code = code_for_mve_q_m_f (m_unspec_for_m_fp, e.vector_mode (0));
+ code = code_for_mve_q_f (m_unspec_for_fp, mode);
break;


I'd write this as:
if (e.type_suffix (0).integer_p)
  {
int unspec = (e.type_suffix (0).unsigned_p
  ? m_unspec_for_m_uint
  : m_unspec_for_m_sint);
code = code_for_mve_q (unspec, unspec, mode);
  }
else
  code = code_for_mve_q_f (m_unspec_for_fp, mode);
break;

And same for similar below ofc.  I have a slight preference to this as 
it makes it clear that both parameters are the same without needing to 
make a more difficult visual comparison and it also makes clear what the 
difference is between the unsigned_p true or false.


Not a strong opinion here though.


[RFC/RFA] [PATCH v2 11/12] Replace the original CRC loops with a faster CRC calculation.

2024-08-02 Thread Mariam Arutunian
After the loop exit an internal function call (CRC, CRC_REV) is added,
and its result is assigned to the output CRC variable (the variable where
the calculated CRC is stored after the loop execution).
The removal of the loop is left to CFG cleanup and DCE.

  gcc/

* gimple-crc-optimization.cc (get_data): New function.
(optimize_crc_loop): Likewise.
(build_polynomial_without_1): Likewise.
(execute): Add optimize_crc_loop function call.

Signed-off-by: Mariam Arutunian 
diff --git a/gcc/gimple-crc-optimization.cc b/gcc/gimple-crc-optimization.cc
index bd84d553a60..4de383419a0 100644
--- a/gcc/gimple-crc-optimization.cc
+++ b/gcc/gimple-crc-optimization.cc
@@ -216,6 +216,24 @@ class crc_optimization {
   /* Returns phi statement which may hold the calculated CRC.  */
   gphi *get_output_phi ();
 
+  /* Returns data argument to pass to the CRC IFN.
+ If there is data from the code - use it (this is the case,
+ when data isn't xor-ed with CRC before the loop).
+ Otherwise, generate a new variable for the data with 0 value
+ (the case, when data is xor-ed with CRC before the loop).
+ For the CRC calculation, it doesn't matter CRC is calculated for the
+ (CRC^data, 0) or (CRC, data).  */
+  tree get_data ();
+
+  /* Attempts to optimize a CRC calculation loop by replacing it with a call to
+ an internal function (IFN_CRC or IFN_CRC_REV).
+ Returns true if replacement is succeeded, otherwise false.  */
+  bool optimize_crc_loop (value *polynomial, gphi *output_crc);
+
+  /* Build tree for the POLYNOMIAL (from its binary representation)
+ without the leading 1.  */
+  tree build_polynomial_without_1 (tree crc_arg, value *polynomial);
+
  public:
   unsigned int execute (function *fun);
 };
@@ -1094,6 +1112,142 @@ crc_optimization::get_output_phi ()
   return nullptr;
 }
 
+/* Build tree for the POLYNOMIAL (from its binary representation)
+   without the leading 1.  */
+
+tree
+crc_optimization::build_polynomial_without_1 (tree crc_arg, value *polynomial)
+{
+  unsigned HOST_WIDE_INT cst_polynomial = 0;
+  for (unsigned i = 0; i < (*polynomial).length (); i++)
+{
+  value_bit *const_bit;
+  if (m_is_bit_forward)
+	const_bit = (*polynomial)[(*polynomial).length () - 1 - i];
+  else
+	const_bit = (*polynomial)[i];
+  cst_polynomial <<= 1;
+  cst_polynomial ^= (as_a (const_bit))->get_val () ? 1 : 0;
+}
+  return build_int_cstu (TREE_TYPE (crc_arg), cst_polynomial);
+}
+
+/* Returns data argument to pass to the CRC IFN.
+   If there is data from the code - use it (this is the case,
+   when data isn't xor-ed with CRC before the loop).
+   Otherwise, generate a new variable for the data with 0 value
+   (the case, when data is xor-ed with CRC before the loop).
+   For the CRC calculation, it doesn't matter CRC is calculated for the
+   (CRC^data, 0) or (CRC, data).  */
+
+tree
+crc_optimization::get_data ()
+{
+  unsigned HOST_WIDE_INT
+data_size = tree_to_uhwi (m_crc_loop->nb_iterations) + 1;
+
+  /* If we have the data, use it.  */
+  if (m_phi_for_data)
+{
+  if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file,
+		 "Data and CRC are xor-ed in the for loop.  Initializing data "
+		 "with its value.\n");
+  tree data_arg = PHI_ARG_DEF (m_phi_for_data, 1);
+  if (TYPE_PRECISION (TREE_TYPE (data_arg)) == data_size)
+	return data_arg;
+  else
+	{
+	  if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file,
+		 "Loop iteration number and data's size differ.\n");
+	  return nullptr;
+	}
+}
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+fprintf (dump_file,
+	 "Data and CRC are xor-ed before for loop.  Initializing data "
+	 "with 0.\n");
+  /* Create a new variable for the data.
+ Determine the data's size with the loop iteration count.  */
+  tree type = build_nonstandard_integer_type (data_size, 1);
+  return build_int_cstu (type, 0);
+}
+
+/* Attempts to optimize a CRC calculation loop by replacing it with a call to
+   an internal function (IFN_CRC or IFN_CRC_REV).
+   Returns true if replacement is succeeded, otherwise false.  */
+
+bool
+crc_optimization::optimize_crc_loop (value *polynomial, gphi *output_crc)
+{
+  if (!output_crc)
+{
+  if (dump_file)
+	fprintf (dump_file, "Couldn't determine output CRC.\n");
+  return false;
+}
+
+  gcc_assert (m_phi_for_crc);
+
+  tree crc_arg = PHI_ARG_DEF (m_phi_for_crc, 1);
+  if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (crc_arg))).to_constant ()
+  > GET_MODE_SIZE (word_mode))
+{
+  if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "word_mode is less than CRC mode.\n");
+  return false;
+}
+
+  tree data_arg = get_data ();
+  tree polynomial_arg = build_polynomial_without_1 (crc_arg, polynomial);
+
+  if (!crc_arg || !data_arg || !polynomial_arg)
+{
+  if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "crc_arg, data_arg or polynomial_arg is null.\n

New Chinese (simplified) PO file for 'gcc' (version 14.2.0)

2024-08-02 Thread Translation Project Robot
Hello, gentle maintainer.

This is a message from the Translation Project robot.

A revised PO file for textual domain 'gcc' has been submitted
by the Chinese (simplified) team of translators.  The file is available at:

https://translationproject.org/latest/gcc/zh_CN.po

(This file, 'gcc-14.2.0.zh_CN.po', has just now been sent to you in
a separate email.)

All other PO files for your package are available in:

https://translationproject.org/latest/gcc/

Please consider including all of these in your next release, whether
official or a pretest.

Whenever you have a new distribution with a new version number ready,
containing a newer POT file, please send the URL of that distribution
tarball to the address below.  The tarball may be just a pretest or a
snapshot, it does not even have to compile.  It is just used by the
translators when they need some extra translation context.

The following HTML page has been updated:

https://translationproject.org/domain/gcc.html

If any question arises, please contact the translation coordinator.

Thank you for all your work,

The Translation Project robot, in the
name of your translation coordinator.




Re: [PATCH] fortran: Fix a pasto in gfc_check_dependency

2024-08-02 Thread Mikael Morin

Le 02/08/2024 à 17:05, Jakub Jelinek a écrit :

On Fri, Aug 02, 2024 at 04:58:09PM +0200, Mikael Morin wrote:

But the function actually returns 0 rather than 1 that PR45019 meant.
So I bet in addition to fixing the pasto we should move that conditional
from where it is right now to the return 0; location after
check_data_pointer_types calls.


No, the function check_data_pointer_types returns true if there is no
aliasing, according to its function comment, so after both calls everything
is safe and returning anything but 0 is overly pessimistic.


My (limited) understanding is that the original PR is about some corner case
in the standard wording where in order to allow aliasing of TARGET vars with
POINTER vars it also makes valid the weirdo stuff in the testcase.

And so should return 1 which means that they possibly alias.

I agree with all of that.  Sure keeping the condition around would be 
the safest.  I'm just afraid of keeping code that would remain dead.



And the pasto fix would guess fix
aliasing_dummy_5.f90 with
  arg(2:3) = arr(1:2)
instead of
  arr(2:3) = arg(1:2)
if the original testcase would actually fail.


Mmh, aren't they both actually the same?


It is just bad choice of variable/argument names, I also originally thought
they are the same, but they aren't.
arr is a variable in the parent routine which is passed to the arg dummy,
both have TARGET attribute and one of them is assumed shape and so that
"the dummy argument has the TARGET attribute, the dummy argument does not have 
IN-
TENT (IN), the dummy argument is a scalar object or an assumed-shape array 
without the
CONTIGUOUS attribute, and the actual argument is a target other than an array 
section
with a vector subscript."
means that
"Action that affects the value of the entity or any subobject of it shall be 
taken
only through the dummy argument"
is not true and so one can doesn't need to access the object just through
arg, but can access it as arr as well and those two can alias.

They can alias, and they do alias.  So in the end, writing either line 
is equivalent, what do I miss?


Re: [PATCH] forwprop: Don't add uses to dce list if debug statement [PR116156]

2024-08-02 Thread Andrew Pinski
On Thu, Aug 1, 2024 at 11:55 PM Richard Biener
 wrote:
>
> On Thu, Aug 1, 2024 at 10:40 PM Andrew Pinski  
> wrote:
> >
> > The problem here is that when forwprop does a copy prop, into a statement,
> > we mark the uses of that statement as possibly need to be removed. But it 
> > just
> > happened that statement was a debug statement, there will be a difference 
> > when
> > compiling with debuging info turned on vs off; this is not expected.
> > So the fix is not to add the old use to dce list to process if it was a 
> > debug
> > statement.
> >
> > Bootstrapped and tested on x86_64-linux-gnu with no regressions.
>
> OK

Thanks Applied to the trunk and GCC 14 branch (since it is a regression there).

Thanks,
Andrew Pinski

>
> > PR tree-optimization/116156
> >
> > gcc/ChangeLog:
> >
> > * tree-ssa-forwprop.cc (pass_forwprop::execute): Don't add
> > uses if the statement was a debug statement.
> >
> > gcc/testsuite/ChangeLog:
> >
> > * c-c++-common/torture/pr116156-1.c: New test.
> >
> > Signed-off-by: Andrew Pinski 
> > ---
> >  .../c-c++-common/torture/pr116156-1.c | 30 +++
> >  gcc/tree-ssa-forwprop.cc  | 16 +-
> >  2 files changed, 39 insertions(+), 7 deletions(-)
> >  create mode 100644 gcc/testsuite/c-c++-common/torture/pr116156-1.c
> >
> > diff --git a/gcc/testsuite/c-c++-common/torture/pr116156-1.c 
> > b/gcc/testsuite/c-c++-common/torture/pr116156-1.c
> > new file mode 100644
> > index 000..10f938ef4e5
> > --- /dev/null
> > +++ b/gcc/testsuite/c-c++-common/torture/pr116156-1.c
> > @@ -0,0 +1,30 @@
> > +/* { dg-additional-options "-fcompare-debug" } */
> > +/* PR tree-optimization/116156 */
> > +
> > +/* Forwprop used to delete an unused statement
> > +   but only with debug statements around. */
> > +
> > +struct jpeg_compress_struct {
> > +  int X_density;
> > +};
> > +void gg();
> > +int h(const char*,const char*) __attribute((pure));
> > +int h1(const char*) __attribute((pure));
> > +int f1() __attribute__((returns_twice));
> > +void real_save_jpeg(char **keys, char *values) {
> > +  struct jpeg_compress_struct cinfo;
> > +  int x_density = 0;
> > +  while (*keys)
> > +  {
> > +if (h1(*keys) == 0)
> > +  gg();
> > +if (h1(*keys) == 0)  {
> > +  if (!*values)
> > +x_density = -1;
> > +  if (x_density <= 0)
> > +gg();
> > +}
> > +  }
> > +  if (f1())
> > +cinfo.X_density = x_density;
> > +}
> > diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc
> > index 44a6b5d39aa..2e37642359c 100644
> > --- a/gcc/tree-ssa-forwprop.cc
> > +++ b/gcc/tree-ssa-forwprop.cc
> > @@ -3923,7 +3923,8 @@ pass_forwprop::execute (function *fun)
> >   tree val = fwprop_ssa_val (use);
> >   if (val && val != use)
> > {
> > - bitmap_set_bit (simple_dce_worklist, SSA_NAME_VERSION 
> > (use));
> > + if (!is_gimple_debug (stmt))
> > +   bitmap_set_bit (simple_dce_worklist, SSA_NAME_VERSION 
> > (use));
> >   if (may_propagate_copy (use, val))
> > {
> >   propagate_value (usep, val);
> > @@ -3963,12 +3964,13 @@ pass_forwprop::execute (function *fun)
> > if (gimple_cond_true_p (cond)
> > || gimple_cond_false_p (cond))
> >   cfg_changed = true;
> > - /* Queue old uses for simple DCE.  */
> > - for (tree use : uses)
> > -   if (TREE_CODE (use) == SSA_NAME
> > -   && !SSA_NAME_IS_DEFAULT_DEF (use))
> > - bitmap_set_bit (simple_dce_worklist,
> > - SSA_NAME_VERSION (use));
> > + /* Queue old uses for simple DCE if not debug statement.  
> > */
> > + if (!is_gimple_debug (stmt))
> > +   for (tree use : uses)
> > + if (TREE_CODE (use) == SSA_NAME
> > + && !SSA_NAME_IS_DEFAULT_DEF (use))
> > +   bitmap_set_bit (simple_dce_worklist,
> > +   SSA_NAME_VERSION (use));
> > }
> >
> >   if (changed || substituted_p)
> > --
> > 2.43.0
> >


New Croatian PO file for 'gcc' (version 14.2.0)

2024-08-02 Thread Translation Project Robot
Hello, gentle maintainer.

This is a message from the Translation Project robot.

A revised PO file for textual domain 'gcc' has been submitted
by the Croatian team of translators.  The file is available at:

https://translationproject.org/latest/gcc/hr.po

(This file, 'gcc-14.2.0.hr.po', has just now been sent to you in
a separate email.)

All other PO files for your package are available in:

https://translationproject.org/latest/gcc/

Please consider including all of these in your next release, whether
official or a pretest.

Whenever you have a new distribution with a new version number ready,
containing a newer POT file, please send the URL of that distribution
tarball to the address below.  The tarball may be just a pretest or a
snapshot, it does not even have to compile.  It is just used by the
translators when they need some extra translation context.

The following HTML page has been updated:

https://translationproject.org/domain/gcc.html

If any question arises, please contact the translation coordinator.

Thank you for all your work,

The Translation Project robot, in the
name of your translation coordinator.




Re: [PATCH 01/15] arm: [MVE intrinsics] improve comment for orrq shape

2024-08-02 Thread Christophe Lyon
On Fri, 2 Aug 2024 at 17:46, Andre Vieira (lists)
 wrote:
>
> Hi Christophe,
>
> Maybe this patch was based on an older source, but the comment now reads:
>
> /* _t vfoo[t0](_t, _t)
> _t vfoo[_n_t0](_t, _t)
>
> Where the _n form only supports s16/s32/u16/u32 types as for vorrq.
>
> Example: vorrq.
> int16x8_t [__arm_]vorrq[_s16](int16x8_t a, int16x8_t b)
> int16x8_t [__arm_]vorrq_m[_s16](int16x8_t inactive, int16x8_t a,
> int16x8_t b, mve_pred16_t p)
> int16x8_t [__arm_]vorrq_x[_s16](int16x8_t a, int16x8_t b,
> mve_pred16_t p)
> int16x8_t [__arm_]vorrq[_n_s16](int16x8_t a, const int16_t imm)
> int16x8_t [__arm_]vorrq_m_n[_s16](int16x8_t a, const int16_t imm,
> mve_pred16_t p)  */
>
> So it already says it only supports _n for 16/32-bit signed and unsigned
> integers.  I don't have a problem with your changes necessarily, but it
> does seem a bit double. Anyway, no strong objection, just making sure we
> are really wanting to emphasize further that there are no _n for FP or
> 8-bit types.
>

Indeed it's a bit verbose :-)
I added it when I restarted working on this series as it was not
immediately clear what the first comment implied...

Thanks

Christophe

> On 11/07/2024 22:42, Christophe Lyon wrote:
> > Add a comment about the lack of "n" forms for floating-point nor 8-bit
> > integers, to make it clearer why we use build_16_32 for MODE_n.
> >
> > 2024-07-11  Christophe Lyon  
> >
> >   gcc/
> >   * config/arm/arm-mve-builtins-shapes.cc (binary_orrq_def): Improve 
> > comment.
> > ---
> >   gcc/config/arm/arm-mve-builtins-shapes.cc | 7 ++-
> >   1 file changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/gcc/config/arm/arm-mve-builtins-shapes.cc 
> > b/gcc/config/arm/arm-mve-builtins-shapes.cc
> > index ba20c6a8f73..e01939469e3 100644
> > --- a/gcc/config/arm/arm-mve-builtins-shapes.cc
> > +++ b/gcc/config/arm/arm-mve-builtins-shapes.cc
> > @@ -865,7 +865,12 @@ SHAPE (binary_opt_n)
> >  int16x8_t [__arm_]vorrq_m[_s16](int16x8_t inactive, int16x8_t a, 
> > int16x8_t b, mve_pred16_t p)
> >  int16x8_t [__arm_]vorrq_x[_s16](int16x8_t a, int16x8_t b, mve_pred16_t 
> > p)
> >  int16x8_t [__arm_]vorrq[_n_s16](int16x8_t a, const int16_t imm)
> > -   int16x8_t [__arm_]vorrq_m_n[_s16](int16x8_t a, const int16_t imm, 
> > mve_pred16_t p)  */
> > +   int16x8_t [__arm_]vorrq_m_n[_s16](int16x8_t a, const int16_t imm, 
> > mve_pred16_t p)
> > +
> > +   No "_n" forms for floating-point, nor 8-bit integers:
> > +   float16x8_t [__arm_]vorrq[_f16](float16x8_t a, float16x8_t b)
> > +   float16x8_t [__arm_]vorrq_m[_f16](float16x8_t inactive, float16x8_t a, 
> > float16x8_t b, mve_pred16_t p)
> > +   float16x8_t [__arm_]vorrq_x[_f16](float16x8_t a, float16x8_t b, 
> > mve_pred16_t p)  */
> >   struct binary_orrq_def : public overloaded_base<0>
> >   {
> > bool


Re: [PATCH 03/15] arm: [MVE intrinsics] Cleanup arm-mve-builtins-functions.h

2024-08-02 Thread Christophe Lyon
On Fri, 2 Aug 2024 at 18:14, Andre Vieira (lists)
 wrote:
>
> Hi,
>
> This looks great to me, only one small suggestion, but take it or leave
> it I think it's a matter of preference.
>
> On 11/07/2024 22:42, Christophe Lyon wrote:
>
> > + /* No predicate, no suffix.  */
> >   if (e.type_suffix (0).integer_p)
> > if (e.type_suffix (0).unsigned_p)
> > - code = code_for_mve_q_m (m_unspec_for_m_uint, 
> > m_unspec_for_m_uint, e.vector_mode (0));
> > + code = code_for_mve_q (m_unspec_for_uint, m_unspec_for_uint, 
> > mode);
> > else
> > - code = code_for_mve_q_m (m_unspec_for_m_sint, 
> > m_unspec_for_m_sint, e.vector_mode (0));
> > + code = code_for_mve_q (m_unspec_for_sint, m_unspec_for_sint, 
> > mode);
> >   else
> > -   code = code_for_mve_q_m_f (m_unspec_for_m_fp, e.vector_mode 
> > (0));
> > +   code = code_for_mve_q_f (m_unspec_for_fp, mode);
> >   break;
>
> I'd write this as:
> if (e.type_suffix (0).integer_p)
>{
>  int unspec = (e.type_suffix (0).unsigned_p
>? m_unspec_for_m_uint
>: m_unspec_for_m_sint);
>  code = code_for_mve_q (unspec, unspec, mode);
>}
> else
>code = code_for_mve_q_f (m_unspec_for_fp, mode);
> break;
>
> And same for similar below ofc.  I have a slight preference to this as
> it makes it clear that both parameters are the same without needing to
> make a more difficult visual comparison and it also makes clear what the
> difference is between the unsigned_p true or false.
>
> Not a strong opinion here though.


I think you are right, this goes in the same direction of what this
cleanup intended: remove duplication and make it easier to
read/maintain.

I'll update this patch accordingly.

Thanks,

Christophe


Re: [PATCH] c++: permit errors inside uninstantiated templates [PR116064]

2024-08-02 Thread Jason Merrill

On 8/1/24 2:52 PM, Patrick Palka wrote:

In recent versions of GCC we've been diagnosing more and more kinds of
errors inside a template ahead of time.  This is a largely good thing
because it catches bugs, typos, dead code etc sooner.

But if the template never gets instantiated then such errors are
harmless, and can be inconvenient to work around if say the code in
question is third party and in maintenence mode.  So it'd be useful to


"maintenance"


diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index d80bac822ba..0bb0a482e28 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -165,6 +165,58 @@ class cxx_format_postprocessor : public 
format_postprocessor
deferred_printed_type m_type_b;
  };
  
+/* A map from TEMPLATE_DECL to the location of the first error (if any)

+   within the template that we permissivly downgraded to a warning.  */


"permissively"


+relaxed_template_errors_t *relaxed_template_errors;
+
+/* Callback function diagnostic_context::m_adjust_diagnostic_info.
+
+   In -fpermissive mode we downgrade errors within a template to
+   warnings, and only issue an error if we later need to instantiate
+   the template.  */
+
+static void
+cp_adjust_diagnostic_info (diagnostic_context *context,
+  diagnostic_info *diagnostic)
+{
+  tree ti;
+  if (diagnostic->kind == DK_ERROR
+  && context->m_permissive
+  && !current_instantiation ()
+  && in_template_context
+  && (ti = get_template_info (current_scope (
+{
+  if (!relaxed_template_errors)
+   relaxed_template_errors = new relaxed_template_errors_t;
+
+  tree tmpl = TI_TEMPLATE (ti);
+  if (!relaxed_template_errors->get (tmpl))
+   relaxed_template_errors->put (tmpl, diagnostic->richloc->get_loc ());
+  diagnostic->kind = DK_WARNING;


Rather than check m_permissive directly and downgrade to DK_WARNING, how 
about downgrading to DK_PERMERROR?  That way people will get the 
[-fpermissive] clue.


...though I suppose DK_PERMERROR doesn't work where you call this hook 
in report_diagnostic, at which point we've already reassigned it into 
DK_WARNING or DK_ERROR in diagnostic_impl.


But we could still set diagnostic->option_index even for DK_ERROR, 
whether to context->m_opt_permissive or to its own warning flag, perhaps 
-Wno-template-body?



+/* A generalization of seen_error which also returns true if we've
+   permissively downgraded an error to a warning inside a template.  */
+
+bool
+cp_seen_error ()
+{
+#undef seen_error
+  if (seen_error ())
+return true;
+
+  tree ti;
+  if (relaxed_template_errors
+  && in_template_context
+  && (ti = get_template_info (current_scope ()))


Let's factor the "in template body" checks in this function and the 
previous one into a separate function; I expect we want the 
!current_instantiation test in this case as well?



diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 77fa5907c3d..b58ccb318d5 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -12376,6 +12376,22 @@ instantiate_class_template (tree type)
if (! push_tinst_level (type))
  return type;
  
+  if (relaxed_template_errors)

+if (location_t *error_loc = relaxed_template_errors->get (templ))
+  {
+   /* We're trying to instantiate a template pattern containing
+  an error that we've permissively downgraded to a warning.
+  Issue a hard error now.  */
+   location_t decl_loc = location_of (templ);
+   error_at (decl_loc, "instantiating erroneous template pattern");


I wouldn't use the internal term "pattern" in diagnostics, I think just 
"erroneous template" is enough.



@@ -27291,6 +27307,20 @@ instantiate_decl (tree d, bool defer_ok, bool 
expl_inst_class_mem_p)
}
  }
  
+  if (relaxed_template_errors)

+if (location_t *error_loc = relaxed_template_errors->get (td))
+  {
+   /* We're trying to instantiate a template pattern containing
+  an error that we've permissively downgraded to a warning.
+  Issue a hard error now.  */
+   location_t decl_loc = location_of (td);
+   error_at (decl_loc, "instantiating erroneous template pattern");


Likewise.


diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 71d2f44e40c..cbd2c82f19d 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -219,6 +219,7 @@ diagnostic_context::initialize (int n_opts)
m_warn_system_headers = false;
m_max_errors = 0;
m_internal_error = nullptr;
+  m_adjust_diagnostic_info = nullptr;
m_text_callbacks.m_begin_diagnostic = default_diagnostic_starter;
m_text_callbacks.m_start_span = default_diagnostic_start_span_fn;
m_text_callbacks.m_end_diagnostic = default_diagnostic_finalizer;
@@ -1409,6 +1410,9 @@ diagnostic_context::report_diagnostic (diagnostic_info 
*diagnostic)
   flush diagnostics with on_end_group when the topmost group is ended.  */
gcc_assert (m_diagnostic_groups.m_nesting_depth > 0);
  
+  if (m_adjust_diagnostic_info)

+m_adjust_diagnosti

Re: [PATCH v1] aarch64: Add fp8 scalar types

2024-08-02 Thread Claudio Bantaloukas


On 02/08/2024 12:17, Richard Sandiford wrote:
> Claudio Bantaloukas  writes:
>> The ACLE defines a new scalar type, __mfp8. This is an opaque 8bit types that
>> can only be used by fp8 intrinsics. Additionally, the mfloat8_t type is made
>> available in arm_neon.h and arm_sve.h as an alias of the same.
>>
>> This implementation uses an INTEGER_TYPE, with precision 8 to represent
>> __mfp8. Conversions to int and other types are disabled via the
>> TARGET_INVALID_CONVERSION hook.
>> Additionally, operations that are typically available to integer types are
>> disabled via TARGET_INVALID_UNARY_OP and TARGET_INVALID_BINARY_OP hooks.
>>
>> gcc/ChangeLog:
>>
>>  * config/aarch64/aarch64-builtins.cc (aarch64_mfp8_type_node): Add node
>>  for __mfp8 type.
>>  (aarch64_mfp8_ptr_type_node): Add node for __mfp8 pointer type.
>>  (aarch64_init_fp8_types): New function to initialise fp8 types and
>>  register with language backends.
>>  * config/aarch64/aarch64.cc (aarch64_invalid_conversion): Add function
>>  implementing TARGET_INVALID_CONVERSION hook that blocks conversion to
>>  and from __mfp8 type.
>>  (aarch64_invalid_unary_op): Add function implementing TARGET_UNARY_OP
>>  hook that blocks operations on __mfp8 other than &.
>>  (aarch64_invalid_binary_op): Extend TARGET_BINARY_OP hook to disallow
>>  operations on __mfp8 type.
>>  (TARGET_INVALID_CONVERSION): Add define.
>>  (TARGET_INVALID_UNARY_OP): Likewise.
>>  * config/aarch64/aarch64.h (aarch64_mfp8_type_node): Add node for __mfp8
>>  type.
>>  (aarch64_mfp8_ptr_type_node): Add node for __mfp8 pointer type.
>>  * config/aarch64/arm_neon.h (mfloat8_t): Add typedef.
>>  * config/aarch64/arm_sve.h (mfloat8_t): Likewise.
>>
>> gcc/testsuite/ChangeLog:
>>
>>  * gcc.target/aarch64/fp8_scalar_1.c: New tests in C.
>>  * gcc.target/aarch64/fp8_scalar_typecheck_1.c: Likewise.
>>  * gcc.target/aarch64/fp8_scalar_typecheck_2.C: New tests in C++.
> 

Hi Richard,
thank you for the super fast review!

> C++ tests should go in g++.target instead.

Done

> I think the new type needs to be mangled explicitly, so that the
> overloads in:
> 
>int foo(__mfp8) { return 1; }
>int foo(unsigned char) { return 2; }
>int bar(__mfp8 x) { return foo(x); }
> 
> are distinct.  It'd also be good to have a constexpr version of foo
> in the tests, to make sure that the right overload is chosen.

Added both regular and constexpr overloading checks.

>>
>> +static void
>> +aarch64_init_fp8_types (void)
> 
> The function should have a comment before it.
> 
Added

>> +{
>> +  aarch64_mfp8_type_node = make_node (INTEGER_TYPE);
>> +  TYPE_PRECISION (aarch64_mfp8_type_node) = 8;
>> +  TYPE_MIN_VALUE (aarch64_mfp8_type_node)
>> +  = TYPE_MIN_VALUE (unsigned_char_type_node);
>> +  TYPE_MAX_VALUE (aarch64_mfp8_type_node)
>> +  = TYPE_MAX_VALUE (unsigned_char_type_node);
> 
> If we're using the unsigned range, we should also set TYPE_UNSIGNED.
> That said...
> 
>> +  layout_type (aarch64_mfp8_type_node);
> 
> ...it looks like the code above could be replaced by:
> 
>aarch64_mfp8_type_node = make_unsigned_type (8);
> 
> which would also give TYPE_MIN_VALUE and TYPE_MAX_VALUE the "right" types.

Done, this has reduced the function considerably, thanks!

> I was surprised that the tests worked so well with just a standard
> integer type, without having to use build_distinct_type_copy.
> But since they do, I agree we shouldn't use build_distinct_type_copy
> unless a specific reason comes up.
> 

Haven't found a specific reason to up to now.

>>   
>> +/* Implement TARGET_INVALID_CONVERSION.
>> +
>> +Return the diagnostic message when it is invalid to convert from fromtype to
>> +totype, or NULL if validity should be determined by the front end. */
> 
> The usual style is not to reiterate the hook description, since when
> that's happened in the past, the comments have become out of date
> wrt the documentation.  So just:
> 
> /* Implement TARGET_INVALID_CONVERSION.  */
> 
> should be good enough.

Done

>> +
>> +static const char *
>> +aarch64_invalid_conversion (const_tree fromtype, const_tree totype)
>> +{
>> +  /* Do not allow conversions to/from FP8.  */
>> +  bool fromtype_is_fp8
>> +  = ((fromtype) && (TYPE_MODE (fromtype) == QImode)
>> + && (TYPE_MAIN_VARIANT (fromtype) == aarch64_mfp8_type_node));
>> +  bool totype_is_fp8
>> +  = ((totype)
>> + && (TYPE_MODE (totype) == QImode
>> + && TYPE_MAIN_VARIANT (totype) == aarch64_mfp8_type_node));
> 
> Did you see null fromtypes and totypes?  It doesn't look like the other
> targets have needed to handle them, and it's not clear what the correct
> behaviour would be in that case.
> 
> The QImode tests also look redundant.
> 
> Trying it locally, things seemed to work for me with:
> 
>bool fromtype_is_fp8
>  = TYPE_MAIN_VARIANT (fromtype) == aarch64_mfp8_type_node;
>bool totype_is_fp8
>  = TYPE_MAIN_VA

Re: [PATCH v2] c++/coroutines: check for members we use in handle_types [PR105475]

2024-08-02 Thread Jason Merrill

On 8/2/24 10:50 AM, Arsen Arsenović wrote:

Jason Merrill  writes:


I don't think these names need to mention "baselink", but I'm not strongly
against it.


It doesn't fit with the rest of the codebase either, so I'll rename
them.


A few other tweaks below:


@@ -90,6 +90,7 @@ struct GTY((for_user)) coroutine_info
 tree self_h_proxy;  /* A handle instance that is used as the proxy for the
 one that will eventually be allocated in the coroutine
 frame.  */
+  tree from_address_bl;  /* handle_type from_address function (BASELINK).  */


Inserting this here breaks the "Likewise" reference in the next line.


Ah, true.  Swapped it with the next line.


 tree promise_proxy; /* Likewise, a proxy promise instance.  */
 tree return_void;   /* The expression for p.return_void() if it exists.  */
 location_t first_coro_keyword; /* The location of the keyword that made 
this
@@ -389,7 +389,105 @@ find_coro_handle_template_decl (location_t kw)
   return handle_decl;
   }
   -/* Instantiate the handle template for a given promise type.  */
+/* Get and validate HANDLE_TYPE#address.  The resulting function, if any, will


:: instead of #


Fixed.


+   be a non-overloaded member function that takes no arguments and returns
+   void*.  If that is not the case, signals an error and returns NULL_TREE.  */
+
+static tree
+get_handle_type_address_bl (location_t kw, tree handle_type)
+{
+  tree addr_getter = lookup_member (handle_type, coro_address_identifier, 1,
+   0, tf_warning_or_error);
+  if (!addr_getter || addr_getter == error_mark_node)
+{
+  error_at (kw, "could not find %qE in %qT",
+   coro_address_identifier, handle_type);


How about using qualified_name_lookup_error?


That seems to work, if the following usage is correct:

   tree addr_getter = lookup_member (handle_type, coro_address_identifier, 1,
0, tf_warning_or_error);
   if (!addr_getter || addr_getter == error_mark_node)
 {
   qualified_name_lookup_error (handle_type, coro_address_identifier,
   error_mark_node, kw);
   // notably the error_mark_node above, since it seems that
   // qualified_name_lookup_error accesses DECL.
   return NULL_TREE;
 }


+  gcc_assert (TREE_CODE (addr_getter) == BASELINK);


This looks like it will ICE on an invalid handle type (e.g. where "address" is
a type or data member) instead of giving an error.


Ah, good point.  I'll fix that and add the testcases for it.


+  tree fn_t = TREE_TYPE (addr_getter);
+  if (TREE_CODE (fn_t) != METHOD_TYPE)
+{
+  error_at (kw, "%qE must be a non-overloaded method", addr_getter);
+  return NULL_TREE;
+}
+
+  tree arg = TYPE_ARG_TYPES (fn_t);
+  /* Given that this is a method, we have an argument to skip (the this
+ pointer).  */
+  gcc_checking_assert (TREE_CHAIN (arg));


This assert seems redundant with the following checks.


+  arg = TREE_CHAIN (arg);
+
+  /* Check that from_addr has the argument list ().  */
+  if (!arg
+  || !same_type_p (TREE_VALUE (arg), void_type_node)
+  || TREE_CHAIN (arg))
+{
+  error_at (kw, "%qE must take no arguments", addr_getter);
+  return NULL_TREE;
+}


I think this could just be

if (arg != void_list_node)

as we share the terminal void between all non-varargs function types.


Yes, seems so.  I've addressed both comments above.


+  tree ret_t = TREE_TYPE (fn_t);
+  if (!same_type_p (ret_t, ptr_type_node))
+{
+  error_at (kw, "%qE must return %qT, not %qT",
+   addr_getter, ptr_type_node, ret_t);
+  return NULL_TREE;
+}


Do you also want to check that it has public access?


lookup_member checks access already, and we can recover from that error
AFAICT, so it might be best to leave it.

(I think leaving the check out permits the user to craft particular
invalid code, e.g. when they place a coroutine inside a class inheriting
from coroutine handle but make the methods protected, but as long as the
compiler does not crash, I think this is good enough - I don't think we
ought to verify here that the declaration matches the spec)


@@ -454,10 +552,15 @@ ensure_coro_initialized (location_t loc)
   /*  We can also instantiate the void coroutine_handle<>  */
 void_coro_handle_type =
-   instantiate_coro_handle_for_promise_type (loc, NULL_TREE);
+   instantiate_coro_handle_for_promise_type (loc, void_type_node);
 if (void_coro_handle_type == NULL_TREE)
return false;
   +  void_coro_handle_address =
+   get_handle_type_address_bl (loc, void_coro_handle_type);


The = should be at the beginning of the second line for both variables.


Fixed.


@@ -2365,8 +2480,9 @@ build_actor_fn (location_t loc, tree coro_frame_type, 
tree actor, tree fnbody,
 tree ash = build_class_member_access_expr (actor_frame, ash_m, NULL_TREE,
 

[RFC][PATCH] SVE intrinsics: Fold svdiv (svptrue, x, x) to ones

2024-08-02 Thread Jennifer Schmitz
This patch folds the SVE intrinsic svdiv into a vector of 1's in case
1) the predicate is svptrue and
2) dividend and divisor are equal.
This is implemented in the gimple_folder for signed and unsigned
integers. Corresponding test cases were added to the existing test
suites.

The patch was bootstrapped and regtested on aarch64-linux-gnu, no regression.
OK for mainline?

Please also advise whether it makes sense to implement the same optimization
for float types and if so, under which conditions?

Signed-off-by: Jennifer Schmitz 

gcc/

* config/aarch64/aarch64-sve-builtins-base.cc (svdiv_impl::fold):
Add optimization.

gcc/testsuite/

* gcc.target/aarch64/sve/acle/asm/div_s32.c: New test.
* gcc.target/aarch64/sve/acle/asm/div_s64.c: Likewise.
* gcc.target/aarch64/sve/acle/asm/div_u32.c: Likewise.
* gcc.target/aarch64/sve/acle/asm/div_u64.c: Likewise.


0001-SVE-intrinsics-Fold-svdiv-svptrue-x-x-to-ones.patch
Description: Binary data


smime.p7s
Description: S/MIME cryptographic signature


Re: [PATCH] c++: Add unsequenced C++ testcase

2024-08-02 Thread Jason Merrill

On 8/1/24 2:43 PM, Jakub Jelinek wrote:

Hi!

This is the testcase I wrote originally and which on top of the
https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659154.html
patch didn't behave the way I wanted (no warning and no optimizations of
[[unsequenced]] function templates which don't have pointer/reference
arguments.
Posting this separately, because it depends on the above mentioned
patch as well as the PR116175
https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659157.html
patch.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?


OK.


2024-08-01  Jakub Jelinek  

* g++.dg/ext/attr-unsequenced-1.C: New test.

--- gcc/testsuite/g++.dg/ext/attr-unsequenced-1.C.jj2024-08-01 
16:57:52.309618653 +0200
+++ gcc/testsuite/g++.dg/ext/attr-unsequenced-1.C   2024-08-01 
16:53:36.711859089 +0200
@@ -0,0 +1,53 @@
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -fdump-tree-optimized" } */
+// { dg-final { scan-tree-dump-times " bar \\\(1, 2, 3\\\);" 1 
"optimized" } }
+// { dg-final { scan-tree-dump-times " bar \\\(4, 5, 6\\\);" 1 
"optimized" } }
+
+template 
+[[gnu::noipa]] U
+foo (T x, T y, T z) [[gnu::unsequenced]]
+{
+  *x = 1;
+  *y = 2;
+  *z = 3;
+}
+
+template 
+[[gnu::noipa]] T
+bar (T x, T y, T z) [[gnu::unsequenced]]
+{
+  return x + y + z;
+}
+
+int
+baz () [[gnu::unsequenced]]
+{
+  int x, y, z;
+  foo  (&x, &y, &z);
+  return x;
+}
+
+int
+qux () [[gnu::unsequenced]]
+{
+  int a = bar (1, 2, 3);
+  int b = bar (1, 2, 3);
+  int c = bar (1, 2, 3);
+  int d = bar (4, 5, 6);
+  int e = bar (4, 5, 6);
+  int f = bar (4, 5, 6);
+  return a + b + c + d + e + f;
+}
+
+template 
+[[gnu::noipa]] U
+corge (T x, T y, T z) [[gnu::unsequenced]] // { dg-warning "'unsequenced' 
attribute on function type without pointer arguments returning 'void'" }
+{
+  x += y + z;
+}
+
+void
+freddy ()
+{
+  corge  (1, 2, 3);
+}

Jakub





[Patch, Fortran] PR104626 ICE in gfc_format_decoder, at fortran/error.cc:1071

2024-08-02 Thread Jerry D

Hi all,

Doing some catchup here. I plan to commit the following shortly. This is 
one of Steve's patches posted on bugzilla.


I have created a new test case.

Regression tested on linux x86-64.

git show:

commit 4d4549937b789afe4037c2f8f80dfc2285504a1e (HEAD -> master)
Author: Steve Kargl 
Date:   Thu Aug 1 21:50:49 2024 -0700

Fortran: Fix ICE on invalid in gfc_format_decoder.

PR fortran/104626

gcc/fortran/ChangeLog:

* symbol.cc (gfc_add_save): Add checks for SAVE attribute
conflicts and duplicate SAVE attribute.

gcc/testsuite/ChangeLog:

* gfortran.dg/pr104626.f90: New test.

diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc
index a8479b862e3..b5143d9f790 100644
--- a/gcc/fortran/symbol.cc
+++ b/gcc/fortran/symbol.cc
@@ -1307,9 +1307,8 @@ gfc_add_save (symbol_attribute *attr, save_state 
s, const char *name,


   if (s == SAVE_EXPLICIT && gfc_pure (NULL))
 {
-  gfc_error
-   ("SAVE attribute at %L cannot be specified in a PURE procedure",
-where);
+  gfc_error ("SAVE attribute at %L cannot be specified in a PURE "
+"procedure", where);
   return false;
 }

@@ -1319,10 +1318,15 @@ gfc_add_save (symbol_attribute *attr, save_state 
s, const char *name,

   if (s == SAVE_EXPLICIT && attr->save == SAVE_EXPLICIT
   && (flag_automatic || pedantic))
 {
-   if (!gfc_notify_std (GFC_STD_LEGACY,
-"Duplicate SAVE attribute specified at %L",
-where))
+  if (!where)
+   {
+ gfc_error ("Duplicate SAVE attribute specified near %C");
  return false;
+   }
+
+  if (!gfc_notify_std (GFC_STD_LEGACY, "Duplicate SAVE attribute "
+  "specified at %L", where))
+   return false;
 }

   attr->save = s;
diff --git a/gcc/testsuite/gfortran.dg/pr104626.f90 
b/gcc/testsuite/gfortran.dg/pr104626.f90

new file mode 100644
index 000..faff65a8c92
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr104626.f90
@@ -0,0 +1,8 @@
+! { dg-do compile }
+program p
+   procedure(g), save :: f ! { dg-error "PROCEDURE attribute conflicts" }
+   procedure(g), save :: f ! { dg-error "Duplicate SAVE attribute" }
+contains
+   subroutine g
+   end
+end


[PATCH] c++: remove function/var concepts code

2024-08-02 Thread Marek Polacek
Bootstrapped/regtested on x86_64-pc-linux-gnu.  Comments?

-- >8 --
This patch removes vestigial Concepts TS code as discussed in
.

In particular, it removes code related to function/variable concepts.
That includes variable_concept_p and function_concept_p, which then
cascades into removing DECL_DECLARED_CONCEPT_P etc.  So I think we
no longer need to say "standard concept" since there are no non-standard
ones anymore.

I've added two new errors saying that "variable/function concepts are
no longer supported".

gcc/cp/ChangeLog:

* constexpr.cc (cxx_eval_constant_expression): Don't call
unpack_concept_check.  Add a concept_check_p assert.  Remove
function_concept_p code.
* constraint.cc (check_constraint_atom): Remove function concepts code.
(unpack_concept_check): Remove.
(get_concept_check_template): Remove Concepts TS code.
(resolve_function_concept_overload): Remove.
(resolve_function_concept_check): Remove.
(resolve_concept_check): Remove Concepts TS code.
(get_returned_expression): Remove.
(get_variable_initializer): Remove.
(get_concept_definition): Remove Concepts TS code.
(normalize_concept_check): Likewise.
(build_function_check): Remove.
(build_variable_check): Remove.
(build_standard_check): Use concept_definition_p instead of
standard_concept_p.
(build_concept_check): Remove variable_concept_p/function_concept_p
code.
(build_concept_id): Simplify.
(build_type_constraint): Likewise.
(placeholder_extract_concept_and_args): Likewise.
(satisfy_nondeclaration_constraints): Likewise.
(check_function_concept): Remove.
(get_constraint_error_location): Remove Concepts TS code.
* cp-tree.h (DECL_DECLARED_CONCEPT_P): Remove.
(check_function_concept): Remove.
(unpack_concept_check): Remove.
(standard_concept_p): Remove.
(variable_concept_p): Remove.
(function_concept_p): Remove.
(concept_definition_p): Simplify.
(concept_check_p): Don't check for CALL_EXPR.
* decl.cc (check_concept_refinement): Remove.
(duplicate_decls): Remove check_concept_refinement code.
(is_concept_var): Remove.
(cp_finish_decl): Remove is_concept_var.
(check_concept_fn): Remove.
(grokfndecl): Give an error about function concepts not being supported
anymore.  Remove unused code.
(grokvardecl): Give an error about variable concepts not being
supported anymore.
(finish_function): Remove DECL_DECLARED_CONCEPT_P code.
* decl2.cc (min_vis_expr_r): Use concept_definition_p instead of
standard_concept_p.
(maybe_instantiate_decl): Remove DECL_DECLARED_CONCEPT_P check.
(mark_used): Likewise.
* error.cc (dump_simple_decl): Use concept_definition_p instead of
standard_concept_p.
(dump_function_decl): Remove DECL_DECLARED_CONCEPT_P code.
(print_concept_check_info): Don't call unpack_concept_check.
* mangle.cc (write_type_constraint): Likewise.
* parser.cc (cp_parser_nested_name_specifier_opt): Remove
function_concept_p code.  Only check concept_definition_p, not
variable_concept_p/standard_concept_p.
(add_debug_begin_stmt): Remove DECL_DECLARED_CONCEPT_P code.
(cp_parser_template_declaration_after_parameters): Remove a stale
comment.
* pt.cc (check_explicit_specialization): Remove
DECL_DECLARED_CONCEPT_P code.
(process_partial_specialization): Remove variable_concept_p code.
(lookup_template_variable): Likewise.
(tsubst_expr) : Remove Concepts TS code and simplify.
(do_decl_instantiation): Remove DECL_DECLARED_CONCEPT_P code.
(instantiate_decl): Likewise.
(placeholder_type_constraint_dependent_p): Don't call
unpack_concept_check.  Add a concept_check_p assert.
(convert_generic_types_to_packs): Likewise.
* semantics.cc (finish_call_expr): Remove Concepts TS code and simplify.

gcc/testsuite/ChangeLog:

* g++.dg/concepts/decl-diagnose.C: Adjust dg-error.
* g++.dg/concepts/fn-concept2.C: Likewise.
* g++.dg/concepts/pr71128.C: Likewise.
* g++.dg/concepts/var-concept6.C: Likewise.
* g++.dg/cpp2a/concepts.C: Likewise.
---
 gcc/cp/constexpr.cc   |  13 +-
 gcc/cp/constraint.cc  | 346 +-
 gcc/cp/cp-tree.h  |  71 +---
 gcc/cp/decl.cc| 118 +-
 gcc/cp/decl2.cc   |   4 +-
 gcc/cp/error.cc   |  10 +-
 gcc/cp/mangle.cc  |   4 +-
 gcc/cp/parser.cc  |  16 +-
 gcc/cp/pt.cc

Re: [PATCH] c++: Move -Wdangling-reference to -Wextra

2024-08-02 Thread Marek Polacek
On Thu, Aug 01, 2024 at 05:18:35PM -0400, Jason Merrill wrote:
> On 8/1/24 4:20 PM, Marek Polacek wrote:
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > 
> > -- >8 --
> > Despite a number of mitigations (don't warn for std::span-like classes,
> > lambdas, adding [[gnu::no_dangling]], etc.), the warning still seems to
> > cause some grief.  Let's move the warning to -Wextra, then.
> 
> Any references to the grief?

Two recent:
https://gcc.gnu.org/PR115361
https://gcc.gnu.org/PR115730

> The patch is OK.

Thanks.

Marek



Re: [PATCH] c++: permit errors inside uninstantiated templates [PR116064]

2024-08-02 Thread Patrick Palka
On Fri, 2 Aug 2024, Jason Merrill wrote:

> On 8/1/24 2:52 PM, Patrick Palka wrote:
> > In recent versions of GCC we've been diagnosing more and more kinds of
> > errors inside a template ahead of time.  This is a largely good thing
> > because it catches bugs, typos, dead code etc sooner.
> > 
> > But if the template never gets instantiated then such errors are
> > harmless, and can be inconvenient to work around if say the code in
> > question is third party and in maintenence mode.  So it'd be useful to
> 
> "maintenance"

Fixed

> 
> > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
> > index d80bac822ba..0bb0a482e28 100644
> > --- a/gcc/cp/error.cc
> > +++ b/gcc/cp/error.cc
> > @@ -165,6 +165,58 @@ class cxx_format_postprocessor : public
> > format_postprocessor
> > deferred_printed_type m_type_b;
> >   };
> >   +/* A map from TEMPLATE_DECL to the location of the first error (if any)
> > +   within the template that we permissivly downgraded to a warning.  */
> 
> "permissively"

Fixed

> 
> > +relaxed_template_errors_t *relaxed_template_errors;
> > +
> > +/* Callback function diagnostic_context::m_adjust_diagnostic_info.
> > +
> > +   In -fpermissive mode we downgrade errors within a template to
> > +   warnings, and only issue an error if we later need to instantiate
> > +   the template.  */
> > +
> > +static void
> > +cp_adjust_diagnostic_info (diagnostic_context *context,
> > +  diagnostic_info *diagnostic)
> > +{
> > +  tree ti;
> > +  if (diagnostic->kind == DK_ERROR
> > +  && context->m_permissive
> > +  && !current_instantiation ()
> > +  && in_template_context
> > +  && (ti = get_template_info (current_scope (
> > +{
> > +  if (!relaxed_template_errors)
> > +   relaxed_template_errors = new relaxed_template_errors_t;
> > +
> > +  tree tmpl = TI_TEMPLATE (ti);
> > +  if (!relaxed_template_errors->get (tmpl))
> > +   relaxed_template_errors->put (tmpl, diagnostic->richloc->get_loc ());
> > +  diagnostic->kind = DK_WARNING;
> 
> Rather than check m_permissive directly and downgrade to DK_WARNING, how about
> downgrading to DK_PERMERROR?  That way people will get the [-fpermissive]
> clue.
> 
> ...though I suppose DK_PERMERROR doesn't work where you call this hook in
> report_diagnostic, at which point we've already reassigned it into DK_WARNING
> or DK_ERROR in diagnostic_impl.
> 
> But we could still set diagnostic->option_index even for DK_ERROR, whether to
> context->m_opt_permissive or to its own warning flag, perhaps
> -Wno-template-body?

Fixed by adding an enabled-by-default -Wtemplate-body flag and setting
option_index to it for each downgraded error.  Thus -permissive
-Wno-template-body would suppress the downgraded warnings entirely, and
only issue a generic error upon instantiation of the erroneous template.

> 
> > +/* A generalization of seen_error which also returns true if we've
> > +   permissively downgraded an error to a warning inside a template.  */
> > +
> > +bool
> > +cp_seen_error ()
> > +{
> > +#undef seen_error
> > +  if (seen_error ())
> > +return true;
> > +
> > +  tree ti;
> > +  if (relaxed_template_errors
> > +  && in_template_context
> > +  && (ti = get_template_info (current_scope ()))
> 
> Let's factor the "in template body" checks in this function and the previous
> one into a separate function; I expect we want the !current_instantiation test
> in this case as well?

Done.
> 
> > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > index 77fa5907c3d..b58ccb318d5 100644
> > --- a/gcc/cp/pt.cc
> > +++ b/gcc/cp/pt.cc
> > @@ -12376,6 +12376,22 @@ instantiate_class_template (tree type)
> > if (! push_tinst_level (type))
> >   return type;
> >   +  if (relaxed_template_errors)
> > +if (location_t *error_loc = relaxed_template_errors->get (templ))
> > +  {
> > +   /* We're trying to instantiate a template pattern containing
> > +  an error that we've permissively downgraded to a warning.
> > +  Issue a hard error now.  */
> > +   location_t decl_loc = location_of (templ);
> > +   error_at (decl_loc, "instantiating erroneous template pattern");
> 
> I wouldn't use the internal term "pattern" in diagnostics, I think just
> "erroneous template" is enough.

Fixed

> 
> > @@ -27291,6 +27307,20 @@ instantiate_decl (tree d, bool defer_ok, bool
> > expl_inst_class_mem_p)
> > }
> >   }
> >   +  if (relaxed_template_errors)
> > +if (location_t *error_loc = relaxed_template_errors->get (td))
> > +  {
> > +   /* We're trying to instantiate a template pattern containing
> > +  an error that we've permissively downgraded to a warning.
> > +  Issue a hard error now.  */
> > +   location_t decl_loc = location_of (td);
> > +   error_at (decl_loc, "instantiating erroneous template pattern");
> 
> Likewise.

Fixed.

> 
> > diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
> > index 71d2f44e40c..cbd2c82f19d 100644
> > --- a/gcc/diagnostic.cc
> > +++ b/gcc/diagnostic.cc
> >

Re: [PATCH 0/1] Initial support for AVX10.2

2024-08-02 Thread Andi Kleen
> 
> INT8 is actually char per my understanding.
> 
> For FP8, currently there is no basic calculation insts yet. So we have no
> support for them in AVX10.2 currently, and treat them just as a piece
> of char.
> 
> Also there might be other issues for FP8 to discuss, like ABI issues, so
> we put the support aside for now. When everything is mature, we may
> add the support for that.

But then it's too late isn't it? You wouldn't be able to change
the types of the existing intrinsics anymore, or later end up with
two sets of intrinsics, and end up with interoperability problems
with full computation.

Better to define proper types from the beginning.

-Andi


Re: [PATCH] c++: Move -Wdangling-reference to -Wextra

2024-08-02 Thread Patrick Palka
On Fri, 2 Aug 2024, Marek Polacek wrote:

> On Thu, Aug 01, 2024 at 05:18:35PM -0400, Jason Merrill wrote:
> > On 8/1/24 4:20 PM, Marek Polacek wrote:
> > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > 
> > > -- >8 --
> > > Despite a number of mitigations (don't warn for std::span-like classes,
> > > lambdas, adding [[gnu::no_dangling]], etc.), the warning still seems to
> > > cause some grief.  Let's move the warning to -Wextra, then.
> > 
> > Any references to the grief?
> 
> Two recent:
> https://gcc.gnu.org/PR115361
> https://gcc.gnu.org/PR115730

FWIW PR115361 suggested adding another mitigation:

  Since the heuristic is concerned only with dangling references to
  *members of the GetKey object itself*, could you maybe add yet another
  heuristic to suppress the warning whenever the GetKey object is_empty?

That seems sensible to me, and would also resolve PR115229.

> 
> > The patch is OK.
> 
> Thanks.
> 
> Marek
> 
> 



[PATCH v2] c++: fix -Wdangling-reference false positive [PR115987]

2024-08-02 Thread Marek Polacek
On Thu, Aug 01, 2024 at 05:20:43PM -0400, Jason Merrill wrote:
> On 8/1/24 4:19 PM, Marek Polacek wrote:
> > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > 
> > -- >8 --
> > This fixes another false positive.  When a function is taking a
> > temporary of scalar type that couldn't be bound to the return type
> > of the function, don't warn, such a program would be ill-formed.
> > 
> > Thanks to Jonathan for reporting the problem.
> > 
> > PR c++/115987
> > 
> > gcc/cp/ChangeLog:
> > 
> > * call.cc (do_warn_dangling_reference): Don't consider a
> > temporary with a scalar type that cannot bind to the return type.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/warn/Wdangling-reference22.C: New test.
> > ---
> >   gcc/cp/call.cc| 15 +--
> >   .../g++.dg/warn/Wdangling-reference22.C   | 19 +++
> >   2 files changed, 32 insertions(+), 2 deletions(-)
> >   create mode 100644 gcc/testsuite/g++.dg/warn/Wdangling-reference22.C
> > 
> > diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
> > index 40cb582acc7..375256ebcc4 100644
> > --- a/gcc/cp/call.cc
> > +++ b/gcc/cp/call.cc
> > @@ -14290,8 +14290,19 @@ do_warn_dangling_reference (tree expr, bool arg_p)
> > /* Recurse to see if the argument is a temporary.  It could also
> >be another call taking a temporary and returning it and
> >initializing this reference parameter.  */
> > -   if (do_warn_dangling_reference (arg, /*arg_p=*/true))
> > - return expr;
> > +   if ((arg = do_warn_dangling_reference (arg, /*arg_p=*/true)))
> > + {
> > +   /* If we know the temporary could not bind to the return type,
> > +  don't warn.  This is for scalars only because for classes
> > +  we can't be sure we are not returning its sub-object.  */
> > +   if (SCALAR_TYPE_P (TREE_TYPE (arg))
> > +   && TYPE_REF_P (rettype)
> > +   && SCALAR_TYPE_P (TREE_TYPE (rettype))
> 
> I don't think we need to check for scalar return type, only argument type.

Oh that was a late change to keep attr-no-dangling6.C working, i.e., to
keep warning for something like

  struct X { X(int); };
  const X& get (const int& i)
  {
 return i;
  }

  void test ()
  {
[[maybe_unused]] const X& x2 = get (10);
  }

But we already emit a -Wreturn-local-addr warning there.  So, I've dropped
the SCALAR_TYPE_P check and adjusted attr-no-dangling6.C instead:

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
This fixes another false positive.  When a function is taking a
temporary of scalar type that couldn't be bound to the return type
of the function, don't warn, such a program would be ill-formed.

Thanks to Jonathan for reporting the problem.

PR c++/115987

gcc/cp/ChangeLog:

* call.cc (do_warn_dangling_reference): Don't consider a
temporary with a scalar type that cannot bind to the return type.

gcc/testsuite/ChangeLog:

* g++.dg/ext/attr-no-dangling6.C: Adjust.
* g++.dg/ext/attr-no-dangling7.C: Likewise.
* g++.dg/warn/Wdangling-reference22.C: New test.
---
 gcc/cp/call.cc| 14 ++--
 gcc/testsuite/g++.dg/ext/attr-no-dangling6.C  | 22 +--
 gcc/testsuite/g++.dg/ext/attr-no-dangling7.C  |  8 +++
 .../g++.dg/warn/Wdangling-reference22.C   | 19 
 4 files changed, 46 insertions(+), 17 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/Wdangling-reference22.C

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 40cb582acc7..a75e2e5e3af 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -14290,8 +14290,18 @@ do_warn_dangling_reference (tree expr, bool arg_p)
/* Recurse to see if the argument is a temporary.  It could also
   be another call taking a temporary and returning it and
   initializing this reference parameter.  */
-   if (do_warn_dangling_reference (arg, /*arg_p=*/true))
- return expr;
+   if ((arg = do_warn_dangling_reference (arg, /*arg_p=*/true)))
+ {
+   /* If we know the temporary could not bind to the return type,
+  don't warn.  This is for scalars only because for classes
+  we can't be sure we are not returning its sub-object.  */
+   if (SCALAR_TYPE_P (TREE_TYPE (arg))
+   && TYPE_REF_P (rettype)
+   && !reference_related_p (TREE_TYPE (arg),
+TREE_TYPE (rettype)))
+ continue;
+   return expr;
+ }
  /* Don't warn about member functions like:
  std::any a(...);
  S& s = a.emplace({0}, 0);
diff --git a/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C 
b/gcc/testsuite/g++.dg/ext/attr-no-dangling6.C
index 235a5fd86c5..5b349e8e682 100644
--- a/gcc/testsuite/g++

Re: [PATCH] c++: permit errors inside uninstantiated templates [PR116064]

2024-08-02 Thread Patrick Palka
On Fri, 2 Aug 2024, Patrick Palka wrote:

> On Fri, 2 Aug 2024, Jason Merrill wrote:
> 
> > On 8/1/24 2:52 PM, Patrick Palka wrote:
> > > In recent versions of GCC we've been diagnosing more and more kinds of
> > > errors inside a template ahead of time.  This is a largely good thing
> > > because it catches bugs, typos, dead code etc sooner.
> > > 
> > > But if the template never gets instantiated then such errors are
> > > harmless, and can be inconvenient to work around if say the code in
> > > question is third party and in maintenence mode.  So it'd be useful to
> > 
> > "maintenance"
> 
> Fixed
> 
> > 
> > > diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
> > > index d80bac822ba..0bb0a482e28 100644
> > > --- a/gcc/cp/error.cc
> > > +++ b/gcc/cp/error.cc
> > > @@ -165,6 +165,58 @@ class cxx_format_postprocessor : public
> > > format_postprocessor
> > > deferred_printed_type m_type_b;
> > >   };
> > >   +/* A map from TEMPLATE_DECL to the location of the first error (if any)
> > > +   within the template that we permissivly downgraded to a warning.  */
> > 
> > "permissively"
> 
> Fixed
> 
> > 
> > > +relaxed_template_errors_t *relaxed_template_errors;
> > > +
> > > +/* Callback function diagnostic_context::m_adjust_diagnostic_info.
> > > +
> > > +   In -fpermissive mode we downgrade errors within a template to
> > > +   warnings, and only issue an error if we later need to instantiate
> > > +   the template.  */
> > > +
> > > +static void
> > > +cp_adjust_diagnostic_info (diagnostic_context *context,
> > > +diagnostic_info *diagnostic)
> > > +{
> > > +  tree ti;
> > > +  if (diagnostic->kind == DK_ERROR
> > > +  && context->m_permissive
> > > +  && !current_instantiation ()
> > > +  && in_template_context
> > > +  && (ti = get_template_info (current_scope (
> > > +{
> > > +  if (!relaxed_template_errors)
> > > + relaxed_template_errors = new relaxed_template_errors_t;
> > > +
> > > +  tree tmpl = TI_TEMPLATE (ti);
> > > +  if (!relaxed_template_errors->get (tmpl))
> > > + relaxed_template_errors->put (tmpl, diagnostic->richloc->get_loc ());
> > > +  diagnostic->kind = DK_WARNING;
> > 
> > Rather than check m_permissive directly and downgrade to DK_WARNING, how 
> > about
> > downgrading to DK_PERMERROR?  That way people will get the [-fpermissive]
> > clue.
> > 
> > ...though I suppose DK_PERMERROR doesn't work where you call this hook in
> > report_diagnostic, at which point we've already reassigned it into 
> > DK_WARNING
> > or DK_ERROR in diagnostic_impl.
> > 
> > But we could still set diagnostic->option_index even for DK_ERROR, whether 
> > to
> > context->m_opt_permissive or to its own warning flag, perhaps
> > -Wno-template-body?
> 
> Fixed by adding an enabled-by-default -Wtemplate-body flag and setting
> option_index to it for each downgraded error.  Thus -permissive
> -Wno-template-body would suppress the downgraded warnings entirely, and
> only issue a generic error upon instantiation of the erroneous template.

... or did you have in mind to set option_index even when not using
-fpermissive so that eligible non-downgraded errors get the
[-fpermissive] or [-Wtemplate-body] hint as well?

IMHO I'm not sure that'd be worth the extra noise since the vast
majority of users appreciate and expect errors to get diagnosed inside
templates.

And on second thought I'm not sure what extra value a new warning flag
adds either.  I can't think of a good reason why one would use
-fpermissive -Wno-template-body?

> 
> > 
> > > +/* A generalization of seen_error which also returns true if we've
> > > +   permissively downgraded an error to a warning inside a template.  */
> > > +
> > > +bool
> > > +cp_seen_error ()
> > > +{
> > > +#undef seen_error
> > > +  if (seen_error ())
> > > +return true;
> > > +
> > > +  tree ti;
> > > +  if (relaxed_template_errors
> > > +  && in_template_context
> > > +  && (ti = get_template_info (current_scope ()))
> > 
> > Let's factor the "in template body" checks in this function and the previous
> > one into a separate function; I expect we want the !current_instantiation 
> > test
> > in this case as well?
> 
> Done.
> > 
> > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > > index 77fa5907c3d..b58ccb318d5 100644
> > > --- a/gcc/cp/pt.cc
> > > +++ b/gcc/cp/pt.cc
> > > @@ -12376,6 +12376,22 @@ instantiate_class_template (tree type)
> > > if (! push_tinst_level (type))
> > >   return type;
> > >   +  if (relaxed_template_errors)
> > > +if (location_t *error_loc = relaxed_template_errors->get (templ))
> > > +  {
> > > + /* We're trying to instantiate a template pattern containing
> > > +an error that we've permissively downgraded to a warning.
> > > +Issue a hard error now.  */
> > > + location_t decl_loc = location_of (templ);
> > > + error_at (decl_loc, "instantiating erroneous template pattern");
> > 
> > I wouldn't use the internal term "pattern" in diagnostics, I think just
>

Re: [PATCH] Make may_trap_p_1 return false for constant pool references [PR116145]

2024-08-02 Thread Andrew Pinski
On Wed, Jul 31, 2024 at 9:41 AM Richard Sandiford
 wrote:
>
> The testcase contains the constant:
>
>   arr2 = svreinterpret_u8(svdup_u32(0x0a0d5c3f));
>
> which was initially hoisted by hand, but which gimple optimisers later
> propagated to each use (as expected).  The constant was then expanded
> as a load-and-duplicate from the constant pool.  Normally that load
> should then be hoisted back out of the loop, but may_trap_or_fault_p
> stopped that from happening in this case.
>
> The code responsible was:
>
>   if (/* MEM_NOTRAP_P only relates to the actual position of the memory
>  reference; moving it out of context such as when moving code
>  when optimizing, might cause its address to become invalid.  */
>   code_changed
>   || !MEM_NOTRAP_P (x))
> {
>   poly_int64 size = MEM_SIZE_KNOWN_P (x) ? MEM_SIZE (x) : -1;
>   return rtx_addr_can_trap_p_1 (XEXP (x, 0), 0, size,
> GET_MODE (x), code_changed);
> }
>
> where code_changed is true.  (Arguably it doesn't need to be true in
> this case, if we inserted invariants on the preheader edge, but it
> would still need to be true for conditionally executed loads.)
>
> Normally this wouldn't be a problem, since rtx_addr_can_trap_p_1
> would recognise that the address refers to the constant pool.
> However, the SVE load-and-replicate instructions have a limited
> offset range, so it isn't possible for them to have a LO_SUM address.
> All we have is a plain pseudo base register.
>
> MEM_READONLY_P is defined as:
>
> /* 1 if RTX is a mem that is statically allocated in read-only memory.  */
>   (RTL_FLAG_CHECK1 ("MEM_READONLY_P", (RTX), MEM)->unchanging)
>
> and so I think it should be safe to move memory references if both
> MEM_READONLY_P and MEM_NOTRAP_P are true.
>
> The testcase isn't a minimal reproducer, but I think it's good
> to have a realistic full routine in the testsuite.
>
> Bootstrapped & regression-tested on aarch64-linux-gnu.  OK to install?


This is breaking the build on a few targets (x86_64 and powerpc64le so
far reported, see PR 116200).

>From what I can tell is that it is treating `(plus:DI (ashift:DI
(reg:DI 0 ax [690]) (const_int 3 [0x3]))  (label_ref:DI 1620))` as not
trapping and allowing it to be moved before the check of ax being in
the range [0..2] and we have eax being (unsigned long)(unsigned int)-9
in value. So we get a bogus address which will trap. I put my findings
in PR 116200 too.

Thanks,
Andrew Pinski


>
> Richard
>
>
> gcc/
> PR rtl-optimization/116145
> * rtlanal.cc (may_trap_p_1): Trust MEM_NOTRAP_P even for code
> movement if MEM_READONLY_P is also true.
>
> gcc/testsuite/
> PR rtl-optimization/116145
> * gcc.target/aarch64/sve/acle/general/pr116145.c: New test.
> ---
>  gcc/rtlanal.cc| 14 --
>  .../aarch64/sve/acle/general/pr116145.c   | 46 +++
>  2 files changed, 56 insertions(+), 4 deletions(-)
>  create mode 100644 
> gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr116145.c
>
> diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc
> index 4158a531bdd..893a6afbbc5 100644
> --- a/gcc/rtlanal.cc
> +++ b/gcc/rtlanal.cc
> @@ -3152,10 +3152,16 @@ may_trap_p_1 (const_rtx x, unsigned flags)
>   && MEM_VOLATILE_P (x)
>   && XEXP (x, 0) == stack_pointer_rtx)
> return true;
> -  if (/* MEM_NOTRAP_P only relates to the actual position of the memory
> -reference; moving it out of context such as when moving code
> -when optimizing, might cause its address to become invalid.  */
> - code_changed
> +  if (/* MEM_READONLY_P means that the memory is both statically
> +allocated and readonly, so MEM_NOTRAP_P should remain true
> +even if the memory reference is moved.  This is certainly
> +true for the important case of force_const_mem.
> +
> +Otherwise, MEM_NOTRAP_P only relates to the actual position
> +of the memory reference; moving it out of context such as
> +when moving code when optimizing, might cause its address
> +to become invalid.  */
> + (code_changed && !MEM_READONLY_P (x))
>   || !MEM_NOTRAP_P (x))
> {
>   poly_int64 size = MEM_SIZE_KNOWN_P (x) ? MEM_SIZE (x) : -1;
> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr116145.c 
> b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr116145.c
> new file mode 100644
> index 000..a3d93d3e1c8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/sve/acle/general/pr116145.c
> @@ -0,0 +1,46 @@
> +// { dg-options "-O2" }
> +
> +#include 
> +#include 
> +
> +#pragma GCC target "+sve2"
> +
> +typedef unsigned char uchar;
> +
> +const uchar *
> +search_line_fast (const uchar *s, const uchar *end)
> +{
> +  size_t VL = svcntb();
> +  svuint8_t arr1, arr2;
> +  svbool_t pc,

[PATCH] libstdc++: Do not use deduced return type for std::forward_like

2024-08-02 Thread Jonathan Wakely
This isn't properly tested so I'm not pushing it, but I'm sharing it now
for comment.

-- >8 --

Inspired by https://github.com/llvm/llvm-project/issues/101614 this
replaces the deduced return type of std::forward_like with a type trait
to compute that type.

libstdc++-v3/ChangeLog:

* include/bits/move.h (__forward_like_impl): New metafunction to
compute the return type of std::forward_like.
(forward_like, __like_t): Use it.
* testsuite/20_util/forward_like/2_neg.cc: Adjust expected
errors.
---
 libstdc++-v3/include/bits/move.h  | 45 +--
 .../testsuite/20_util/forward_like/2_neg.cc   |  2 +-
 2 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index bb200c95964..15b7cd07fce 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -88,31 +88,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __glibcxx_forward_like // C++ >= 23
   template
-  [[nodiscard]]
-  constexpr decltype(auto)
-  forward_like(_Up&& __x) noexcept
-  {
-constexpr bool __as_rval = is_rvalue_reference_v<_Tp&&>;
-
-if constexpr (is_const_v>)
-  {
-   using _Up2 = remove_reference_t<_Up>;
-   if constexpr (__as_rval)
- return static_cast(__x);
-   else
- return static_cast(__x);
-  }
-else
-  {
-   if constexpr (__as_rval)
- return static_cast&&>(__x);
-   else
- return static_cast<_Up&>(__x);
-  }
-  }
+struct __forward_like_impl
+{
+#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_reference)
+  template using __remove_ref_t = __remove_reference(_Xp);
+#else
+  template using __remove_ref_t = remove_reference_t<_Xp>;
+#endif
+  template
+   using _Copy_const = __conditional_t, const _Yp, _Yp>;
+  template
+   using _Override_ref = __conditional_t,
+ __remove_ref_t<_Yp>&&, _Yp&>;
+  using type = _Override_ref<_Tp&&, _Copy_const<__remove_ref_t<_Tp>,
+   __remove_ref_t<_Up>>>;
+};
 
   template
-using __like_t = decltype(std::forward_like<_Tp>(std::declval<_Up>()));
+using __like_t = typename __forward_like_impl<_Tp, _Up>::type;
+
+  template
+[[nodiscard]]
+constexpr __like_t<_Tp, _Up>
+forward_like(_Up&& __x) noexcept
+{ return static_cast<__like_t<_Tp, _Up>>(__x); }
 #endif
 
   /**
diff --git a/libstdc++-v3/testsuite/20_util/forward_like/2_neg.cc 
b/libstdc++-v3/testsuite/20_util/forward_like/2_neg.cc
index ff835af1915..f6e98420a9a 100644
--- a/libstdc++-v3/testsuite/20_util/forward_like/2_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/forward_like/2_neg.cc
@@ -7,4 +7,4 @@ auto x1 = std::forward_like(1); // { dg-error "here" }
 auto x2 = std::forward_like(1); // { dg-error "here" }
 // { dg-error "forming reference to qualified function" "" { target *-*-* } 0 }
 
-// { dg-prune-output "inconsistent deduction for auto return type" } // 
PR111484
+// { dg-prune-output "no matching function" }
-- 
2.45.2



Re: [PATCH] PR116080: Fix test suite checks for musttail

2024-08-02 Thread Andi Kleen
Andi Kleen  writes:

> From: Andi Kleen 
>
> This is a new attempt to fix PR116080. The previous try was reverted
> because it just broke a bunch of tests, hiding the problem.

The previous version still had one failure on powerpc because
of a template call that needs a dg-error check for external_tail_call.
I fixed that now in the below version.

Okay for trunk? I would like to check that one in to avoid the noise
in the regression reports.

---

This is a new attempt to fix PR116080. The previous try was reverted
because it just broke a bunch of tests, hiding the problem.

- musttail behaves differently than tailcall at -O0. Some of the test
run at -O0, so add separate effective target tests for musttail.
- New effective target tests need to use unique file names
to make dejagnu caching work
- Change the tests to use new targets
- Add a external_musttail test to check for target's ability
to do tail calls between translation units. This covers some powerpc
ABIs.

gcc/testsuite/ChangeLog:

PR testsuite/116080
* c-c++-common/musttail1.c: Use musttail target.
* c-c++-common/musttail12.c: Use struct_musttail target.
* c-c++-common/musttail2.c: Use musttail target.
* c-c++-common/musttail3.c: Likewise.
* c-c++-common/musttail4.c: Likewise.
* c-c++-common/musttail7.c: Likewise.
* c-c++-common/musttail8.c: Likewise.
* g++.dg/musttail10.C: Likewise. Replace powerpc checks with
external_musttail.
* g++.dg/musttail11.C: Use musttail target.
* g++.dg/musttail6.C: Use musttail target. Replace powerpc
checks with external_musttail.
* g++.dg/musttail9.C: Use musttail target.
* lib/target-supports.exp: Add musttail, struct_musttail,
external_musttail targets. Remove optimization for musttail.
Use unique file names for musttail.
---
 gcc/testsuite/c-c++-common/musttail1.c  |  2 +-
 gcc/testsuite/c-c++-common/musttail12.c |  2 +-
 gcc/testsuite/c-c++-common/musttail2.c  |  2 +-
 gcc/testsuite/c-c++-common/musttail3.c  |  2 +-
 gcc/testsuite/c-c++-common/musttail4.c  |  2 +-
 gcc/testsuite/c-c++-common/musttail7.c  |  2 +-
 gcc/testsuite/c-c++-common/musttail8.c  |  2 +-
 gcc/testsuite/g++.dg/musttail10.C   |  6 ++---
 gcc/testsuite/g++.dg/musttail11.C   |  2 +-
 gcc/testsuite/g++.dg/musttail6.C|  4 ++--
 gcc/testsuite/g++.dg/musttail9.C|  2 +-
 gcc/testsuite/lib/target-supports.exp   | 30 -
 12 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/gcc/testsuite/c-c++-common/musttail1.c 
b/gcc/testsuite/c-c++-common/musttail1.c
index 74efcc2a0bc6..51549672e02a 100644
--- a/gcc/testsuite/c-c++-common/musttail1.c
+++ b/gcc/testsuite/c-c++-common/musttail1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+/* { dg-do compile { target { musttail && { c || c++11 } } } } */
 /* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */
 
 int __attribute__((noinline,noclone,noipa))
diff --git a/gcc/testsuite/c-c++-common/musttail12.c 
b/gcc/testsuite/c-c++-common/musttail12.c
index 4140bcd00950..475afc5af3f3 100644
--- a/gcc/testsuite/c-c++-common/musttail12.c
+++ b/gcc/testsuite/c-c++-common/musttail12.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { struct_tail_call && { c || c++11 } } } } */
+/* { dg-do compile { target { struct_musttail && { c || c++11 } } } } */
 /* { dg-additional-options "-fdelayed-branch" { target sparc*-*-* } } */
 
 struct str
diff --git a/gcc/testsuite/c-c++-common/musttail2.c 
b/gcc/testsuite/c-c++-common/musttail2.c
index 86f2c3d77404..1970c4edd670 100644
--- a/gcc/testsuite/c-c++-common/musttail2.c
+++ b/gcc/testsuite/c-c++-common/musttail2.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+/* { dg-do compile { target { musttail && { c || c++11 } } } } */
 
 struct box { char field[256]; int i; };
 
diff --git a/gcc/testsuite/c-c++-common/musttail3.c 
b/gcc/testsuite/c-c++-common/musttail3.c
index ea9589c59ef2..7499fd6460b4 100644
--- a/gcc/testsuite/c-c++-common/musttail3.c
+++ b/gcc/testsuite/c-c++-common/musttail3.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+/* { dg-do compile { target { struct_musttail && { c || c++11 } } } } */
 
 extern int foo2 (int x, ...);
 
diff --git a/gcc/testsuite/c-c++-common/musttail4.c 
b/gcc/testsuite/c-c++-common/musttail4.c
index 23f4b5e1cd68..bd6effa4b931 100644
--- a/gcc/testsuite/c-c++-common/musttail4.c
+++ b/gcc/testsuite/c-c++-common/musttail4.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { tail_call && { c || c++11 } } } } */
+/* { dg-do compile { target { musttail && { c || c++11 } } } } */
 
 struct box { char field[64]; int i; };
 
diff --git a/gcc/testsuite/c-c++-common/musttail7.c 
b/gcc/testsuite/c-c++-common/musttail7.c
index c753a3fe9b2a..d17cb71256d7 100644
--- a/gcc/testsuite/c-c++-common/musttail7.c
+++ b/gcc/testsuite/c-c++-common

[PATCH] warn-access: ignore template parameters when matching operator new/delete [PR109224]

2024-08-02 Thread Arsen Arsenović
I'm not 100% clear on what the semantics of the matching here are meant
to be - AFAICT, an operator new/delete pair matches (after falling
through the other cases) if all their components (besides the actual
operator name, of course) match, and the pair of actual operator names
matches if one is a singleton new and the other a singleton delete, or,
similarly, if one is an array new and the other an array delete.  We
also appear to ignore their argument types (or so it seems by
experimentation - I was not able to quite discern what path those take).

Stripping operator template arguments from either side of the pair
should have no impact on this logic, I think.

Tested on x86_64-pc-linux-gnu, no regressions.

OK for trunk?

TIA, have a lovely evening.
-- >8 --
Template parameters on a member operator new cannot affect its member
status nor whether it is a singleton or array operator new, hence, we
can ignore it for purposes of matching.  Similar logic applies to the
placement operator delete.

In the PR (and a lot of idiomatic coroutine code generally), operator
new is templated in order to be able to inspect (some of) the arguments
passed to the coroutine, to make allocation-related decisions.  However,
the coroutine implementation will not call a placement delete form, so
it cannot get templated.  As a result, when demangling, we have an extra
template DEMANGLE_COMPONENT_TEMPLATE around the actual operator new, but
not operator delete.  This terminates new_delete_mismatch_p early.

PR middle-end/109224 - Wmismatched-new-delete false positive with a templated 
operator new (common with coroutines)

gcc/ChangeLog:

PR middle-end/109224
* gimple-ssa-warn-access.cc (new_delete_mismatch_p): Strip
DEMANGLE_COMPONENT_TEMPLATE from the operator new and operator
after demangling.

gcc/testsuite/ChangeLog:

PR middle-end/109224
* g++.dg/warn/Wmismatched-new-delete-9.C: New test.
---
 gcc/gimple-ssa-warn-access.cc | 18 ++-
 .../g++.dg/warn/Wmismatched-new-delete-9.C| 47 +++
 gcc/testsuite/g++.dg/warn/pr109224.C  | 25 ++
 3 files changed, 89 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/Wmismatched-new-delete-9.C
 create mode 100644 gcc/testsuite/g++.dg/warn/pr109224.C

diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index 61f9f0f3d310..e3fec5fb8e77 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -1762,7 +1762,23 @@ new_delete_mismatch_p (tree new_decl, tree delete_decl)
   void *np = NULL, *dp = NULL;
   demangle_component *ndc = cplus_demangle_v3_components (new_str, 0, &np);
   demangle_component *ddc = cplus_demangle_v3_components (del_str, 0, &dp);
-  bool mismatch = ndc && ddc && new_delete_mismatch_p (*ndc, *ddc);
+
+  /* Sometimes, notably quite often with coroutines, 'operator new' is
+ templated.  However, template arguments can't change whether a given
+ new/delete is a singleton or array one, nor what it is a member of, so
+ the template arguments can be safely ignored for the purposes of checking
+ for mismatches.   */
+
+  auto strip_dc_template = [] (demangle_component* dc)
+  {
+if (dc->type == DEMANGLE_COMPONENT_TEMPLATE)
+  dc = dc->u.s_binary.left;
+return dc;
+  };
+
+  bool mismatch = ndc && ddc
+&& new_delete_mismatch_p (*strip_dc_template (ndc),
+ *strip_dc_template (ddc));
   free (np);
   free (dp);
   return mismatch;
diff --git a/gcc/testsuite/g++.dg/warn/Wmismatched-new-delete-9.C 
b/gcc/testsuite/g++.dg/warn/Wmismatched-new-delete-9.C
new file mode 100644
index ..fa511bbfdb4b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wmismatched-new-delete-9.C
@@ -0,0 +1,47 @@
+/* { dg-do compile { target c++11 } } */
+/* { dg-additional-options "-Wmismatched-new-delete" } */
+/* PR middle-end/109224 */
+/* Verify that we consider templated operator new matching with its operator
+   delete.  */
+
+#include 
+
+struct foo
+{
+  template
+  void* operator new (std::size_t sz, Args&&...);
+  template
+  void* operator new[] (std::size_t sz, Args&&...);
+
+  void operator delete (void* x);
+  void operator delete[] (void* x);
+
+  template
+  void operator delete (void* x, Args&&...);
+  template
+  void operator delete[] (void* x, Args&&...);
+};
+
+void
+f ()
+{
+  delete (new (123, true) foo);
+  delete[] (new (123, true) foo[123]);
+
+  delete (new (123, true) foo[123]);
+  // { dg-warning "Wmismatched-new-delete" "" { target *-*-* } {.-1} }
+  // { dg-note "returned from" "" { target *-*-* } {.-2} }
+  delete[] (new (123, true) foo);
+  // { dg-warning "Wmismatched-new-delete" "" { target *-*-* } {.-1} }
+  // { dg-note "returned from" "" { target *-*-* } {.-2} }
+
+  foo::operator delete (new (123, true) foo, 123, true);
+  foo::operator delete[] (new (123, true) foo[123], 123, true);
+
+  foo::operator delete (new (123, 

Re: [PATCH] rs6000, document built-ins vec_test_lsbb_all_ones and, vec_test_lsbb_all_zeros

2024-08-02 Thread Peter Bergner
On 7/31/24 10:21 PM, Kewen.Lin wrote:
> on 2024/8/1 01:52, Carl Love wrote:
>> Yes, I noticed that the built-ins were defined as overloaded but only had 
>> one definition.   Did seem odd to me.
>>
>>> either is with "vector unsigned char" as argument type, but the 
>>> corresponding instance
>>> prototype in builtin table is with "vector signed char".  It's inconsistent 
>>> and weird,
>>> I think we can just update the prototype in builtin table with "vector 
>>> unsigned char"
>>> and remove the entries in overload table.  It can be a follow up patch.
>>
>> I didn't notice that it was signed in the instance prototype but unsigned in 
>> the overloaded definition.  That is definitely inconsistent.
>>
>> That said, should we just go ahead and support both signed and unsigned 
>> argument versions of the all ones and all zeros built-ins?
> 
> Good question, I thought about that but found openxl only supports the 
> unsigned version 
> so I felt it's probably better to keep consistent with it.  But I'm fine for 
> either, if
> we decide to extend it to cover both signed and unsigned, we should notify 
> openxl team
> to extend it as well.
> 
> openxl doc links:
> 
> https://www.ibm.com/docs/en/openxl-c-and-cpp-aix/17.1.2?topic=functions-vec-test-lsbb-all-ones
> https://www.ibm.com/docs/en/openxl-c-and-cpp-aix/17.1.2?topic=functions-vec-test-lsbb-all-zeros

If it makes sense to support vector signed char rather than only the vector 
unsigned char,
then I'm fine adding support for it.  It almost seems since we tried adding an 
overload
for it, that that was our intention (to support both signed and unsigned) and 
we just
had a bug so only unsigned was supported?

CC'ing Steve since he noticed the missing documentation when we was trying to
use the built-ins.  Steve, do you see a need to also support vector signed char
with these built-ins?

Peter




Re: [PATCH] libstdc++: Do not use deduced return type for std::forward_like

2024-08-02 Thread Patrick Palka
On Fri, 2 Aug 2024, Jonathan Wakely wrote:

> This isn't properly tested so I'm not pushing it, but I'm sharing it now
> for comment.
> 
> -- >8 --
> 
> Inspired by https://github.com/llvm/llvm-project/issues/101614 this
> replaces the deduced return type of std::forward_like with a type trait
> to compute that type.
> 
> libstdc++-v3/ChangeLog:
> 
>   * include/bits/move.h (__forward_like_impl): New metafunction to
>   compute the return type of std::forward_like.
>   (forward_like, __like_t): Use it.
>   * testsuite/20_util/forward_like/2_neg.cc: Adjust expected
>   errors.
> ---
>  libstdc++-v3/include/bits/move.h  | 45 +--
>  .../testsuite/20_util/forward_like/2_neg.cc   |  2 +-
>  2 files changed, 23 insertions(+), 24 deletions(-)
> 
> diff --git a/libstdc++-v3/include/bits/move.h 
> b/libstdc++-v3/include/bits/move.h
> index bb200c95964..15b7cd07fce 100644
> --- a/libstdc++-v3/include/bits/move.h
> +++ b/libstdc++-v3/include/bits/move.h
> @@ -88,31 +88,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  
>  #if __glibcxx_forward_like // C++ >= 23
>template
> -  [[nodiscard]]
> -  constexpr decltype(auto)
> -  forward_like(_Up&& __x) noexcept
> -  {
> -constexpr bool __as_rval = is_rvalue_reference_v<_Tp&&>;
> -
> -if constexpr (is_const_v>)
> -  {
> - using _Up2 = remove_reference_t<_Up>;
> - if constexpr (__as_rval)
> -   return static_cast(__x);
> - else
> -   return static_cast(__x);
> -  }
> -else
> -  {
> - if constexpr (__as_rval)
> -   return static_cast&&>(__x);
> - else
> -   return static_cast<_Up&>(__x);
> -  }
> -  }
> +struct __forward_like_impl
> +{
> +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_reference)
> +  template using __remove_ref_t = __remove_reference(_Xp);
> +#else
> +  template using __remove_ref_t = remove_reference_t<_Xp>;
> +#endif
> +  template
> + using _Copy_const = __conditional_t, const _Yp, _Yp>;
> +  template
> + using _Override_ref = __conditional_t,
> +   __remove_ref_t<_Yp>&&, _Yp&>;

Moving these nested alias templates out to namespace scope improves
compile time and memory usage of forward_like by about 25% (since nested
templates are more expensive to instantiate).

However, the following implementation using a single partially
specialized class template is a further 20% faster and uses around
15% less memory:

-- >8 --

Subject: [PATCH] libstdc++: use concrete return type for std::forward_like

Inspired by https://github.com/llvm/llvm-project/issues/101614 this
inverts the relationship between forward_like and __like_t, so that
forward_like is defined in terms of __like_t and with a concrete return
type.  __like_t in turn is defined via partial specializations that
performs case analysis on the const- and reference-ness of T.

This turns out to be more SFINAE friendly and significantly cheaper
to compile than the previous implementation.

libstdc++-v3/ChangeLog:

* include/bits/move.h (__like_impl): New metafunction.
(__like_t): Redefine in terms of __like_impl.
(forward_like): Redefine in terms of __like_t.
* testsuite/20_util/forward_like/2_neg.cc: Don't expect
error outside the immediate context anymore.
---
 libstdc++-v3/include/bits/move.h  | 46 +--
 .../testsuite/20_util/forward_like/2_neg.cc   |  6 +--
 2 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index bb200c95964..eaf4280d7ec 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -88,31 +88,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if __glibcxx_forward_like // C++ >= 23
   template
-  [[nodiscard]]
-  constexpr decltype(auto)
-  forward_like(_Up&& __x) noexcept
-  {
-constexpr bool __as_rval = is_rvalue_reference_v<_Tp&&>;
-
-if constexpr (is_const_v>)
-  {
-   using _Up2 = remove_reference_t<_Up>;
-   if constexpr (__as_rval)
- return static_cast(__x);
-   else
- return static_cast(__x);
-  }
-else
-  {
-   if constexpr (__as_rval)
- return static_cast&&>(__x);
-   else
- return static_cast<_Up&>(__x);
-  }
-  }
+  struct __like_impl; // _Tp must be a reference and _Up an lvalue reference
+
+  template
+  struct __like_impl<_Tp&, _Up&>
+  { using type = _Up&; };
+
+  template
+  struct __like_impl
+  { using type = const _Up&; };
+
+  template
+  struct __like_impl<_Tp&&, _Up&>
+  { using type = _Up&&; };
+
+  template
+  struct __like_impl
+  { using type = const _Up&&; };
 
   template
-using __like_t = decltype(std::forward_like<_Tp>(std::declval<_Up>()));
+using __like_t = __like_impl<_Tp&&, _Up&>;
+
+  template
+  constexpr __like_t<_Tp, _Up>
+  forward_like(_Up&& __x) noexcept
+  { return static_cast<__like_t<_Tp, _Up>>(__x); }
 #endif
 
   /**
diff

Re: [PATCH] libstdc++: Do not use deduced return type for std::forward_like

2024-08-02 Thread Patrick Palka
On Fri, 2 Aug 2024, Patrick Palka wrote:

> On Fri, 2 Aug 2024, Jonathan Wakely wrote:
> 
> > This isn't properly tested so I'm not pushing it, but I'm sharing it now
> > for comment.
> > 
> > -- >8 --
> > 
> > Inspired by https://github.com/llvm/llvm-project/issues/101614 this
> > replaces the deduced return type of std::forward_like with a type trait
> > to compute that type.
> > 
> > libstdc++-v3/ChangeLog:
> > 
> > * include/bits/move.h (__forward_like_impl): New metafunction to
> > compute the return type of std::forward_like.
> > (forward_like, __like_t): Use it.
> > * testsuite/20_util/forward_like/2_neg.cc: Adjust expected
> > errors.
> > ---
> >  libstdc++-v3/include/bits/move.h  | 45 +--
> >  .../testsuite/20_util/forward_like/2_neg.cc   |  2 +-
> >  2 files changed, 23 insertions(+), 24 deletions(-)
> > 
> > diff --git a/libstdc++-v3/include/bits/move.h 
> > b/libstdc++-v3/include/bits/move.h
> > index bb200c95964..15b7cd07fce 100644
> > --- a/libstdc++-v3/include/bits/move.h
> > +++ b/libstdc++-v3/include/bits/move.h
> > @@ -88,31 +88,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >  
> >  #if __glibcxx_forward_like // C++ >= 23
> >template
> > -  [[nodiscard]]
> > -  constexpr decltype(auto)
> > -  forward_like(_Up&& __x) noexcept
> > -  {
> > -constexpr bool __as_rval = is_rvalue_reference_v<_Tp&&>;
> > -
> > -if constexpr (is_const_v>)
> > -  {
> > -   using _Up2 = remove_reference_t<_Up>;
> > -   if constexpr (__as_rval)
> > - return static_cast(__x);
> > -   else
> > - return static_cast(__x);
> > -  }
> > -else
> > -  {
> > -   if constexpr (__as_rval)
> > - return static_cast&&>(__x);
> > -   else
> > - return static_cast<_Up&>(__x);
> > -  }
> > -  }
> > +struct __forward_like_impl
> > +{
> > +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_reference)
> > +  template using __remove_ref_t = 
> > __remove_reference(_Xp);
> > +#else
> > +  template using __remove_ref_t = 
> > remove_reference_t<_Xp>;
> > +#endif
> > +  template
> > +   using _Copy_const = __conditional_t, const _Yp, _Yp>;
> > +  template
> > +   using _Override_ref = __conditional_t,
> > + __remove_ref_t<_Yp>&&, _Yp&>;
> 
> Moving these nested alias templates out to namespace scope improves
> compile time and memory usage of forward_like by about 25% (since nested
> templates are more expensive to instantiate).
> 
> However, the following implementation using a single partially
> specialized class template is a further 20% faster and uses around
> 15% less memory:
> 
> -- >8 --
> 
> Subject: [PATCH] libstdc++: use concrete return type for std::forward_like
> 
> Inspired by https://github.com/llvm/llvm-project/issues/101614 this
> inverts the relationship between forward_like and __like_t, so that
> forward_like is defined in terms of __like_t and with a concrete return
> type.  __like_t in turn is defined via partial specializations that
> performs case analysis on the const- and reference-ness of T.
> 
> This turns out to be more SFINAE friendly and significantly cheaper
> to compile than the previous implementation.
> 
> libstdc++-v3/ChangeLog:
> 
>   * include/bits/move.h (__like_impl): New metafunction.
>   (__like_t): Redefine in terms of __like_impl.
>   (forward_like): Redefine in terms of __like_t.
>   * testsuite/20_util/forward_like/2_neg.cc: Don't expect
>   error outside the immediate context anymore.
> ---
>  libstdc++-v3/include/bits/move.h  | 46 +--
>  .../testsuite/20_util/forward_like/2_neg.cc   |  6 +--
>  2 files changed, 25 insertions(+), 27 deletions(-)
> 
> diff --git a/libstdc++-v3/include/bits/move.h 
> b/libstdc++-v3/include/bits/move.h
> index bb200c95964..eaf4280d7ec 100644
> --- a/libstdc++-v3/include/bits/move.h
> +++ b/libstdc++-v3/include/bits/move.h
> @@ -88,31 +88,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>  
>  #if __glibcxx_forward_like // C++ >= 23
>template
> -  [[nodiscard]]
> -  constexpr decltype(auto)
> -  forward_like(_Up&& __x) noexcept
> -  {
> -constexpr bool __as_rval = is_rvalue_reference_v<_Tp&&>;
> -
> -if constexpr (is_const_v>)
> -  {
> - using _Up2 = remove_reference_t<_Up>;
> - if constexpr (__as_rval)
> -   return static_cast(__x);
> - else
> -   return static_cast(__x);
> -  }
> -else
> -  {
> - if constexpr (__as_rval)
> -   return static_cast&&>(__x);
> - else
> -   return static_cast<_Up&>(__x);
> -  }
> -  }
> +  struct __like_impl; // _Tp must be a reference and _Up an lvalue reference
> +
> +  template
> +  struct __like_impl<_Tp&, _Up&>
> +  { using type = _Up&; };
> +
> +  template
> +  struct __like_impl
> +  { using type = const _Up&; };
> +
> +  template
> +  struct __like_impl<_Tp&&, _Up&>
> +  { using type = _Up&&; };
> +
> +  template
> +  struct __like_impl
> +  { using type = const _Up&&; };
>  
>  

Re: [PATCH v2] libstdc++: add default template parameters to algorithms

2024-08-02 Thread Giuseppe D'Angelo

Hello,

as usual thank you for the review. V2 is attached.

On 02/08/2024 14:38, Jonathan Wakely wrote:

On Fri, 2 Aug 2024 at 13:17, Jonathan Wakely  wrote:


On Fri, 2 Aug 2024 at 11:45, Giuseppe D'Angelo wrote:


Hello,

The attached patch adds support for P2248R8 + P3217R0 (Enabling
list-initialization for algorithms, C++26). The big question is whether
this keeps the code readable enough without introducing too much
#ifdef-ery, so any feedback is appreciated.


Putting the extra args on the algorithmfwd.h declarations is a nice
way to avoid any clutter on the definitions. I think that is very
readable.
Another option would be to not touch those forward declarations, but
add new ones with the defaults:

#if __glibcxx_default_template_type_for_algorithm_values
// new declarations with default template args ...
#endif

But I think what you've done is good.


I'll keep it then :)


For ranges_algo.h I'm almost tempted to say we should just treat this
as a DR, to avoid the #ifdef-ery. Almost.
Is there any reason we can't rearrange the template parameters fo
C++20 and C++23 mode? I don't think users are allowed to use explicit
template argument lists for invoke e.g. ranges::find.operator() so it should be unobservable if we change the order for C++20
(and just don't add the default args until C++26). That might reduce
the differences to just a line or two for each CPO.


Indeed, users cannot rely on any specific order of the template 
arguments when calling algorithms. This is


https://eel.is/c++draft/algorithms.requirements#15

which has this note:

"Consequently, an implementation can declare an algorithm with different 
template parameters than those presented"


which of course does apply here: it's why P2248 could do these changes 
to begin with. The only reason why I kept them in the original order was 
a matter of caution, but sure, in the new patch I've changed them 
unconditionally and just used a macro to hide the default in pre-C++26 
modes. This should keep the code clean(er).




The merged wording also removes the redundant 'typename' from the
default arguments, but I think we might still need that for Clang
compat. I'm not sure when Clang fully implemented "down with
typename", but it was still causing issues some time last year.


I hope it's fine if I keep it.

Thanks,
--
Giuseppe D'Angelo

From 607c43341502b7f6e34a24e9f2ecbdaae504cf4e Mon Sep 17 00:00:00 2001
From: Giuseppe D'Angelo 
Date: Fri, 2 Aug 2024 00:23:04 +0200
Subject: [PATCH] libstdc++: add default template parameters to algorithms

This implements P2248R8 + P3217R0, both approved for C++26.
The changes are mostly mechanical; the struggle is to keep readability
with the pre-P2248 signatures.

* For containers, "classic STL" algorithms and their parallel versions,
  introduce a macro and amend their declarations/definitions with it.
  The macro either expands to the defaulted parameter or to nothing
  in pre-C++26 modes.

* For range algorithms, we need to reorder their template parameters.
  I've done so unconditionally, because users cannot rely on template
  parameters of algorithms (this is explicitly authorized by
  [algorithms.requirements]/15). The defaults are then hidden behind
  another macro.

libstdc++-v3/ChangeLog:

	* include/bits/iterator_concepts.h: Add projected_value_t.
	* include/bits/algorithmfwd.h: Add the default template
	parameter to the relevant forward declarations.
	* include/pstl/glue_algorithm_defs.h: Likewise.
	* include/bits/ranges_algo.h: Add the default template
	parameter to range-based algorithms.
	* include/bits/ranges_algobase.h: Likewise.
	* include/bits/ranges_util.h: Likewise.
* include/bits/stl_iterator_base_types.h: Add helper macro.
	* include/bits/version.def: Add the new feature-testing macro.
	* include/bits/version.h: Regenerate.
	* include/std/algorithm: Pull the feature-testing macro.
	* include/std/ranges: Likewise.
	* include/std/deque: Pull the feature-testing macro, add
	the default for std::erase.
	* include/std/forward_list: Likewise.
	* include/std/list: Likewise.
	* include/std/string: Likewise.
	* include/std/vector: Likewise.
	* testsuite/23_containers/default_template_value.cc: New test.
	* testsuite/25_algorithms/default_template_value.cc: New test.

Signed-off-by: Giuseppe D'Angelo 
---
 libstdc++-v3/include/bits/algorithmfwd.h  |  61 ---
 libstdc++-v3/include/bits/iterator_concepts.h |   7 +
 libstdc++-v3/include/bits/ranges_algo.h   | 154 +-
 libstdc++-v3/include/bits/ranges_algobase.h   |  16 +-
 libstdc++-v3/include/bits/ranges_base.h   |   9 +
 libstdc++-v3/include/bits/ranges_util.h   |  10 +-
 .../include/bits/stl_iterator_base_types.h|   7 +
 libstdc++-v3/include/bits/version.def |   8 +
 libstdc++-v3/include/bits/version.h   |  10 ++
 .../include/pstl/glue_algorithm_defs.h|  23 +--
 libstdc++-v3/include/std/algorithm|   1 +
 libstdc++-v3/include/std/deque|   4

Re: [PATCH] libstdc++: Do not use deduced return type for std::forward_like

2024-08-02 Thread Jonathan Wakely
On Fri, 2 Aug 2024 at 23:43, Patrick Palka  wrote:
>
> On Fri, 2 Aug 2024, Patrick Palka wrote:
>
> > On Fri, 2 Aug 2024, Jonathan Wakely wrote:
> >
> > > This isn't properly tested so I'm not pushing it, but I'm sharing it now
> > > for comment.
> > >
> > > -- >8 --
> > >
> > > Inspired by https://github.com/llvm/llvm-project/issues/101614 this
> > > replaces the deduced return type of std::forward_like with a type trait
> > > to compute that type.
> > >
> > > libstdc++-v3/ChangeLog:
> > >
> > > * include/bits/move.h (__forward_like_impl): New metafunction to
> > > compute the return type of std::forward_like.
> > > (forward_like, __like_t): Use it.
> > > * testsuite/20_util/forward_like/2_neg.cc: Adjust expected
> > > errors.
> > > ---
> > >  libstdc++-v3/include/bits/move.h  | 45 +--
> > >  .../testsuite/20_util/forward_like/2_neg.cc   |  2 +-
> > >  2 files changed, 23 insertions(+), 24 deletions(-)
> > >
> > > diff --git a/libstdc++-v3/include/bits/move.h 
> > > b/libstdc++-v3/include/bits/move.h
> > > index bb200c95964..15b7cd07fce 100644
> > > --- a/libstdc++-v3/include/bits/move.h
> > > +++ b/libstdc++-v3/include/bits/move.h
> > > @@ -88,31 +88,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> > >
> > >  #if __glibcxx_forward_like // C++ >= 23
> > >template
> > > -  [[nodiscard]]
> > > -  constexpr decltype(auto)
> > > -  forward_like(_Up&& __x) noexcept
> > > -  {
> > > -constexpr bool __as_rval = is_rvalue_reference_v<_Tp&&>;
> > > -
> > > -if constexpr (is_const_v>)
> > > -  {
> > > -   using _Up2 = remove_reference_t<_Up>;
> > > -   if constexpr (__as_rval)
> > > - return static_cast(__x);
> > > -   else
> > > - return static_cast(__x);
> > > -  }
> > > -else
> > > -  {
> > > -   if constexpr (__as_rval)
> > > - return static_cast&&>(__x);
> > > -   else
> > > - return static_cast<_Up&>(__x);
> > > -  }
> > > -  }
> > > +struct __forward_like_impl
> > > +{
> > > +#if _GLIBCXX_USE_BUILTIN_TRAIT(__remove_reference)
> > > +  template using __remove_ref_t = 
> > > __remove_reference(_Xp);
> > > +#else
> > > +  template using __remove_ref_t = 
> > > remove_reference_t<_Xp>;
> > > +#endif
> > > +  template
> > > +   using _Copy_const = __conditional_t, const _Yp, _Yp>;
> > > +  template
> > > +   using _Override_ref = __conditional_t,
> > > + __remove_ref_t<_Yp>&&, _Yp&>;
> >
> > Moving these nested alias templates out to namespace scope improves
> > compile time and memory usage of forward_like by about 25% (since nested
> > templates are more expensive to instantiate).
> >
> > However, the following implementation using a single partially
> > specialized class template is a further 20% faster and uses around
> > 15% less memory:
> >
> > -- >8 --
> >
> > Subject: [PATCH] libstdc++: use concrete return type for std::forward_like
> >
> > Inspired by https://github.com/llvm/llvm-project/issues/101614 this
> > inverts the relationship between forward_like and __like_t, so that
> > forward_like is defined in terms of __like_t and with a concrete return
> > type.  __like_t in turn is defined via partial specializations that
> > performs case analysis on the const- and reference-ness of T.
> >
> > This turns out to be more SFINAE friendly and significantly cheaper
> > to compile than the previous implementation.
> >
> > libstdc++-v3/ChangeLog:
> >
> >   * include/bits/move.h (__like_impl): New metafunction.
> >   (__like_t): Redefine in terms of __like_impl.
> >   (forward_like): Redefine in terms of __like_t.
> >   * testsuite/20_util/forward_like/2_neg.cc: Don't expect
> >   error outside the immediate context anymore.
> > ---
> >  libstdc++-v3/include/bits/move.h  | 46 +--
> >  .../testsuite/20_util/forward_like/2_neg.cc   |  6 +--
> >  2 files changed, 25 insertions(+), 27 deletions(-)
> >
> > diff --git a/libstdc++-v3/include/bits/move.h 
> > b/libstdc++-v3/include/bits/move.h
> > index bb200c95964..eaf4280d7ec 100644
> > --- a/libstdc++-v3/include/bits/move.h
> > +++ b/libstdc++-v3/include/bits/move.h
> > @@ -88,31 +88,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
> >
> >  #if __glibcxx_forward_like // C++ >= 23
> >template
> > -  [[nodiscard]]
> > -  constexpr decltype(auto)
> > -  forward_like(_Up&& __x) noexcept
> > -  {
> > -constexpr bool __as_rval = is_rvalue_reference_v<_Tp&&>;
> > -
> > -if constexpr (is_const_v>)
> > -  {
> > - using _Up2 = remove_reference_t<_Up>;
> > - if constexpr (__as_rval)
> > -   return static_cast(__x);
> > - else
> > -   return static_cast(__x);
> > -  }
> > -else
> > -  {
> > - if constexpr (__as_rval)
> > -   return static_cast&&>(__x);
> > - else
> > -   return static_cast<_Up&>(__x);
> > -  }
> > -  }
> > +  struct __like_impl; // _Tp must be a reference and _Up an lvalue 
> > reference
> > +
> > +  templat

Re: [PATCH v2] libstdc++: add default template parameters to algorithms

2024-08-02 Thread Jonathan Wakely
On Fri, 2 Aug 2024 at 23:49, Giuseppe D'Angelo
 wrote:
>
> Hello,
>
> as usual thank you for the review. V2 is attached.
>
> On 02/08/2024 14:38, Jonathan Wakely wrote:
> > On Fri, 2 Aug 2024 at 13:17, Jonathan Wakely  wrote:
> >>
> >> On Fri, 2 Aug 2024 at 11:45, Giuseppe D'Angelo wrote:
> >>>
> >>> Hello,
> >>>
> >>> The attached patch adds support for P2248R8 + P3217R0 (Enabling
> >>> list-initialization for algorithms, C++26). The big question is whether
> >>> this keeps the code readable enough without introducing too much
> >>> #ifdef-ery, so any feedback is appreciated.
> >>
> >> Putting the extra args on the algorithmfwd.h declarations is a nice
> >> way to avoid any clutter on the definitions. I think that is very
> >> readable.
> >> Another option would be to not touch those forward declarations, but
> >> add new ones with the defaults:
> >>
> >> #if __glibcxx_default_template_type_for_algorithm_values
> >> // new declarations with default template args ...
> >> #endif
> >>
> >> But I think what you've done is good.
>
> I'll keep it then :)
>
> >> For ranges_algo.h I'm almost tempted to say we should just treat this
> >> as a DR, to avoid the #ifdef-ery. Almost.
> >> Is there any reason we can't rearrange the template parameters fo
> >> C++20 and C++23 mode? I don't think users are allowed to use explicit
> >> template argument lists for invoke e.g. ranges::find.operator() >> Proj> so it should be unobservable if we change the order for C++20
> >> (and just don't add the default args until C++26). That might reduce
> >> the differences to just a line or two for each CPO.
>
> Indeed, users cannot rely on any specific order of the template
> arguments when calling algorithms. This is
>
> https://eel.is/c++draft/algorithms.requirements#15
>
> which has this note:
>
> "Consequently, an implementation can declare an algorithm with different
> template parameters than those presented"
>
> which of course does apply here: it's why P2248 could do these changes
> to begin with. The only reason why I kept them in the original order was
> a matter of caution, but sure, in the new patch I've changed them
> unconditionally and just used a macro to hide the default in pre-C++26
> modes. This should keep the code clean(er).
>
>
> > The merged wording also removes the redundant 'typename' from the
> > default arguments, but I think we might still need that for Clang
> > compat. I'm not sure when Clang fully implemented "down with
> > typename", but it was still causing issues some time last year.
>
> I hope it's fine if I keep it.

Yes, certainly.

This looks good to me now, thanks.

Reviewed-by: Jonathan Wakely 

Patrick, could you please review + test this some time next week? If
it's all fine and you're happy with it too, please push to trunk.



  1   2   >