Re: [PATCH] target/100312 - make x86 masked load builtins pure

2021-04-29 Thread Richard Biener
On Wed, 28 Apr 2021, Uros Bizjak wrote:

> On Wed, Apr 28, 2021 at 3:32 PM Richard Biener  wrote:
> >
> > On Wed, 28 Apr 2021, Uros Bizjak wrote:
> >
> > > On Wed, Apr 28, 2021 at 1:46 PM Richard Biener  wrote:
> > > >
> > > > On Wed, 28 Apr 2021, Uros Bizjak wrote:
> > > >
> > > > > On Wed, Apr 28, 2021 at 1:02 PM Richard Biener  
> > > > > wrote:
> > > > > >
> > > > > > This arranges for the x86 AVX and AVX2 masked load builtins to be
> > > > > > pure to enable dead code elimination and more appropriate alias
> > > > > > analysis.
> > > > > >
> > > > > > Bootstrapped and tested on x86_64-unknown-linux-gnu.  OK for trunk?
> > > > > >
> > > > > > Thanks,
> > > > > > Richard.
> > > > > >
> > > > > > 2021-04-28  Richard Biener  
> > > > > >
> > > > > > PR target/100312
> > > > > > * config/i386/i386-builtin.def (IX86_BUILTIN_MASKLOADPD,
> > > > > > IX86_BUILTIN_MASKLOADPS, IX86_BUILTIN_MASKLOADPD256,
> > > > > > IX86_BUILTIN_MASKLOADPS256, IX86_BUILTIN_MASKLOADD,
> > > > > > IX86_BUILTIN_MASKLOADQ, IX86_BUILTIN_MASKLOADD256,
> > > > > > IX86_BUILTIN_MASKLOADQ256): Remove.
> > > > > > * config/i386/i386-builtins.h (ix86_builtins): Add entries 
> > > > > > for
> > > > > > IX86_BUILTIN_MASKLOADPD, IX86_BUILTIN_MASKLOADPS,
> > > > > > IX86_BUILTIN_MASKLOADPD256, IX86_BUILTIN_MASKLOADPS256,
> > > > > > IX86_BUILTIN_MASKLOADD, IX86_BUILTIN_MASKLOADQ,
> > > > > > IX86_BUILTIN_MASKLOADD256, and IX86_BUILTIN_MASKLOADQ256.
> > > > > > * config/i386/i386-builtins.c (ix86_init_mmx_sse_builtins):
> > > > > > Initialize IX86_BUILTIN_MASKLOADPD, IX86_BUILTIN_MASKLOADPS,
> > > > > > IX86_BUILTIN_MASKLOADPD256, IX86_BUILTIN_MASKLOADPS256,
> > > > > > IX86_BUILTIN_MASKLOADD, IX86_BUILTIN_MASKLOADQ,
> > > > > > IX86_BUILTIN_MASKLOADD256, and IX86_BUILTIN_MASKLOADQ256
> > > > > > as pure builtins.
> > > > >
> > > > > OK.
> > > >
> > > > Whoops - somehow I posted the wrong version.  The version posted
> > > > ICEs because I failed to realize I'd have to explicitely handle
> > > > those builtins in ix86_expand_builtin.  What bootstrapped and
> > > > tested OK is the version below.
> > > >
> > > > Is that version also OK?
> > >
> > > Hm, your previous version removed mentioned builtins from builtins.def
> > > and initialized them in ix86_init_mmx_sse_builtins by hand (this seems
> > > to be the preferred way). This should work, so I really don't see why
> > > the previous approach would result in ICE.
> >
> > It eventually runs into the gcc_unreachable () at the very end of
> > ix86_expand_builtin since IX86_BUILTIN_MASKLOADD and friends are
> > no longer in the range of IX86_BUILTIN__BDESC_SPECIAL_ARGS_FIRST
> > to IX86_BUILTIN__BDESC_SPECIAL_ARGS_LAST.
> 
> How about the attached (untested) patch then?

Ah yeah - good idea.

The patch works, bootstrapped and tested on x86_64-unknown-linux-gnu.

As expected it reduces the number of masked load builtins for the
PR99912 testcase from ~800 to ~350 (at the GIMPLE level).

Thanks,
Richard.


[Ada] Spurious error on 'Image

2021-04-29 Thread Pierre-Marie de Rodat
As part of recent improvements related to discriminant checks, a
regression was introduced in complex cases of generics and use of 'Image
on an expression partially rewritten as a [raise Constraint_Error] node.

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

gcc/ada/

* sem_attr.adb (Check_Image_Type): Protect against empty
Image_Type.diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -1466,7 +1466,11 @@ package body Sem_Attr is
 
  procedure Check_Image_Type (Image_Type : Entity_Id) is
  begin
+--  Image_Type may be empty in case of another error detected,
+--  or if an N_Raise_xxx_Error node is a parent of N.
+
 if Ada_Version < Ada_2020
+  and then Present (Image_Type)
   and then not Is_Scalar_Type (Image_Type)
 then
Error_Msg_Ada_2020_Feature ("nonscalar ''Image", Sloc (P));




[Ada] Warning for 'Class applied to untagged incomplete type

2021-04-29 Thread Pierre-Marie de Rodat
Applying Class to an untagged incomplete type is legal, but classified
as obsolescent in Annex J (for Ada 2005 and later), so should be flagged
with a warning when the -gnatwj switch applies, as well as being
reported as a violation of No_Obsolescent_Features when that restriction
is enabled.  Both of these warnings are made effective by this change.

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

gcc/ada/

* sem_ch8.adb (Find_Type): Check the No_Obsolescent_Features
restriction for 'Class applied to an untagged incomplete
type (when Ada_Version >= Ada_2005).  Remove disabling of the
warning message for such usage, along with the ??? comment,
which no longer applies (because the -gnatg switch no longer
sets Warn_On_Obsolescent_Feature).diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -7893,16 +7893,18 @@ package body Sem_Ch8 is
 Set_Entity (N, Any_Type);
 return;
 
- --  ??? This test is temporarily disabled (always
- --  False) because it causes an unwanted warning on
- --  GNAT sources (built with -gnatg, which includes
- --  Warn_On_Obsolescent_ Feature). Once this issue
- --  is cleared in the sources, it can be enabled.
+ else
+if Restriction_Check_Required (No_Obsolescent_Features)
+then
+   Check_Restriction
+ (No_Obsolescent_Features, Prefix (N));
+end if;
 
- elsif Warn_On_Obsolescent_Feature and then False then
-Error_Msg_N
-  ("applying ''Class to an untagged incomplete type"
-   & " is an obsolescent feature (RM J.11)?r?", N);
+if Warn_On_Obsolescent_Feature then
+   Error_Msg_N
+ ("applying ''Class to an untagged incomplete type"
+  & " is an obsolescent feature (RM J.11)?r?", N);
+end if;
  end if;
   end if;
 




[Ada] AI12-0407: Fixups on Big_Integers and Big_Reals

2021-04-29 Thread Pierre-Marie de Rodat
This AI updates among other things some declarations in big number
packages.

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

gcc/ada/

* libgnat/a-nbnbin.ads (From_Universal_Image): New.
(Big_Integer): Update definition.
* libgnat/a-nbnbre.ads, libgnat/a-nbnbre.adb
(From_Universal_Image): New.
(From_String): Remove alternate body, replaced by
From_Universal_Image.
(Big_Real): Update definition.diff --git a/gcc/ada/libgnat/a-nbnbin.ads b/gcc/ada/libgnat/a-nbnbin.ads
--- a/gcc/ada/libgnat/a-nbnbin.ads
+++ b/gcc/ada/libgnat/a-nbnbin.ads
@@ -22,7 +22,7 @@ package Ada.Numerics.Big_Numbers.Big_Integers
   with Preelaborate
 is
type Big_Integer is private
- with Integer_Literal => From_String,
+ with Integer_Literal => From_Universal_Image,
   Put_Image   => Put_Image;
 
function Is_Valid (Arg : Big_Integer) return Boolean
@@ -116,6 +116,9 @@ is
function From_String (Arg : String) return Valid_Big_Integer
  with Global => null;
 
+   function From_Universal_Image (Arg : String) return Valid_Big_Integer
+ renames From_String;
+
procedure Put_Image (S : in out Sink'Class; V : Big_Integer);
 
function "+" (L : Valid_Big_Integer) return Valid_Big_Integer


diff --git a/gcc/ada/libgnat/a-nbnbre.adb b/gcc/ada/libgnat/a-nbnbre.adb
--- a/gcc/ada/libgnat/a-nbnbre.adb
+++ b/gcc/ada/libgnat/a-nbnbre.adb
@@ -593,13 +593,6 @@ package body Ada.Numerics.Big_Numbers.Big_Reals is
   end;
end From_String;
 
-   function From_String
- (Numerator, Denominator : String) return Valid_Big_Real is
-   begin
-  return Big_Integers.From_String (Numerator) /
-Big_Integers.From_String (Denominator);
-   end From_String;
-
--
-- From_Quotient_String --
--


diff --git a/gcc/ada/libgnat/a-nbnbre.ads b/gcc/ada/libgnat/a-nbnbre.ads
--- a/gcc/ada/libgnat/a-nbnbre.ads
+++ b/gcc/ada/libgnat/a-nbnbre.ads
@@ -21,7 +21,7 @@ package Ada.Numerics.Big_Numbers.Big_Reals
   with Preelaborate
 is
type Big_Real is private with
- Real_Literal => From_String,
+ Real_Literal => From_Universal_Image,
  Put_Image=> Put_Image;
 
function Is_Valid (Arg : Big_Real) return Boolean
@@ -122,8 +122,13 @@ is
 
function From_String (Arg : String) return Valid_Big_Real
  with Global => null;
-   function From_String (Numerator, Denominator : String) return Valid_Big_Real
- with Global => null;
+
+   function From_Universal_Image (Arg : String) return Valid_Big_Real
+ renames From_String;
+   function From_Universal_Image (Num, Den : String) return Valid_Big_Real is
+ (Big_Integers.From_Universal_Image (Num) /
+  Big_Integers.From_Universal_Image (Den))
+  with Global => null;
 
function To_Quotient_String (Arg : Big_Real) return String is
  (Big_Integers.To_String (Numerator (Arg)) & " / "




[Ada] Fixes in the use of spans for error locations

2021-04-29 Thread Pierre-Marie de Rodat
Various fixes regarding the use of spans in error messages when using
debug flag -gnatdF.

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

gcc/ada/

* errout.adb (Error_Msg_NEL): Extract span from node.
(First_And_Last_Nodes): Use spans for subtype indications and
attribute definition clauses.
(Write_Source_Code_Lines): Fix for tabulation characters. Change
output for large spans to skip intermediate lines.
* sem_case.adb (Check_Choice_Set): Report duplicate choice on
the Original_Node for the case.
(Generic_Check_Choices): Set the Original_Node for the rewritten
case, so that the subtree used in spans has the correct
locations.diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -1430,8 +1430,14 @@ package body Errout is
   E : Node_Or_Entity_Id;
   Flag_Location : Source_Ptr)
is
+  Fst, Lst : Node_Id;
begin
-  Error_Msg_NEL (Msg, N, E, To_Span (Flag_Location));
+  First_And_Last_Nodes (N, Fst, Lst);
+  Error_Msg_NEL
+(Msg, N, E,
+ To_Span (Ptr   => Flag_Location,
+  First => Source_Ptr'Min (Flag_Location, First_Sloc (Fst)),
+  Last  => Source_Ptr'Max (Flag_Location, Last_Sloc (Lst;
end Error_Msg_NEL;
 
procedure Error_Msg_NEL
@@ -1757,7 +1763,7 @@ package body Errout is
and then Get_Source_File_Index (Loc) = Sfile
  then
 Latest := Norig;
-Lloc := Loc;
+Lloc   := Loc;
  end if;
 
  return OK_Orig;
@@ -1782,6 +1788,8 @@ package body Errout is
| N_Pragma
| N_Use_Type_Clause
| N_With_Clause
+   | N_Attribute_Definition_Clause
+   | N_Subtype_Indication
   then
  Earliest := Orig;
  Eloc := Loc;
@@ -2284,11 +2292,35 @@ package body Errout is
 
   procedure Write_Source_Code_Lines (Span : Source_Span) is
 
+ function Get_Line_End
+   (Buf : Source_Buffer_Ptr;
+Loc : Source_Ptr) return Source_Ptr;
+ --  Get the source location for the end of the line in Buf for Loc
+
+ function Get_Line_Start
+   (Buf : Source_Buffer_Ptr;
+Loc : Source_Ptr) return Source_Ptr;
+ --  Get the source location for the start of the line in Buf for Loc
+
  function Image (X : Positive; Width : Positive) return String;
  --  Output number X over Width characters, with whitespace padding.
  --  Only output the low-order Width digits of X, if X is larger than
  --  Width digits.
 
+ procedure Write_Buffer
+   (Buf   : Source_Buffer_Ptr;
+First : Source_Ptr;
+Last  : Source_Ptr);
+ --  Output the characters from First to Last position in Buf, using
+ --  Write_Buffer_Char.
+
+ procedure Write_Buffer_Char
+   (Buf : Source_Buffer_Ptr;
+Loc : Source_Ptr);
+ --  Output the characters at position Loc in Buf, translating ASCII.HT
+ --  in a suitable number of spaces so that the output is not modified
+ --  by starting in a different column that 1.
+
  procedure Write_Line_Marker
(Num   : Pos;
 Mark  : Boolean;
@@ -2297,6 +2329,44 @@ package body Errout is
  --  a Mark to denote the line with the main location when reporting
  --  a span over multiple lines.
 
+ --
+ -- Get_Line_End --
+ --
+
+ function Get_Line_End
+   (Buf : Source_Buffer_Ptr;
+Loc : Source_Ptr) return Source_Ptr
+ is
+Cur_Loc : Source_Ptr := Loc;
+ begin
+while Cur_Loc <= Buf'Last
+  and then Buf (Cur_Loc) /= ASCII.LF
+loop
+   Cur_Loc := Cur_Loc + 1;
+end loop;
+
+return Cur_Loc;
+ end Get_Line_End;
+
+ 
+ -- Get_Line_Start --
+ 
+
+ function Get_Line_Start
+   (Buf : Source_Buffer_Ptr;
+Loc : Source_Ptr) return Source_Ptr
+ is
+Cur_Loc : Source_Ptr := Loc;
+ begin
+while Cur_Loc > Buf'First
+  and then Buf (Cur_Loc - 1) /= ASCII.LF
+loop
+   Cur_Loc := Cur_Loc - 1;
+end loop;
+
+return Cur_Loc;
+ end Get_Line_Start;
+
  ---
  -- Image --
  ---
@@ -2317,6 +2387,50 @@ package body Errout is
 return Str;
  end Image;
 
+ --
+ -- Write_Buffer --
+ --
+
+ procedure Write_Buffer
+   (Buf   : Source_Buffer_Ptr;
+First : Source_Ptr;
+Last  : So

[Ada] Reimplement Pred and Succ atttributes for floating-point types

2021-04-29 Thread Pierre-Marie de Rodat
The main reason is that the current implementation does not work if the
type does not support denormalized numbers, because it is piggybacked
on the Scaling attribute and Scaling will flush to zero in this case.

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

gcc/ada/

* libgnat/s-fatgen.adb: Remove with clause for Interfaces and
use type clauses for Interfaces.Unsigned_{16,32,64}.
(Small16): Remove.
(Small32): Likewise
(Small64): Likewise.
(Small80): Likewise.
(Tiny16): Likewise.
(Tiny32): Likewise.
(Tiny64): Likewise.
(Tiny80): Likewise.
(Siz): Always use 16.
(NR): New constant.
(Rep_Last): Use it in the computation.
(Exp_Factor): Remove special case for 80-bit.
(Sign_Mask): Likewise.
(Finite_Succ): New function implementing the Succ attribute for
finite numbers.
(Pred): Rewrite in terms of Finite_Succ.
(Succ): Likewise.diff --git a/gcc/ada/libgnat/s-fatgen.adb b/gcc/ada/libgnat/s-fatgen.adb
--- a/gcc/ada/libgnat/s-fatgen.adb
+++ b/gcc/ada/libgnat/s-fatgen.adb
@@ -35,17 +35,12 @@
 --  floating-point implementations.
 
 with Ada.Unchecked_Conversion;
-with Interfaces;
 with System.Unsigned_Types;
 
 pragma Warnings (Off, "non-static constant in preelaborated unit");
 --  Every constant is static given our instantiation model
 
 package body System.Fat_Gen is
-   use type Interfaces.Unsigned_16;
-   use type Interfaces.Unsigned_32;
-   use type Interfaces.Unsigned_64;
-
pragma Assert (T'Machine_Radix = 2);
--  This version does not handle radix 16
 
@@ -61,33 +56,9 @@ package body System.Fat_Gen is
--  Small : constant T := Rad ** (T'Machine_Emin - 1);
--  Smallest positive normalized number
 
-   Small16 : constant Interfaces.Unsigned_16 := 2**(Mantissa - 1);
-   Small32 : constant Interfaces.Unsigned_32 := 2**(Mantissa - 1);
-   Small64 : constant Interfaces.Unsigned_64 := 2**(Mantissa - 1);
-   Small80 : constant array (1 .. 2) of Interfaces.Unsigned_64 :=
-   (2**48 * (1 - Standard'Default_Bit_Order),
-1 * Standard'Default_Bit_Order);
-   for Small80'Alignment use Standard'Maximum_Alignment;
-   --  We cannot use the direct declaration because it cannot be translated
-   --  into C90, as the hexadecimal floating constants were introduced in C99.
-   --  So we work around this by using an overlay of the integer constant.
-   --  ??? Revisit this when the new CCG technoloy is in production
-
--  Tiny : constant T := Rad ** (T'Machine_Emin - Mantissa);
--  Smallest positive denormalized number
 
-   Tiny16 : constant Interfaces.Unsigned_16 := 1;
-   Tiny32 : constant Interfaces.Unsigned_32 := 1;
-   Tiny64 : constant Interfaces.Unsigned_64 := 1;
-   Tiny80 : constant array (1 .. 2) of Interfaces.Unsigned_64 :=
-  (1 * Standard'Default_Bit_Order,
-   2**48 * (1 - Standard'Default_Bit_Order));
-   for Tiny80'Alignment use Standard'Maximum_Alignment;
-   --  We cannot use the direct declaration because it cannot be translated
-   --  into C90, as the hexadecimal floating constants were introduced in C99.
-   --  So we work around this by using an overlay of the integer constant.
-   --  ??? Revisit this when the new CCG technoloy is in production
-
RM1 : constant T := Rad ** (Mantissa - 1);
--  Smallest positive member of the large consecutive integers. It is equal
--  to the ratio Small / Tiny, which means that multiplying by it normalizes
@@ -125,22 +96,23 @@ package body System.Fat_Gen is
--  component of Float_Rep, named Most Significant Word (MSW).
 
--- The sign occupies the most significant bit of the MSW and the
-   --  exponent is in the following bits. The exception is 80-bit
-   --  double extended, where they occupy the low 16-bit halfword.
-
-   --  The low-level primitives Copy_Sign, Decompose, Scaling and Valid are
-   --  implemented by accessing the bit pattern of the floating-point number.
-   --  Only the normalization of denormalized numbers, if any, and the gradual
-   --  underflow are left to the hardware, mainly because there is some leeway
-   --  for the hardware implementation in this area: for example, the MSB of
-   --  the mantissa, which is 1 for normalized numbers and 0 for denormalized
+   --  exponent is in the following bits.
+
+   --  The low-level primitives Copy_Sign, Decompose, Finite_Succ, Scaling and
+   --  Valid are implemented by accessing the bit pattern of the floating-point
+   --  number. Only the normalization of denormalized numbers, if any, and the
+   --  gradual underflow are left to the hardware, mainly because there is some
+   --  leeway for the hardware implementation in this area: for example the MSB
+   --  of the mantissa, that is 1 for normalized numbers and 0 for denormalized
--  numbers, may or may not be stored by the hardware.
 
-   Siz : constant := (if System.Word_Size > 

[PATCH] middle-end/38474 - speedup PTA constraint solving

2021-04-29 Thread Richard Biener
In testcases like PR38474 and PR99912 we're seeing very slow
PTA solving.  One can observe an excessive amount of forwarding,
mostly during sd constraint solving.  The way we solve the graph
does not avoid forwarding the same bits through multiple paths,
and especially when such alternate path involves ESCAPED as
intermediate this causes the ESCAPED solution to be expanded
in receivers.

The following adds heuristic to add_graph_edge which adds
forwarding edges but also guards the initial solution forwarding
(which is the expensive part) to detect the case of ESCAPED
receiving the same set and the destination already containing
ESCAPED.

This speeds up the PTA solving process by more than 50%.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed to trunk.

2021-04-29  Richard Biener  

PR middle-end/38474
* tree-ssa-structalias.c (add_graph_edge): Avoid direct
forwarding when indirect forwarding through ESCAPED
alread happens.
---
 gcc/tree-ssa-structalias.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 529ec3a5b80..a0238710e72 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -1195,6 +1195,22 @@ add_graph_edge (constraint_graph_t graph, unsigned int 
to,
 
   if (!graph->succs[from])
graph->succs[from] = BITMAP_ALLOC (&pta_obstack);
+
+  /* The graph solving process does not avoid "triangles", thus
+there can be multiple paths from a node to another involving
+intermediate other nodes.  That causes extra copying which is
+most difficult to avoid when the intermediate node is ESCAPED
+because there are no edges added from ESCAPED.  Avoid
+adding the direct edge FROM -> TO when we have FROM -> ESCAPED
+and TO contains ESCAPED.
+???  Note this is only a heuristic, it does not prevent the
+situation from occuring.  The heuristic helps PR38474 and
+PR99912 significantly.  */
+  if (to < FIRST_REF_NODE
+ && bitmap_bit_p (graph->succs[from], find (escaped_id))
+ && bitmap_bit_p (get_varinfo (find (to))->solution, escaped_id))
+   return false;
+
   if (bitmap_set_bit (graph->succs[from], to))
{
  r = true;
-- 
2.26.2


[Ada] Extend Find_Related_Context to deal with child instances

2021-04-29 Thread Pierre-Marie de Rodat
Aspect Part_Of is first translated into a corresponding pragma; then, we
use Find_Related_Context to recover the node where the aspect was
originally attached.

However, this routine was only working for pragmas Part_Of coming from
aspects applied to generic packages instantiated within other program
units; it was returning Empty for generic package instantiated as
standalone compilation units, e.g.:

   with Generic_Pkg;
   private package Parent.Child_Instance is new Generic_Pkg
 with Part_Of => State;

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

gcc/ada/

* sem_elab.adb (Process_SPARK_Instantiation): Fix typo in
comment.
* sem_prag.adb (Find_Related_Context): Add missing reference to
No_Caching in the comment; handle pragmas on compilation units.diff --git a/gcc/ada/sem_elab.adb b/gcc/ada/sem_elab.adb
--- a/gcc/ada/sem_elab.adb
+++ b/gcc/ada/sem_elab.adb
@@ -15121,7 +15121,7 @@ package body Sem_Elab is
  Inst_Rep : Scenario_Rep_Id;
  In_State : Processing_In_State);
   pragma Inline (Process_SPARK_Instantiation);
-  --  Verify that instanciation Inst does not precede the generic body it
+  --  Verify that instantiation Inst does not precede the generic body it
   --  instantiates (SPARK RM 7.7(6)). Inst_Rep is the representation of the
   --  instantiation. In_State is the current state of the Processing phase.
 


diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -243,6 +243,7 @@ package body Sem_Prag is
--Constant_After_Elaboration
--Effective_Reads
--Effective_Writers
+   --No_Caching
--Part_Of
--  Find the first source declaration or statement found while traversing
--  the previous node chain starting from pragma Prag. If flag Do_Checks is
@@ -30474,6 +30475,16 @@ package body Sem_Prag is
   Stmt : Node_Id;
 
begin
+  --  If the pragma comes from an aspect on a compilation unit that is a
+  --  package instance, then return the original package instantiation
+  --  node.
+
+  if Nkind (Parent (Prag)) = N_Compilation_Unit_Aux then
+ return
+   Get_Unit_Instantiation_Node
+ (Defining_Entity (Unit (Enclosing_Comp_Unit_Node (Prag;
+  end if;
+
   Stmt := Prev (Prag);
   while Present (Stmt) loop
 




[Ada] Crash on predicated constrained out_parameter

2021-04-29 Thread Pierre-Marie de Rodat
Compiler aborts on an aggregate for a discriminated out_parameter when
the parent type has dynamic_predicates.

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

gcc/ada/

* sem_util.adb (Build_Constrained_Itype): Inhibit the generation
of predicate functions for this Itype, which is created for an
aggregate of a discriminated type. The object to which the
aggregate is assigned, e.g a writable actual parameter, will
apply the predicates if any are inherited from the base type.diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -2380,6 +2380,14 @@ package body Sem_Util is
 
   Analyze (Subtyp_Decl, Suppress => All_Checks);
 
+  --  In addition, inhibit the generation of predicate functions for
+  --  this subtype, because its declaration is not in a declarative
+  --  list, and no predicates apply to the aggregate itself, but only
+  --  to the object to which it may be assigned.
+
+  Set_Has_Dynamic_Predicate_Aspect (Def_Id, False);
+  Set_Has_Predicates (Def_Id, False);
+
   Set_Etype (N, Def_Id);
end Build_Constrained_Itype;
 




[Ada] Fix static computation of 'Succ for floating point without denormals

2021-04-29 Thread Pierre-Marie de Rodat
The implementation computes an incorrect increment for normalized numbers
with the smallest exponent when the floating-point type does not support
denormalized numbers.

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

gcc/ada/

* eval_fat.adb (Succ): Add a special case for zero if the type does
not support denormalized numbers.  Always use the canonical formula
in other cases and add commentary throughout the function.diff --git a/gcc/ada/eval_fat.adb b/gcc/ada/eval_fat.adb
--- a/gcc/ada/eval_fat.adb
+++ b/gcc/ada/eval_fat.adb
@@ -729,22 +729,30 @@ package body Eval_Fat is
   New_Frac : T;
 
begin
+  --  Treat zero as a regular denormalized number if they are supported,
+  --  otherwise return the smallest normalized number.
+
   if UR_Is_Zero (X) then
- Exp := Emin;
+ if Has_Denormals (RT) then
+Exp := Emin;
+ else
+return Scaling (RT, Ureal_1, Emin - 1);
+ end if;
   end if;
 
-  --  Set exponent such that the radix point will be directly following the
-  --  mantissa after scaling.
-
-  if Has_Denormals (RT) or Exp /= Emin then
- Exp := Exp - Mantissa;
-  else
- Exp := Exp - 1;
-  end if;
+  --  Multiply the number by 2.0**(Mantissa-Exp) so that the radix point
+  --  will be directly following the mantissa after scaling.
 
+  Exp := Exp - Mantissa;
   Frac := Scaling (RT, X, -Exp);
+
+  --  Round to the neareast integer towards +Inf
+
   New_Frac := Ceiling (RT, Frac);
 
+  --  If the rounding was a NOP, add one, except for -2.0**(Mantissa-1)
+  --  because the exponent is going to be reduced.
+
   if New_Frac = Frac then
  if New_Frac = Scaling (RT, -Ureal_1, Mantissa - 1) then
 New_Frac := New_Frac + Scaling (RT, Ureal_1, Uint_Minus_1);
@@ -753,6 +761,8 @@ package body Eval_Fat is
  end if;
   end if;
 
+  --  Divide back by 2.0**(Mantissa-Exp) to get the final result
+
   return Scaling (RT, New_Frac, Exp);
end Succ;
 




[Ada] Fix handling of visibility when categorization from pragmas

2021-04-29 Thread Pierre-Marie de Rodat
Routine Set_Categorization_From_Pragmas processes pragmas listed after
the compilation unit. It requires enclosing scopes to be visible, to
support pragmas (and aspects that are translated to pragmas) like here:

   with Generic_Pkg;
   private package Parent.Child_Instance is new Generic_Pkg
 with Part_Of => Parent.State;
 
  --  "Parent" need to be visible when processing the pragma

However, detection of the special case with generic child unit of a
generic parent, where the enclosing scopes need to be made visible, was
imprecise.  For simplicity, this special case is now removed, because
detecting it seemed expensive and complicated.

Also, the visibility is now properly restored to its previous value and
not just blindly left as False.

Finally, the explicit check for an empty list of pragmas is removed; it
was only meant as an optimization, but it didn't seem essential. The
routine is now much simpler and hopefully more robust.

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

gcc/ada/

* sem_cat.adb (Set_Categorization_From_Pragmas): Remove special
case for generic child units; remove optimization for empty list
of pragmas; properly restore visibility.diff --git a/gcc/ada/sem_cat.adb b/gcc/ada/sem_cat.adb
--- a/gcc/ada/sem_cat.adb
+++ b/gcc/ada/sem_cat.adb
@@ -691,56 +691,25 @@ package body Sem_Cat is
-
 
procedure Set_Categorization_From_Pragmas (N : Node_Id) is
-  P   : constant Node_Id := Parent (N);
-  S   : constant Entity_Id := Current_Scope;
+  P : constant Node_Id := Parent (N);
 
-  procedure Set_Parents (Visibility : Boolean);
- --  If this is a child instance, the parents are not immediately
- --  visible during analysis. Make them momentarily visible so that
- --  the argument of the pragma can be resolved properly, and reset
- --  afterwards.
+  procedure Make_Parents_Visible_And_Process_Pragmas (Par : Entity_Id);
+  --  Parents might not be immediately visible during analysis. Make
+  --  them momentarily visible so that the argument of the pragma can
+  --  be resolved properly, process pragmas and restore the previous
+  --  visibility.
 
-  -
-  -- Set_Parents --
-  -
+  procedure Process_Categorization_Pragmas;
+  --  Process categorization pragmas, if any
 
-  procedure Set_Parents (Visibility : Boolean) is
- Par : Entity_Id;
-  begin
- Par := Scope (S);
- while Present (Par) and then Par /= Standard_Standard loop
-Set_Is_Immediately_Visible (Par, Visibility);
-Par := Scope (Par);
- end loop;
-  end Set_Parents;
-
-   --  Start of processing for Set_Categorization_From_Pragmas
-
-   begin
-  --  Deal with categorization pragmas in Pragmas of Compilation_Unit.
-  --  The purpose is to set categorization flags before analyzing the
-  --  unit itself, so as to diagnose violations of categorization as
-  --  we process each declaration, even though the pragma appears after
-  --  the unit. This processing is only needed if compilation unit pragmas
-  --  are present.
-  --  Note: This code may be incorrect in the unlikely case a child generic
-  --  unit is instantiated as a child of its (nongeneric) parent, so that
-  --  generic and instance are siblings.
-
-  if Nkind (P) /= N_Compilation_Unit
- or else No (First (Pragmas_After (Aux_Decls_Node (P
-  then
- return;
-  end if;
+  
+  -- Process_Categorization_Pragmas --
+  
 
-  declare
+  procedure Process_Categorization_Pragmas is
  PN : Node_Id;
 
   begin
- if Is_Child_Unit (S) and then Is_Generic_Instance (S) then
-Set_Parents (True);
- end if;
-
  PN := First (Pragmas_After (Aux_Decls_Node (P)));
  while Present (PN) loop
 
@@ -765,11 +734,49 @@ package body Sem_Cat is
 
 Next (PN);
  end loop;
+  end Process_Categorization_Pragmas;
+
+  --
+  -- Make_Parents_Visible_And_Process_Pragmas --
+  --
+
+  procedure Make_Parents_Visible_And_Process_Pragmas (Par : Entity_Id) is
+  begin
+ --  When we reached the Standard scope, then just process pragmas
+
+ if Par = Standard_Standard then
+Process_Categorization_Pragmas;
 
- if Is_Child_Unit (S) and then Is_Generic_Instance (S) then
-Set_Parents (False);
+ --  Otherwise make the current scope momentarily visible, recurse
+ --  into its enclosing scope, and restore the visibility. This is
+ --  required for child units that are instances of generic parents.
+
+ else
+  

[Ada] Makefile.rtl:ADA_EXCLUDE_SRCS update after some System.GCC unit renames

2021-04-29 Thread Pierre-Marie de Rodat
In a previous commit, some System.GCC units were renamed to be children
of System.GCC.DI instead, so as to have System.GCC be free of symbols
which are specific to 32bit platforms. This was needed in the context
of a 64bit vx7r2cert platform (AArch64) where we needed to add
equivalent routines specific to 64bit platforms ("ti" functions
instead of "di" ones, added under System.GCC.TI). Unfortunately,
that previous commit forgot to update references to these files
in Makefile.rtl.

Luckily, Makefile.rtl only has visibility over runtime files in libgnat
and libgnarl, so references to files in hie can be completely removed,
thus simplifying things and avoiding the problem entirely.

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

gcc/ada/

* Makefile.rtl (ADA_EXCLUDE_SRCS): Remove s-gcc.adb, s-gcc.ads,
s-gccdiv.adb, s-gccdiv.ads, s-gccshi.adb and s-gccshi.ads.diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -2992,8 +2992,6 @@ ADA_EXCLUDE_SRCS =\
   s-bbsle3.ads s-bbsuer.ads s-bbsule.ads s-bbthqu.adb s-bbthqu.ads \
   s-bbthre.adb s-bbthre.ads s-bbtiev.adb s-bbtiev.ads s-bbtime.adb \
   s-bbtime.ads s-bcprmu.adb s-bcprmu.ads s-btstch.adb s-btstch.ads \
-  s-gcc.adbs-gcc.adss-gccdiv.adb s-gccdiv.ads \
-  s-gccshi.adb s-gccshi.ads \
   s-init.ads   s-init.adb   s-linux.ads  s-macres.ads \
   s-memcom.adb s-memcom.ads s-memmov.adb s-memmov.ads s-memset.adb \
   s-memset.ads s-mufalo.adb s-mufalo.ads s-musplo.adb s-musplo.ads \




[Ada] SPARK needs DIC expressions within partial DIC procedures for abstract types

2021-04-29 Thread Pierre-Marie de Rodat
A recent change done as part of the implementation of AI12-0397 was to
suppress generation of DIC check expressions within DIC procedures
associated with abstract types (to avoid producing calls to abstract
subprograms, which are legal to give in a DIC aspect, but would cause
problems for gigi if they resulted in actual calls). However, SPARK
still needs access to the resolved expression of the DIC aspect, which
normally occurs within the partial DIC procedure of the type. This is
fixed by adding a test of GNATprove_Mode to avoid suppressing the
DIC check pragma when running SPARK tools.

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

gcc/ada/

* exp_util.adb (Add_Own_DIC): Relax the suppression of adding a
DIC Check pragma that's done for abstract types by still doing
it in the case where GNATprove_Mode is set.diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -1860,7 +1860,7 @@ package body Exp_Util is
  --  procedures can never be called in any case, so not generating the
  --  check at all is OK).
 
- if not Is_Abstract_Type (DIC_Typ) then
+ if not Is_Abstract_Type (DIC_Typ) or else GNATprove_Mode then
 Add_DIC_Check
   (DIC_Prag => DIC_Prag,
DIC_Expr => Expr,




[Ada] Couple of minor tweaks to Eval_Fat.Succ

2021-04-29 Thread Pierre-Marie de Rodat
This saves a few cycles by using Ureal_Half instead of Ureal_1.

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

gcc/ada/

* eval_fat.adb (Succ): Use Ureal_Half in a couple of places.diff --git a/gcc/ada/eval_fat.adb b/gcc/ada/eval_fat.adb
--- a/gcc/ada/eval_fat.adb
+++ b/gcc/ada/eval_fat.adb
@@ -736,7 +736,7 @@ package body Eval_Fat is
  if Has_Denormals (RT) then
 Exp := Emin;
  else
-return Scaling (RT, Ureal_1, Emin - 1);
+return Scaling (RT, Ureal_Half, Emin);
  end if;
   end if;
 
@@ -755,7 +755,7 @@ package body Eval_Fat is
 
   if New_Frac = Frac then
  if New_Frac = Scaling (RT, -Ureal_1, Mantissa - 1) then
-New_Frac := New_Frac + Scaling (RT, Ureal_1, Uint_Minus_1);
+New_Frac := New_Frac + Ureal_Half;
  else
 New_Frac := New_Frac + Ureal_1;
  end if;




[Ada] Ada 2020 AI12-0401: Renaming of qualified expression of variable

2021-04-29 Thread Pierre-Marie de Rodat
A new version of this AI was published recently, refining the legality
rules around renaming of a qualified expression.

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

gcc/ada/

* sem_ch8.adb (Analyze_Object_Renaming): Update check for
AI12-0401.diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -759,6 +759,7 @@ package body Sem_Ch8 is
   Dec   : Node_Id;
   T : Entity_Id;
   T2: Entity_Id;
+  Q : Node_Id;
 
   procedure Check_Constrained_Object;
   --  If the nominal type is unconstrained but the renamed object is
@@ -1074,17 +1075,55 @@ package body Sem_Ch8 is
  --  Check against AI12-0401 here before Resolve may rewrite Nam and
  --  potentially generate spurious warnings.
 
+ --   In the case where the object_name is a qualified_expression with
+ --   a nominal subtype T and whose expression is a name that denotes
+ --   an object Q:
+ --* if T is an elementary subtype, then:
+ --  * Q shall be a constant other than a dereference of an access
+ --type; or
+ --  * the nominal subtype of Q shall be statically compatible with
+ --T; or
+ --  * T shall statically match the base subtype of its type if
+ --scalar, or the first subtype of its type if an access type.
+ --* if T is a composite subtype, then Q shall be known to be
+ --  constrained or T shall statically match the first subtype of
+ --  its type.
+
  if Nkind (Nam) = N_Qualified_Expression
-   and then Is_Variable (Expression (Nam))
-   and then not
- (Subtypes_Statically_Match (T, Etype (Expression (Nam)))
-or else
-  Subtypes_Statically_Match (Base_Type (T), Etype (Nam)))
+   and then Is_Object_Reference (Expression (Nam))
  then
-Error_Msg_N
-  ("subtype of renamed qualified expression does not " &
-   "statically match", N);
-return;
+Q := Expression (Nam);
+
+if (Is_Elementary_Type (T)
+  and then
+not ((not Is_Variable (Q)
+   and then Nkind (Q) /= N_Explicit_Dereference)
+  or else Subtypes_Statically_Compatible (Etype (Q), T)
+  or else (Is_Scalar_Type (T)
+and then Subtypes_Statically_Match
+   (T, Base_Type (T)))
+  or else (Is_Access_Type (T)
+and then Subtypes_Statically_Match
+   (T, First_Subtype (T)
+  or else (Is_Composite_Type (T)
+ and then
+
+   --  If Q is an aggregate, Is_Constrained may not be set
+   --  yet and its type may not be resolved yet.
+   --  This doesn't quite correspond to the complex notion
+   --  of "known to be constrained" but this is good enough
+   --  for a rule which is in any case too complex.
+
+   not (Is_Constrained (Etype (Q))
+ or else Nkind (Q) = N_Aggregate
+ or else Subtypes_Statically_Match
+   (T, First_Subtype (T
+then
+   Error_Msg_N
+ ("subtype of renamed qualified expression does not " &
+  "statically match", N);
+   return;
+end if;
  end if;
 
  Resolve (Nam, T);




[Ada] Bad handling of array sliding in aggregate

2021-04-29 Thread Pierre-Marie de Rodat
In the case of an aggregate containing controlled array components,
if sliding of the indexes is involved, the components are prematurely
finalized without a corresponding initialization.

Also fix a latent bug in Exp_Aggr.Collect_Initialization_Statements
which was not always inserting Initialization_Statements properly when
the Node_After was empty (in the case of e.g. a single object
declaration).  This is needed in order to take advantage of
Initialization_Statements in Expand_N_Object_Declaration: we scan
Initialization_Statements and if a call to xxxSA is found, it means we
need to initialize the corresponding array component before it gets
prematurely adjusted.

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

gcc/ada/

* exp_aggr.adb (Collect_Initialization_Statements): Removed.
(Convert_Aggr_In_Object_Decl, Expand_Array_Aggregate): Fix
creation and insertion of Initialization_Statements.  Do not set
Initialization_Statements when a transient scope is involved.
Move processing of Array_Slice here.  Ensure that an object with
an Array_Slice call gets its array component initialized.  Add
comments.
* exp_ch7.adb: Update comments.
(Store_Actions_In_Scope): Deal properly with an empty list which
might now be generated by Convert_Aggr_In_Object_Decl.
* exp_ch3.adb: Update comments.
(Expand_N_Object_Declaration): Remove processing of Array_Slice.diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -78,15 +78,6 @@ package body Exp_Aggr is
type Case_Table_Type is array (Nat range <>) of Case_Bounds;
--  Table type used by Check_Case_Choices procedure
 
-   procedure Collect_Initialization_Statements
- (Obj: Entity_Id;
-  N  : Node_Id;
-  Node_After : Node_Id);
-   --  If Obj is not frozen, collect actions inserted after N until, but not
-   --  including, Node_After, for initialization of Obj, and move them to an
-   --  expression with actions, which becomes the Initialization_Statements for
-   --  Obj.
-
procedure Expand_Delta_Array_Aggregate  (N : Node_Id; Deltas : List_Id);
procedure Expand_Delta_Record_Aggregate (N : Node_Id; Deltas : List_Id);
procedure Expand_Container_Aggregate (N : Node_Id);
@@ -4210,40 +4201,6 @@ package body Exp_Aggr is
   return L;
end Build_Record_Aggr_Code;
 
-   ---
-   -- Collect_Initialization_Statements --
-   ---
-
-   procedure Collect_Initialization_Statements
- (Obj: Entity_Id;
-  N  : Node_Id;
-  Node_After : Node_Id)
-   is
-  Loc  : constant Source_Ptr := Sloc (N);
-  Init_Actions : constant List_Id:= New_List;
-  Init_Node: Node_Id;
-  Comp_Stmt: Node_Id;
-
-   begin
-  --  Nothing to do if Obj is already frozen, as in this case we known we
-  --  won't need to move the initialization statements about later on.
-
-  if Is_Frozen (Obj) then
- return;
-  end if;
-
-  Init_Node := N;
-  while Next (Init_Node) /= Node_After loop
- Append_To (Init_Actions, Remove_Next (Init_Node));
-  end loop;
-
-  if not Is_Empty_List (Init_Actions) then
- Comp_Stmt := Make_Compound_Statement (Loc, Actions => Init_Actions);
- Insert_Action_After (Init_Node, Comp_Stmt);
- Set_Initialization_Statements (Obj, Comp_Stmt);
-  end if;
-   end Collect_Initialization_Statements;
-
---
-- Convert_Aggr_In_Allocator --
---
@@ -4314,6 +4271,8 @@ package body Exp_Aggr is
   Typ  : constant Entity_Id  := Etype (Aggr);
   Occ  : constant Node_Id:= New_Occurrence_Of (Obj, Loc);
 
+  Has_Transient_Scope : Boolean := False;
+
   function Discriminants_Ok return Boolean;
   --  If the object type is constrained, the discriminants in the
   --  aggregate must be checked against the discriminants of the subtype.
@@ -4405,7 +4364,7 @@ package body Exp_Aggr is
   --  the finalization list of the return must be moved to the caller's
   --  finalization list to complete the return.
 
-  --  However, if the aggregate is limited, it is built in place, and the
+  --  Similarly if the aggregate is limited, it is built in place, and the
   --  controlled components are not assigned to intermediate temporaries
   --  so there is no need for a transient scope in this case either.
 
@@ -4414,13 +4373,60 @@ package body Exp_Aggr is
 and then not Is_Limited_Type (Typ)
   then
  Establish_Transient_Scope (Aggr, Manage_Sec_Stack => False);
+ Has_Transient_Scope := True;
   end if;
 
   declare
- Node_After : constant Node_Id := Next (N);
+ Stmts : constant List_Id := Late_Expansion (Aggr, Typ, Occ);
+ Stmt  : Node_Id;
+

[Ada] Fix internal consistency error with Duration and 32-bit target file

2021-04-29 Thread Pierre-Marie de Rodat
The Duration type of package Standard can be either a 32-bit or a 64-bit
fixed-point type depending on a flag in the system.ads file, but it needs
to be 32-bit when a target configuration file sets a 32-bit size for all
the predefined integer types.

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

gcc/ada/

* gnat1drv.adb (Adjust_Global_Switches): Force a 32-bit Duration
type if the maximum integer size is lower than 64 bits.diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb
--- a/gcc/ada/gnat1drv.adb
+++ b/gcc/ada/gnat1drv.adb
@@ -819,6 +819,12 @@ procedure Gnat1drv is
Ttypes.Standard_Long_Long_Integer_Size;
   end if;
 
+  --  Forcefully use a 32-bit Duration with only 32-bit integer types
+
+  if Ttypes.System_Max_Integer_Size < 64 then
+ Targparm.Duration_32_Bits_On_Target := True;
+  end if;
+
   --  Finally capture adjusted value of Suppress_Options as the initial
   --  value for Scope_Suppress, which will be modified as we move from
   --  scope to scope (by Suppress/Unsuppress/Overflow_Checks pragmas).




[Ada] Fix evaluation of expressions in inlined code

2021-04-29 Thread Pierre-Marie de Rodat
In GNATprove mode, inlining is used to make it easier to perform proof
without forcing the user to annotate all local subprograms with
contracts.  But the compiled code will not be similarly inlined, thus
the analysis should not assume that the compiler will have access to the
same extended precision for compile-time computations as is available on
inlined code.  The same is true for frontend inlining in the compiler
(only used with -gnatN or -gnatd.z), as Ada semantics requires in such a
case that run-time checks are still performed. For these reasons,
inlined expressions should always be checked for possible overflows.

Also add the missing compile-time checks for non-static unary
expressions and exponentiation of signed integer type (as unary minus,
absolute value and exponentiation can all lead to an overflow).

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

gcc/ada/

* sem_eval.adb (Check_Non_Static_Context_For_Overflow): Apply
compile-time checking for overflows in non-static contexts
including inlined code.
(Eval_Arithmetic_Op): Use the new procedure.
(Eval_Unary_Op, Eval_Op_Expon): Add call to the new procedure.diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -142,6 +142,16 @@ package body Sem_Eval is
-- Local Subprograms --
---
 
+   procedure Check_Non_Static_Context_For_Overflow
+ (N  : Node_Id;
+  Stat   : Boolean;
+  Result : Uint);
+   --  For a signed integer type, check non-static overflow in Result when
+   --  Stat is False. This applies also inside inlined code, where the static
+   --  property may be an effect of the inlining, which should not be allowed
+   --  to remove run-time checks (whether during compilation, or even more
+   --  crucially in the special inlining-for-proof in GNATprove mode).
+
function Choice_Matches
  (Expr   : Node_Id;
   Choice : Node_Id) return Match_Result;
@@ -649,6 +659,34 @@ package body Sem_Eval is
   end if;
end Check_Non_Static_Context;
 
+   ---
+   -- Check_Non_Static_Context_For_Overflow --
+   ---
+
+   procedure Check_Non_Static_Context_For_Overflow
+ (N  : Node_Id;
+  Stat   : Boolean;
+  Result : Uint)
+   is
+   begin
+  if (not Stat or else In_Inlined_Body)
+and then Is_Signed_Integer_Type (Etype (N))
+  then
+ declare
+BT : constant Entity_Id := Base_Type (Etype (N));
+Lo : constant Uint := Expr_Value (Type_Low_Bound (BT));
+Hi : constant Uint := Expr_Value (Type_High_Bound (BT));
+ begin
+if Result < Lo or else Result > Hi then
+   Apply_Compile_Time_Constraint_Error
+ (N, "value not in range of }??",
+  CE_Overflow_Check_Failed,
+  Ent => BT);
+end if;
+ end;
+  end if;
+   end Check_Non_Static_Context_For_Overflow;
+
-
-- Check_String_Literal_Length --
-
@@ -2143,25 +2181,10 @@ package body Sem_Eval is
 
 if Is_Modular_Integer_Type (Ltype) then
Result := Result mod Modulus (Ltype);
-
-   --  For a signed integer type, check non-static overflow
-
-elsif (not Stat) and then Is_Signed_Integer_Type (Ltype) then
-   declare
-  BT : constant Entity_Id := Base_Type (Ltype);
-  Lo : constant Uint := Expr_Value (Type_Low_Bound (BT));
-  Hi : constant Uint := Expr_Value (Type_High_Bound (BT));
-   begin
-  if Result < Lo or else Result > Hi then
- Apply_Compile_Time_Constraint_Error
-   (N, "value not in range of }??",
-CE_Overflow_Check_Failed,
-Ent => BT);
- return;
-  end if;
-   end;
 end if;
 
+Check_Non_Static_Context_For_Overflow (N, Stat, Result);
+
 --  If we get here we can fold the result
 
 Fold_Uint (N, Result, Stat);
@@ -3202,6 +3225,8 @@ package body Sem_Eval is
  Result := Result mod Modulus (Etype (N));
   end if;
 
+  Check_Non_Static_Context_For_Overflow (N, Stat, Result);
+
   Fold_Uint (N, Result, Stat);
end if;
 end;
@@ -4375,6 +4400,8 @@ package body Sem_Eval is
Result := abs Rint;
 end if;
 
+Check_Non_Static_Context_For_Overflow (N, Stat, Result);
+
 Fold_Uint (N, Result, Stat);
  end;
 




[Ada] Missing access-to-discriminated conversion check

2021-04-29 Thread Pierre-Marie de Rodat
The compiler was failing to generate a required constraint check in the
case of a type conversion between access-to-discriminated types. This
patch fixes this bug.

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

gcc/ada/

* checks.adb (Apply_Type_Conversion_Checks): Move out constraint
check generation, and add case for general access types with
constraints.
(Make_Discriminant_Constraint_Check): Created to centralize
generation of constraint checks for stored discriminants.diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -3575,6 +3575,102 @@ package body Checks is
   --  full view might have discriminants with defaults, so we need the
   --  full view here to retrieve the constraints.
 
+  procedure Make_Discriminant_Constraint_Check
+(Target_Type : Entity_Id;
+ Expr_Type   : Entity_Id);
+  --  Generate a discriminant check based on the target type and expression
+  --  type for Expr.
+
+  
+  -- Make_Discriminant_Constraint_Check --
+  
+
+  procedure Make_Discriminant_Constraint_Check
+(Target_Type : Entity_Id;
+ Expr_Type   : Entity_Id)
+  is
+ Loc : constant Source_Ptr := Sloc (N);
+ Cond: Node_Id;
+ Constraint  : Elmt_Id;
+ Discr_Value : Node_Id;
+ Discr   : Entity_Id;
+
+ New_Constraints : constant Elist_Id := New_Elmt_List;
+ Old_Constraints : constant Elist_Id :=
+   Discriminant_Constraint (Expr_Type);
+
+  begin
+ --  Build an actual discriminant constraint list using the stored
+ --  constraint, to verify that the expression of the parent type
+ --  satisfies the constraints imposed by the (unconstrained) derived
+ --  type. This applies to value conversions, not to view conversions
+ --  of tagged types.
+
+ Constraint := First_Elmt (Stored_Constraint (Target_Type));
+ while Present (Constraint) loop
+Discr_Value := Node (Constraint);
+
+if Is_Entity_Name (Discr_Value)
+  and then Ekind (Entity (Discr_Value)) = E_Discriminant
+then
+   Discr := Corresponding_Discriminant (Entity (Discr_Value));
+
+   if Present (Discr)
+ and then Scope (Discr) = Base_Type (Expr_Type)
+   then
+  --  Parent is constrained by new discriminant. Obtain
+  --  Value of original discriminant in expression. If the
+  --  new discriminant has been used to constrain more than
+  --  one of the stored discriminants, this will provide the
+  --  required consistency check.
+
+  Append_Elmt
+(Make_Selected_Component (Loc,
+   Prefix=>
+ Duplicate_Subexpr_No_Checks
+   (Expr, Name_Req => True),
+   Selector_Name =>
+ Make_Identifier (Loc, Chars (Discr))),
+ New_Constraints);
+
+   else
+  --  Discriminant of more remote ancestor ???
+
+  return;
+   end if;
+
+--  Derived type definition has an explicit value for this
+--  stored discriminant.
+
+else
+   Append_Elmt
+ (Duplicate_Subexpr_No_Checks (Discr_Value),
+  New_Constraints);
+end if;
+
+Next_Elmt (Constraint);
+ end loop;
+
+ --  Use the unconstrained expression type to retrieve the
+ --  discriminants of the parent, and apply momentarily the
+ --  discriminant constraint synthesized above.
+
+ --  Note: We use Expr_Type instead of Target_Type since the number of
+ --  actual discriminants may be different due to the presence of
+ --  stored discriminants and cause Build_Discriminant_Checks to fail.
+
+ Set_Discriminant_Constraint (Expr_Type, New_Constraints);
+ Cond := Build_Discriminant_Checks (Expr, Expr_Type);
+ Set_Discriminant_Constraint (Expr_Type, Old_Constraints);
+
+ Insert_Action (N,
+   Make_Raise_Constraint_Error (Loc,
+ Condition => Cond,
+ Reason=> CE_Discriminant_Check_Failed));
+  end Make_Discriminant_Constraint_Check;
+
+   --  Start of processing for Apply_Type_Conversion_Checks
+
begin
   if Inside_A_Generic then
  return;
@@ -3704,91 +3800,42 @@ package body Checks is
 end if;
  end;
 
-  elsif Comes_From_Source (N)
-and then not Discriminant_Checks_Suppressed (Target_Type)
-and then Is_Record_Type (Target_Type)
-and then Is_Derived_Type (Target_Type)
-

[Ada] Fix minor issue in Scan_Decimal_Digits

2021-04-29 Thread Pierre-Marie de Rodat
The Extra digit is not correctly set when the precision limit is reached
by means of trailing zeros.

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

gcc/ada/

* libgnat/s-valuer.adb (Scan_Decimal_Digits): Set Extra to zero
when the precision limit is reached by means of trailing zeros
and prevent it from being overwritten later.diff --git a/gcc/ada/libgnat/s-valuer.adb b/gcc/ada/libgnat/s-valuer.adb
--- a/gcc/ada/libgnat/s-valuer.adb
+++ b/gcc/ada/libgnat/s-valuer.adb
@@ -261,7 +261,11 @@ package body System.Value_R is
  Scale := Scale - 1;
 
   else
+ Extra := 0;
  Precision_Limit_Reached := True;
+ if Round and then J = Trailing_Zeros then
+Round_Extra (Digit, Value, Scale, Extra, Base);
+ end if;
  exit;
   end if;
end loop;
@@ -274,11 +278,16 @@ package body System.Value_R is
 
Temp := Value * Uns (Base) + Uns (Digit);
 
+   --  Precision_Limit_Reached may have been set above
+
+   if Precision_Limit_Reached then
+  null;
+
--  Check if Temp is larger than Precision_Limit, taking into
--  account that Temp may wrap around when Precision_Limit is
--  equal to the largest integer.
 
-   if Value <= Umax
+   elsif Value <= Umax
  or else (Value <= UmaxB
and then ((Precision_Limit < Uns'Last
and then Temp <= Precision_Limit)




[Ada] Add colors to GNATprove messages output to a terminal

2021-04-29 Thread Pierre-Marie de Rodat
Add the possibility for a tool to enable colored output using SGR when
outputting to a terminal. This is currently used only in GNATprove, but
could be enabled for compiler messages in the future. Use the same colors
(including bold) as gcc/g++ as much as possible.

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

gcc/ada/

* errout.adb (Output_Messages): Insert SGR strings where needed.
* erroutc.adb (Output_Message_Txt): Insert SGR strings where
needed in the text of the message itself.
(Output_Msg_Text): Allow for style message not to start
with (style).
* erroutc.ads: Add new constants and functions to control colors
in messages output to the terminal. Add variable Use_SGR_Control
that should be set to True for using SGR color control strings.diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -2071,7 +2071,9 @@ package body Errout is
   procedure Write_Max_Errors;
   --  Write message if max errors reached
 
-  procedure Write_Source_Code_Lines (Span : Source_Span);
+  procedure Write_Source_Code_Lines
+(Span : Source_Span;
+ SGR_Span : String);
   --  Write the source code line corresponding to Span, as follows when
   --  Span in on one line:
   --
@@ -2095,6 +2097,9 @@ package body Errout is
   --   | ^ here
   --
   --  where the caret on the line points to location Span.Ptr
+  --
+  --  SGR_Span is the SGR string to start the section of code in the span,
+  --  that should be closed with SGR_Reset.
 
   -
   -- Write_Error_Summary --
@@ -2290,8 +2295,10 @@ package body Errout is
   -- Write_Source_Code_Lines --
   -
 
-  procedure Write_Source_Code_Lines (Span : Source_Span) is
-
+  procedure Write_Source_Code_Lines
+(Span : Source_Span;
+ SGR_Span : String)
+  is
  function Get_Line_End
(Buf : Source_Buffer_Ptr;
 Loc : Source_Ptr) return Source_Ptr;
@@ -2490,6 +2497,15 @@ package body Errout is
 --  the gap with first/last lines, otherwise use ... to denote
 --  intermediate lines.
 
+--  If the span is on one line and not a simple source location,
+--  color it appropriately.
+
+if Line_Fst = Line_Lst
+  and then Col_Fst /= Col_Lst
+then
+   Write_Str (SGR_Span);
+end if;
+
 declare
function Do_Write_Line (Cur_Line : Pos) return Boolean is
   (Cur_Line in Line_Fst | Line | Line_Lst
@@ -2499,7 +2515,7 @@ package body Errout is
(Cur_Line = Line + 1 and then Cur_Line = Line_Lst - 1));
 begin
while Cur_Loc <= Buf'Last
- and then Cur_Loc < Lst
+ and then Cur_Loc <= Lst
loop
   if Do_Write_Line (Cur_Line) then
  Write_Buffer_Char (Buf, Cur_Loc);
@@ -2535,6 +2551,12 @@ package body Errout is
end loop;
 end;
 
+if Line_Fst = Line_Lst
+  and then Col_Fst /= Col_Lst
+then
+   Write_Str (SGR_Reset);
+end if;
+
 --  Output the rest of the last line of the span
 
 Write_Buffer (Buf, Cur_Loc, Get_Line_End (Buf, Cur_Loc));
@@ -2546,6 +2568,9 @@ package body Errout is
Write_Str (String'(1 .. Width => ' '));
Write_Str (" |");
Write_Str (String'(1 .. Col_Fst - 1 => ' '));
+
+   Write_Str (SGR_Span);
+
Write_Str (String'(Col_Fst .. Col - 1 => '~'));
Write_Str ("^");
Write_Str (String'(Col + 1 .. Col_Lst => '~'));
@@ -2557,6 +2582,8 @@ package body Errout is
   Write_Str (" here");
end if;
 
+   Write_Str (SGR_Reset);
+
Write_Eol;
 end if;
  end if;
@@ -2615,6 +2642,8 @@ package body Errout is
end if;
 
if Use_Prefix then
+  Write_Str (SGR_Locus);
+
   if Full_Path_Name_For_Brief_Errors then
  Write_Name (Full_Ref_Name (Errors.Table (E).Sfile));
   else
@@ -2633,6 +2662,8 @@ package body Errout is
 
   Write_Int (Int (Errors.Table (E).Col));
   Write_Str (": ");
+
+  Write_Str (SGR_Reset);
end if;
 
Output_Msg_Text (E);
@@ -2652,12 +2683,23 @@ package body Errout is
   Errors.Table (E).Insertion_Sloc;
  begin
 if Loc /= No_Location then
-   Write_Source_Code_Lines (To_Span (Loc));
+   Write_Source_Code

[Ada] Error on T'Reduce of when T is not a container

2021-04-29 Thread Pierre-Marie de Rodat
This patch fixes a bug that caused the compiler to crash on T'Reduce, if
T is something like Integer.

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

gcc/ada/

* sem_attr.adb (Analyze_Attribute): Change "$" to "&".
Otherwise, Errout will trip over an uninitialized (invalid)
variable (Error_Msg_Unit_1).diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -5682,7 +5682,7 @@ package body Sem_Attr is
   null;
else
   Error_Msg_NE
-("cannot apply Reduce to object of type$", N, Typ);
+("cannot apply Reduce to object of type&", N, Typ);
end if;
 
 elsif Present (Expressions (Stream))




[Ada] Clean up Makefile.rtl

2021-04-29 Thread Pierre-Marie de Rodat
ADA_EXCLUDE_SRCS and ADA_INCLUDE_SRCS contain old references to non
existing files.

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

gcc/ada/

* Makefile.rtl (ADA_EXCLUDE_SRCS): Remove unused files.
(ADA_INCLUDE_SRCS): Remove libgnat/system.adsdiff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -2967,7 +2967,7 @@ GNATRTL_OBJS = $(GNATRTL_NONTASKING_OBJS) $(GNATRTL_TASKING_OBJS) \
 ADA_INCLUDE_SRCS =\
  libgnat/ada.ads libgnat/calendar.ads libgnat/directio.ads libgnat/gnat.ads libgnat/interfac.ads libgnat/ioexcept.ads \
  libgnat/machcode.ads libgnat/text_io.ads libgnat/unchconv.ads libgnat/unchdeal.ads \
- libgnat/sequenio.ads libgnat/system.ads libgnat/memtrack.adb \
+ libgnat/sequenio.ads libgnat/memtrack.adb \
  libgna*/*.gpr \
  libgnat/a-[a-o]*.adb libgnat/a-[a-o]*.ads \
  libgnat/a-[p-z]*.adb libgnat/a-[p-z]*.ads \
@@ -2987,19 +2987,10 @@ ADA_EXCLUDE_SRCS =\
   g-altive.ads g-alveop.adb g-alveop.ads g-alvety.ads g-alvevi.ads \
   g-intpri.ads g-regist.adb g-regist.ads g-sse.adsg-ssvety.ads \
   i-vxinco.adb i-vxinco.ads i-vxwoio.adb i-vxwoio.ads i-vxwork.ads \
-  s-bb.ads s-bbbosu.ads s-bbcaco.ads s-bbcppr.ads s-bbexti.adb \
-  s-bbexti.ads s-bbinte.adb s-bbinte.ads s-bbprot.adb s-bbprot.ads \
-  s-bbsle3.ads s-bbsuer.ads s-bbsule.ads s-bbthqu.adb s-bbthqu.ads \
-  s-bbthre.adb s-bbthre.ads s-bbtiev.adb s-bbtiev.ads s-bbtime.adb \
-  s-bbtime.ads s-bcprmu.adb s-bcprmu.ads s-btstch.adb s-btstch.ads \
-  s-init.ads   s-init.adb   s-linux.ads  s-macres.ads \
-  s-memcom.adb s-memcom.ads s-memmov.adb s-memmov.ads s-memset.adb \
-  s-memset.ads s-mufalo.adb s-mufalo.ads s-musplo.adb s-musplo.ads \
-  s-sam4.ads   s-sopco3.adb s-sopco3.ads s-sopco4.adb s-sopco4.ads \
-  s-sopco5.adb s-sopco5.ads s-stchop.ads s-stchop.adb s-stm32.ads \
+  s-linux.ads  s-vxwext.adb s-vxwext.ads s-win32.ads  s-winext.ads \
+  s-sopco3.adb s-sopco3.ads s-sopco4.adb s-sopco4.ads \
+  s-sopco5.adb s-sopco5.ads s-stchop.ads s-stchop.adb \
   s-strcom.adb s-strcom.ads s-thread.ads \
-  s-vxwext.adb s-vxwext.ads \
-  s-win32.ads  s-winext.ads
 
 # ADA_EXCLUDE_SRCS without the sources used by the target
 ADA_EXCLUDE_FILES=$(filter-out \




[Ada] Change rounding mode of 'Machine for static floating point

2021-04-29 Thread Pierre-Marie de Rodat
This changes the rounding mode used for the static evaluation of the
Machine attribute of floating-point types to the mode used for the
static evaluation of real expressions, for the sake of consistency.

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

gcc/ada/

* sem_attr.adb (Eval_Attribute) : Use
Round_Even instead of Round in the call to the Machine routine.diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -9107,11 +9107,13 @@ package body Sem_Attr is
   -- Machine --
   -
 
+  --  We use the same rounding mode as the one used for RM 4.9(38)
+
   when Attribute_Machine =>
  Fold_Ureal
(N,
 Eval_Fat.Machine
-  (P_Base_Type, Expr_Value_R (E1), Eval_Fat.Round, N),
+  (P_Base_Type, Expr_Value_R (E1), Eval_Fat.Round_Even, N),
 Static);
 
   --




[Ada] Tree inconsistency between -O0 and -O1

2021-04-29 Thread Pierre-Marie de Rodat
The expansion performed in Expand_N_If_Statement only at -O1 and above
can create inconsistencies in the tree that can cause trouble when
compiling different files with different optimization levels. This
is visible in particular in GNAT LLVM when generating C code on ACATS
test cc50a01.

Fixed by only doing the transformation for internally generated nodes,
but systematically. This way we preserve the original control flow for
user code and always simplify internally generated trees which was the
original motivation of this change (simplify some discriminant checks).

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

gcc/ada/

* exp_ch5.adb (Expand_N_If_Statement): Only perform the
simplification on return True/False for internal nodes when
-fpreserve-control-flow is not set.diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -3788,62 +3788,58 @@ package body Exp_Ch5 is
 
   -- return not (expression);
 
-  --  Only do these optimizations if we are at least at -O1 level and
-  --  do not do them if control flow optimizations are suppressed.
+  --  Do these optimizations only for internally generated code and only
+  --  when -fpreserve-control-flow isn't set, to preserve the original
+  --  source control flow.
 
-  if Optimization_Level > 0
+  if not Comes_From_Source (N)
 and then not Opt.Suppress_Control_Flow_Optimizations
+and then Nkind (N) = N_If_Statement
+and then No (Elsif_Parts (N))
+and then Present (Else_Statements (N))
+and then List_Length (Then_Statements (N)) = 1
+and then List_Length (Else_Statements (N)) = 1
   then
- if Nkind (N) = N_If_Statement
-   and then No (Elsif_Parts (N))
-   and then Present (Else_Statements (N))
-   and then List_Length (Then_Statements (N)) = 1
-   and then List_Length (Else_Statements (N)) = 1
- then
-declare
-   Then_Stm : constant Node_Id := First (Then_Statements (N));
-   Else_Stm : constant Node_Id := First (Else_Statements (N));
+ declare
+Then_Stm : constant Node_Id := First (Then_Statements (N));
+Else_Stm : constant Node_Id := First (Else_Statements (N));
 
-begin
-   if Nkind (Then_Stm) = N_Simple_Return_Statement
+Then_Expr : Node_Id;
+Else_Expr : Node_Id;
+
+ begin
+if Nkind (Then_Stm) = N_Simple_Return_Statement
+ and then
+   Nkind (Else_Stm) = N_Simple_Return_Statement
+then
+   Then_Expr := Expression (Then_Stm);
+   Else_Expr := Expression (Else_Stm);
+
+   if Nkind (Then_Expr) in N_Expanded_Name | N_Identifier
 and then
-  Nkind (Else_Stm) = N_Simple_Return_Statement
+  Nkind (Else_Expr) in N_Expanded_Name | N_Identifier
then
-  declare
- Then_Expr : constant Node_Id := Expression (Then_Stm);
- Else_Expr : constant Node_Id := Expression (Else_Stm);
+  if Entity (Then_Expr) = Standard_True
+and then Entity (Else_Expr) = Standard_False
+  then
+ Rewrite (N,
+   Make_Simple_Return_Statement (Loc,
+ Expression => Relocate_Node (Condition (N;
+ Analyze (N);
 
-  begin
- if Nkind (Then_Expr) in N_Expanded_Name | N_Identifier
-  and then
-Nkind (Else_Expr) in N_Expanded_Name | N_Identifier
- then
-if Entity (Then_Expr) = Standard_True
-  and then Entity (Else_Expr) = Standard_False
-then
-   Rewrite (N,
- Make_Simple_Return_Statement (Loc,
-   Expression => Relocate_Node (Condition (N;
-   Analyze (N);
-   return;
-
-elsif Entity (Then_Expr) = Standard_False
-  and then Entity (Else_Expr) = Standard_True
-then
-   Rewrite (N,
- Make_Simple_Return_Statement (Loc,
-   Expression =>
- Make_Op_Not (Loc,
-   Right_Opnd =>
- Relocate_Node (Condition (N);
-   Analyze (N);
-   return;
-end if;
- end if;
-  end;
+  elsif Entity (Then_Expr) = Standard_False
+and then Entity (Else_E

[Ada] Fix interaction of 128-bit integer types and -gnato2 mode

2021-04-29 Thread Pierre-Marie de Rodat
The -gnato2 mode of overflow checking, aka Minimized overflow checking,
cannot work for 128-bit integer types because it is implemented using
64-bit integer types.

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

gcc/ada/

* exp_ch4.adb (Expand_Compare_Minimize_Eliminate_Overflow): Remove
entry condition.
(Expand_N_In): Call Minimized_Eliminated_Overflow_Check on the left
operand before doing the special overflow expansion.
(Expand_N_Op_Eq): Likewise.
(Expand_N_Op_Ge): Likewise.
(Expand_N_Op_Gt): Likewise.
(Expand_N_Op_Le): Likewise.
(Expand_N_Op_Lt): Likewise.
(Expand_N_Op_Ne): Likewise.
(Minimized_Eliminated_Overflow_Check): Return False for Minimized
if the size of the type is greater than that of Long_Long_Integer.diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -2253,9 +2253,6 @@ package body Exp_Ch4 is
   LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
   --  Entity for Long_Long_Integer'Base
 
-  Check : constant Overflow_Mode_Type := Overflow_Check_Mode;
-  --  Current overflow checking mode
-
   procedure Set_True;
   procedure Set_False;
   --  These procedures rewrite N with an occurrence of Standard_True or
@@ -2284,17 +2281,6 @@ package body Exp_Ch4 is
--  Start of processing for Expand_Compare_Minimize_Eliminate_Overflow
 
begin
-  --  Nothing to do unless we have a comparison operator with operands
-  --  that are signed integer types, and we are operating in either
-  --  MINIMIZED or ELIMINATED overflow checking mode.
-
-  if Nkind (N) not in N_Op_Compare
-or else Check not in Minimized_Or_Eliminated
-or else not Is_Signed_Integer_Type (Etype (Left_Opnd (N)))
-  then
- return;
-  end if;
-
   --  OK, this is the case we are interested in. First step is to process
   --  our operands using the Minimize_Eliminate circuitry which applies
   --  this processing to the two operand subtrees.
@@ -6425,8 +6411,7 @@ package body Exp_Ch4 is
   --  type, then expand with a separate procedure. Note the use of the
   --  flag No_Minimize_Eliminate to prevent infinite recursion.
 
-  if Overflow_Check_Mode in Minimized_Or_Eliminated
-and then Is_Signed_Integer_Type (Ltyp)
+  if Minimized_Eliminated_Overflow_Check (Left_Opnd  (N))
 and then not No_Minimize_Eliminate (N)
   then
  Expand_Membership_Minimize_Eliminate_Overflow (N);
@@ -8343,7 +8328,9 @@ package body Exp_Ch4 is
   --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
   --  means we no longer have a comparison operation, we are all done.
 
-  Expand_Compare_Minimize_Eliminate_Overflow (N);
+  if Minimized_Eliminated_Overflow_Check (Left_Opnd (N)) then
+ Expand_Compare_Minimize_Eliminate_Overflow (N);
+  end if;
 
   if Nkind (N) /= N_Op_Eq then
  return;
@@ -9201,7 +9188,9 @@ package body Exp_Ch4 is
   --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
   --  means we no longer have a comparison operation, we are all done.
 
-  Expand_Compare_Minimize_Eliminate_Overflow (N);
+  if Minimized_Eliminated_Overflow_Check (Op1) then
+ Expand_Compare_Minimize_Eliminate_Overflow (N);
+  end if;
 
   if Nkind (N) /= N_Op_Ge then
  return;
@@ -9250,7 +9239,9 @@ package body Exp_Ch4 is
   --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
   --  means we no longer have a comparison operation, we are all done.
 
-  Expand_Compare_Minimize_Eliminate_Overflow (N);
+  if Minimized_Eliminated_Overflow_Check (Op1) then
+ Expand_Compare_Minimize_Eliminate_Overflow (N);
+  end if;
 
   if Nkind (N) /= N_Op_Gt then
  return;
@@ -9299,7 +9290,9 @@ package body Exp_Ch4 is
   --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
   --  means we no longer have a comparison operation, we are all done.
 
-  Expand_Compare_Minimize_Eliminate_Overflow (N);
+  if Minimized_Eliminated_Overflow_Check (Op1) then
+ Expand_Compare_Minimize_Eliminate_Overflow (N);
+  end if;
 
   if Nkind (N) /= N_Op_Le then
  return;
@@ -9348,7 +9341,9 @@ package body Exp_Ch4 is
   --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
   --  means we no longer have a comparison operation, we are all done.
 
-  Expand_Compare_Minimize_Eliminate_Overflow (N);
+  if Minimized_Eliminated_Overflow_Check (Op1) then
+ Expand_Compare_Minimize_Eliminate_Overflow (N);
+  end if;
 
   if Nkind (N) /= N_Op_Lt then
  return;
@@ -9942,7 +9937,9 @@ package body Exp_Ch4 is
  --  Deal with overflow checks in MINIMIZED/ELIMINATED mode and if
  --  means we no longer have a /= operation, we ar

[Ada] Eliminate useless 128-bit overflow check for conversion

2021-04-29 Thread Pierre-Marie de Rodat
This gets rid of overflow checks done using a 128-bit integer type on
64-bit platforms and that can be done in a narrower type, by reusing
the machinery already implemented to narrow the type of operations.

This runs afoul of the processing for Max_Size_In_Storage_Elements
in Expand_N_Attribute_Reference, which attempts to second guess the
expansion of checks done in universal integer contexts, so this code
is simply removed, as it does not seem to serve any real purpose.

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

gcc/ada/

* exp_attr.adb (Expand_N_Attribute_Reference)
: Apply the checks for
universal integer contexts only in the default case.
* exp_ch4.adb (Get_Size_For_Range): Move to library level.
(Expand_N_Type_Conversion): If the operand has Universal_Integer
type and the conversion requires an overflow check, try to do an
intermediate conversion to a narrower type.diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -4598,13 +4598,7 @@ package body Exp_Attr is
   --
 
   when Attribute_Max_Size_In_Storage_Elements => declare
- Typ  : constant Entity_Id := Etype (N);
- Attr : Node_Id;
- Atyp : Entity_Id;
-
- Conversion_Added : Boolean := False;
- --  A flag which tracks whether the original attribute has been
- --  wrapped inside a type conversion.
+ Typ : constant Entity_Id := Etype (N);
 
   begin
  --  If the prefix is X'Class, we transform it into a direct reference
@@ -4618,40 +4612,22 @@ package body Exp_Attr is
 return;
  end if;
 
- Apply_Universal_Integer_Attribute_Checks (N);
-
- --  The universal integer check may sometimes add a type conversion,
- --  retrieve the original attribute reference from the expression.
-
- Attr := N;
-
- if Nkind (Attr) = N_Type_Conversion then
-Attr := Expression (Attr);
-Conversion_Added := True;
- end if;
-
- pragma Assert (Nkind (Attr) = N_Attribute_Reference);
-
  --  Heap-allocated controlled objects contain two extra pointers which
  --  are not part of the actual type. Transform the attribute reference
  --  into a runtime expression to add the size of the hidden header.
 
- if Needs_Finalization (Ptyp)
-   and then not Header_Size_Added (Attr)
- then
-Set_Header_Size_Added (Attr);
-
-Atyp := Etype (Attr);
+ if Needs_Finalization (Ptyp) and then not Header_Size_Added (N) then
+Set_Header_Size_Added (N);
 
 --  Generate:
 --P'Max_Size_In_Storage_Elements +
---  Atyp (Header_Size_With_Padding (Ptyp'Alignment))
+--  Typ (Header_Size_With_Padding (Ptyp'Alignment))
 
-Rewrite (Attr,
+Rewrite (N,
   Make_Op_Add (Loc,
-Left_Opnd  => Relocate_Node (Attr),
+Left_Opnd  => Relocate_Node (N),
 Right_Opnd =>
-  Convert_To (Atyp,
+  Convert_To (Typ,
 Make_Function_Call (Loc,
   Name   =>
 New_Occurrence_Of
@@ -4663,16 +4639,13 @@ package body Exp_Attr is
 New_Occurrence_Of (Ptyp, Loc),
   Attribute_Name => Name_Alignment));
 
-Analyze_And_Resolve (Attr, Atyp);
-
---  Add a conversion to the target type
-
-if not Conversion_Added then
-   Convert_To_And_Rewrite (Typ, Attr);
-end if;
-
+Analyze_And_Resolve (N, Typ);
 return;
  end if;
+
+ --  In the other cases apply the required checks
+
+ Apply_Universal_Integer_Attribute_Checks (N);
   end;
 
   


diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -172,6 +172,10 @@ package body Exp_Ch4 is
--  routine is to find the real type by looking up the tree. We also
--  determine if the operation must be rounded.
 
+   function Get_Size_For_Range (Lo, Hi : Uint) return Uint;
+   --  Return the size of a small signed integer type covering Lo .. Hi, the
+   --  main goal being to return a size lower than that of standard types.
+
function Has_Inferable_Discriminants (N : Node_Id) return Boolean;
--  Ada 2005 (AI-216): A view of an Unchecked_Union object has inferable
--  discriminants if it has a constrained nominal type, unless the object
@@ -12270,6 +12274,41 @@ package body Exp_Ch4 is
  end;
   end if;
 
+  --  If the conversion is from Universal_Integer and requires an overflow
+  --  check, try to do an intermediate conversion to a narrower type first
+  --  with

[Ada] Self reference access discriminant

2021-04-29 Thread Pierre-Marie de Rodat
GNAT does not accept a declaration of the form:
   type Rec (D : access Rec) is null record;

To solve this, we factor out Check_Anonymous_Access_Components and
reuse it from Process_Discriminants and adjust Freeze_Record_Type
accordingly.

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

gcc/ada/

* sem_ch3.adb (Check_Anonymous_Access_Component): Factor out
core processing of Check_Anonymous_Access_Components.
(Check_Anonymous_Access_Components): Call
Check_Anonymous_Access_Component.
(Process_Discriminants): Call Check_Anonymous_Access_Component.
* freeze.adb (Freeze_Record_Type): Code cleanups and add more tree
checking to handle changes in sem_ch3.adb.
* sem_ch8.adb (Find_Type): Remove special case for access
discriminant in task types, these are now supported.diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -4002,11 +4002,6 @@ package body Freeze is
  --  Set True if we find at least one component with no component
  --  clause (used to warn about useless Pack pragmas).
 
- function Check_Allocator (N : Node_Id) return Node_Id;
- --  If N is an allocator, possibly wrapped in one or more level of
- --  qualified expression(s), return the inner allocator node, else
- --  return Empty.
-
  procedure Check_Itype (Typ : Entity_Id);
  --  If the component subtype is an access to a constrained subtype of
  --  an already frozen type, make the subtype frozen as well. It might
@@ -4022,25 +4017,6 @@ package body Freeze is
  --  variants referenceed by the Variant_Part VP are frozen. This is
  --  a recursive routine to deal with nested variants.
 
- -
- -- Check_Allocator --
- -
-
- function Check_Allocator (N : Node_Id) return Node_Id is
-Inner : Node_Id;
- begin
-Inner := N;
-loop
-   if Nkind (Inner) = N_Allocator then
-  return Inner;
-   elsif Nkind (Inner) = N_Qualified_Expression then
-  Inner := Expression (Inner);
-   else
-  return Empty;
-   end if;
-end loop;
- end Check_Allocator;
-
  -
  -- Check_Itype --
  -
@@ -4355,22 +4331,24 @@ package body Freeze is
 
 elsif Is_Access_Type (Etype (Comp))
   and then Present (Parent (Comp))
+  and then
+Nkind (Parent (Comp))
+  in N_Component_Declaration | N_Discriminant_Specification
   and then Present (Expression (Parent (Comp)))
 then
declare
   Alloc : constant Node_Id :=
-Check_Allocator (Expression (Parent (Comp)));
+Unqualify (Expression (Parent (Comp)));
 
begin
-  if Present (Alloc) then
+  if Nkind (Alloc) = N_Allocator then
 
  --  If component is pointer to a class-wide type, freeze
  --  the specific type in the expression being allocated.
  --  The expression may be a subtype indication, in which
  --  case freeze the subtype mark.
 
- if Is_Class_Wide_Type
-  (Designated_Type (Etype (Comp)))
+ if Is_Class_Wide_Type (Designated_Type (Etype (Comp)))
  then
 if Is_Entity_Name (Expression (Alloc)) then
Freeze_And_Append
@@ -4382,17 +4360,14 @@ package body Freeze is
 (Entity (Subtype_Mark (Expression (Alloc))),
  N, Result);
 end if;
-
  elsif Is_Itype (Designated_Type (Etype (Comp))) then
 Check_Itype (Etype (Comp));
-
  else
 Freeze_And_Append
   (Designated_Type (Etype (Comp)), N, Result);
  end if;
   end if;
end;
-
 elsif Is_Access_Type (Etype (Comp))
   and then Is_Itype (Designated_Type (Etype (Comp)))
 then


diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -245,11 +245,12 @@ package body Sem_Ch3 is
--  belongs must be a concurrent type or a descendant of a type with
--  the reserved word 'limited' in its declaration.
 
-   procedure Check_Anonymous_Access_Components
-  (Typ_Decl  : Node_Id;
-   Typ   : Entity_Id;
-   Prev  : Entity_Id;
-   Comp_List : Node_Id);
+   procedure Check_Anonymous_Access_Component
+ (Typ_Decl   : Node_Id;
+  

[PATCH] aarch64: Fix ICE in aarch64_add_offset_1_temporaries [PR100302]

2021-04-29 Thread Jakub Jelinek via Gcc-patches
Hi!

In PR94121 I've changed aarch64_add_offset_1 to use absu_hwi instead of
abs_hwi because offset can be HOST_WIDE_INT_MIN.  As can be seen with
the testcase below, aarch64_add_offset_1_temporaries suffers from the same
problem and should be in sync with aarch64_add_offset_1, i.e. for
HOST_WIDE_INT_MIN it needs a temporary.

Bootstrapped/regtested on aarch64-linux, ok for trunk?

2021-04-29  Jakub Jelinek  

PR target/100302
* config/aarch64/aarch64.c (aarch64_add_offset_1_temporaries): Use
absu_hwi instead of abs_hwi.

* gcc.target/aarch64/sve/pr100302.c: New test.

--- gcc/config/aarch64/aarch64.c.jj 2021-04-28 10:43:06.313337362 +0200
+++ gcc/config/aarch64/aarch64.c2021-04-28 11:01:10.567243000 +0200
@@ -4736,7 +4736,7 @@ aarch64_mov128_immediate (rtx imm)
 static unsigned int
 aarch64_add_offset_1_temporaries (HOST_WIDE_INT offset)
 {
-  return abs_hwi (offset) < 0x100 ? 0 : 1;
+  return absu_hwi (offset) < 0x100 ? 0 : 1;
 }
 
 /* A subroutine of aarch64_add_offset.  Set DEST to SRC + OFFSET for
--- gcc/testsuite/gcc.target/aarch64/sve/pr100302.c.jj  2021-04-28 
10:49:19.337176274 +0200
+++ gcc/testsuite/gcc.target/aarch64/sve/pr100302.c 2021-04-28 
10:42:48.342537828 +0200
@@ -0,0 +1,12 @@
+/* PR target/100302 */
+/* { dg-do compile } */
+/* { dg-options "-march=armv8.2-a+sve -O1 -ftree-loop-vectorize 
-fno-tree-scev-cprop --param vect-partial-vector-usage=0 
-fvect-cost-model=unlimited" } */
+
+long int x;
+
+void
+foo (void)
+{
+  for (x = 0; x >= 0; ++x)
+;
+}

Jakub



Re: [PATCH] aarch64: Fix ICE in aarch64_add_offset_1_temporaries [PR100302]

2021-04-29 Thread Richard Sandiford via Gcc-patches
Jakub Jelinek  writes:
> Hi!
>
> In PR94121 I've changed aarch64_add_offset_1 to use absu_hwi instead of
> abs_hwi because offset can be HOST_WIDE_INT_MIN.  As can be seen with
> the testcase below, aarch64_add_offset_1_temporaries suffers from the same
> problem and should be in sync with aarch64_add_offset_1, i.e. for
> HOST_WIDE_INT_MIN it needs a temporary.
>
> Bootstrapped/regtested on aarch64-linux, ok for trunk?
>
> 2021-04-29  Jakub Jelinek  
>
>   PR target/100302
>   * config/aarch64/aarch64.c (aarch64_add_offset_1_temporaries): Use
>   absu_hwi instead of abs_hwi.
>
>   * gcc.target/aarch64/sve/pr100302.c: New test.

OK, thanks.

Richard

> --- gcc/config/aarch64/aarch64.c.jj   2021-04-28 10:43:06.313337362 +0200
> +++ gcc/config/aarch64/aarch64.c  2021-04-28 11:01:10.567243000 +0200
> @@ -4736,7 +4736,7 @@ aarch64_mov128_immediate (rtx imm)
>  static unsigned int
>  aarch64_add_offset_1_temporaries (HOST_WIDE_INT offset)
>  {
> -  return abs_hwi (offset) < 0x100 ? 0 : 1;
> +  return absu_hwi (offset) < 0x100 ? 0 : 1;
>  }
>  
>  /* A subroutine of aarch64_add_offset.  Set DEST to SRC + OFFSET for
> --- gcc/testsuite/gcc.target/aarch64/sve/pr100302.c.jj2021-04-28 
> 10:49:19.337176274 +0200
> +++ gcc/testsuite/gcc.target/aarch64/sve/pr100302.c   2021-04-28 
> 10:42:48.342537828 +0200
> @@ -0,0 +1,12 @@
> +/* PR target/100302 */
> +/* { dg-do compile } */
> +/* { dg-options "-march=armv8.2-a+sve -O1 -ftree-loop-vectorize 
> -fno-tree-scev-cprop --param vect-partial-vector-usage=0 
> -fvect-cost-model=unlimited" } */
> +
> +long int x;
> +
> +void
> +foo (void)
> +{
> +  for (x = 0; x >= 0; ++x)
> +;
> +}
>
>   Jakub


New French PO file for 'gcc' (version 11.1.0)

2021-04-29 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 French team of translators.  The file is available at:

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

(This file, 'gcc-11.1.0.fr.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.




[committed] c++: Fix up detach clause vs. data-sharing clause checking [PR100319]

2021-04-29 Thread Jakub Jelinek via Gcc-patches
Hi!

The standard says that "The event-handle will be considered as if it
was specified on a firstprivate clause." which means that it can't
be explicitly specified in some other data-sharing clause.
The checking is implemented correctly for C, but for C++ when detach_seen
is true (i.e. the construct had detach clause) we were comparing
OMP_CLAUSE_DECL (c) with t, which was previously initialized to
OMP_CLAUSE_DECL (c), which means it complained about any explicit
data-sharing clause on the same construct with a detach clause.

Fixed by remembering the detach clause in detach_seen (instead of a boolean
flag) and comparing against its OMP_CLAUSE_DECL.

Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk.

2021-04-29  Jakub Jelinek  

PR c++/100319
* semantics.c (finish_omp_clauses): Fix up check that variable
mentioned in detach clause doesn't appear in data-sharing clauses.

* c-c++-common/gomp/task-detach-3.c: New test.

--- gcc/cp/semantics.c.jj   2021-04-15 10:40:33.380919956 +0200
+++ gcc/cp/semantics.c  2021-04-28 17:11:07.325684916 +0200
@@ -6527,7 +6527,7 @@ finish_omp_clauses (tree clauses, enum c
  has been seen, -2 if mixed inscan/normal reduction diagnosed.  */
   int reduction_seen = 0;
   bool allocate_seen = false;
-  bool detach_seen = false;
+  tree detach_seen = NULL_TREE;
   bool mergeable_seen = false;
 
   bitmap_obstack_initialize (NULL);
@@ -7578,7 +7578,7 @@ finish_omp_clauses (tree clauses, enum c
type);
  remove = true;
}
- detach_seen = true;
+ detach_seen = c;
  cxx_mark_addressable (t);
}
  break;
@@ -8548,7 +8548,7 @@ finish_omp_clauses (tree clauses, enum c
  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
- && OMP_CLAUSE_DECL (c) == t)
+ && OMP_CLAUSE_DECL (c) == OMP_CLAUSE_DECL (detach_seen))
{
  error_at (OMP_CLAUSE_LOCATION (c),
"the event handle of a % clause "
--- gcc/testsuite/c-c++-common/gomp/task-detach-3.c.jj  2021-04-28 
17:11:07.326684905 +0200
+++ gcc/testsuite/c-c++-common/gomp/task-detach-3.c 2021-04-28 
17:11:29.594436563 +0200
@@ -0,0 +1,19 @@
+/* PR c++/100319 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+typedef enum omp_event_handle_t
+{
+  __omp_event_handle_t_max__ = __UINTPTR_MAX__
+} omp_event_handle_t;
+
+extern void omp_fulfill_event (omp_event_handle_t);
+
+void f (omp_event_handle_t x, omp_event_handle_t y, int z)
+{
+  #pragma omp task detach (x) firstprivate (y, z)  /* { dg-bogus "the 
event handle of a 'detach' clause should not be in a data-sharing clause" } */
+;
+
+  #pragma omp task detach (x) shared (y)   /* { dg-bogus "the 
event handle of a 'detach' clause should not be in a data-sharing clause" } */
+;
+}

Jakub



[patch] Add parallelism support to gcov for MinGW platforms

2021-04-29 Thread Eric Botcazou
Hi,

if you attempt a profiled bootstrap on the MinGW platforms with -jN, N > 1,
it miserably fails because of profile mismatches all over the place, the
reason being that gcov has no support for parallelism on these platforms.

The attached patch adds it and, therefore, makes it possible to do a profiled
bootstrap with -jN, N > 1, on these platforms.

Tested on x86-64/Linux, x86-64/Windows and x86/Windows, OK for the mainline?


2021-04-29  Eric Botcazou  

libgcc/
* libgcc/libgcov.h: For the target, define GCOV_LOCKED_WITH_LOCKING if
__MSVCRT__ and, for the host, define it if HOST_HAS_LK_LOCK.
* libgcov-driver.c: Add include directives if GCOV_LOCKED_WITH_LOCKING.
gcc/
* configure.ac: Check for the presence of sys/locking.h header and for
whether _LK_LOCK is supported by _locking.
* configure: Regenerate.
* config.in: Likewise.
* gcov-io.h: Define GCOV_LOCKED_WITH_LOCKING if HOST_HAS_LK_LOCK.
* gcov-io.c (gcov_open): Add support for GCOV_LOCKED_WITH_LOCKING.
* system.h: Include  if HAVE_SYS_LOCKING_H.

-- 
Eric Botcazoudiff --git a/gcc/configure.ac b/gcc/configure.ac
index 22305e37071..e9ba2af548a 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -1257,7 +1257,7 @@ AC_HEADER_SYS_WAIT
 AC_HEADER_TIOCGWINSZ
 AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
 		 fcntl.h ftw.h unistd.h sys/file.h sys/time.h sys/mman.h \
-		 sys/resource.h sys/param.h sys/times.h sys/stat.h \
+		 sys/resource.h sys/param.h sys/times.h sys/stat.h sys/locking.h \
 		 direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h)
 
 # Check for thread headers.
@@ -1711,6 +1711,19 @@ if test $ac_cv_af_inet6 = yes; then
   [Define if AF_INET6 supported.])
 fi
 
+# Check if _LK_LOCK is supported by _locking
+AC_CACHE_CHECK(for _LK_LOCK, ac_cv_lk_lock, [
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include 
+#include ]], [[
+  int fd;
+  return _locking (fd, _LK_LOCK, 0);]])],
+[ac_cv_lk_lock=yes],[ac_cv_lk_lock=no])])
+if test $ac_cv_lk_lock = yes; then
+  AC_DEFINE(HOST_HAS_LK_LOCK, 1,
+  [Define if _LK_LOC supported by _locking.])
+fi
+
 # Restore CFLAGS, CXXFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
 CFLAGS="$saved_CFLAGS"
 CXXFLAGS="$saved_CXXFLAGS"
diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c
index 80c9082a649..21ca3949c41 100644
--- a/gcc/gcov-io.c
+++ b/gcc/gcov-io.c
@@ -137,6 +137,8 @@ gcov_open (const char *name, int mode)
   s_flock.l_start = 0;
   s_flock.l_len = 0; /* Until EOF.  */
   s_flock.l_pid = getpid ();
+#elif GCOV_LOCKED_WITH_LOCKING
+  int fd;
 #endif
 
   gcov_nonruntime_assert (!gcov_var.file);
@@ -170,6 +172,34 @@ gcov_open (const char *name, int mode)
 
   gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b");
 
+  if (!gcov_var.file)
+{
+  close (fd);
+  return 0;
+}
+#elif GCOV_LOCKED_WITH_LOCKING
+  if (mode > 0)
+{
+  /* pass mode (ignored) for compatibility */
+  fd = open (name, O_RDONLY | O_BINARY, S_IRUSR | S_IWUSR);
+}
+  else
+ {
+   /* Truncate if force new mode.  */
+   fd = open (name, O_RDWR | O_BINARY | O_CREAT | (mode < 0 ? O_TRUNC : 0),
+		  0666);
+}
+  if (fd < 0)
+return 0;
+
+  if (_locking (fd, _LK_LOCK, LONG_MAX) < 0)
+{
+  close (fd);
+  return 0;
+}
+
+  gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b");
+
   if (!gcov_var.file)
 {
   close (fd);
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 75f16a274c7..c9958f450d3 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -202,6 +202,12 @@ typedef uint64_t gcov_type_unsigned;
 #define GCOV_LOCKED 0
 #endif
 
+#if defined (HOST_HAS_LK_LOCK)
+#define GCOV_LOCKED_WITH_LOCKING 1
+#else
+#define GCOV_LOCKED_WITH_LOCKING 0
+#endif
+
 #define ATTRIBUTE_HIDDEN
 
 #endif /* !IN_LIBGCOV */
diff --git a/gcc/system.h b/gcc/system.h
index a3f5948aaee..6416c4e033e 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -360,6 +360,10 @@ extern int errno;
 # endif
 #endif
 
+#ifdef HAVE_SYS_LOCKING_H
+# include 
+#endif
+
 #ifndef SEEK_SET
 # define SEEK_SET 0
 # define SEEK_CUR 1
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index a1338b6e525..faa2df44715 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -36,10 +36,15 @@ void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
 #else /* inhibit_libc */
 
 #include 
+
 #if GCOV_LOCKED
 #include 
 #include 
 #include 
+#elif GCOV_LOCKED_WITH_LOCKING
+#include 
+#include 
+#include 
 #endif
 
 #if HAVE_SYS_MMAN_H
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 7b0d367ec52..8d323db0538 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -89,6 +89,12 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
 #define GCOV_LOCKED 0
 #endif
 
+#if defined (__MSVCRT__)
+#define GCOV_LOCKED_WITH_LOCKING 1
+#else
+#define GCOV_LOCKED_WITH_LOCKING 0
+#endif
+
 #ifndef GCOV_SUPPORTS_ATOMIC
 /* Detect whether target can support atomic update of profilers.  */
 #

[committed] testsuite: Remove dg-options from pr100305.c [PR100305]

2021-04-29 Thread Jakub Jelinek via Gcc-patches
Hi!

The test FAILs on i?86-linux (due to -Wpsabi warnings).  But, on closer
inspection it seems there is another problem, the dg-options in the testcase
means that the test is compiled with -O0 -O, -O1 -O, -O2 -O, -O3 -O, -Os -O
etc. options, so effectively is tested multiple times with the same options.

Fixed by dropping the dg-options line, then we have -w by default and iterate
over all the optimization levels (including the -O).

Tested on x86_64-linux with
RUNTESTFLAGS='--target_board=unix\{-m32/-mno-sse,-m32,-m64\} 
compile.exp=pr100305.c'
and committed to trunk and 11 as obvious.

2021-04-29  Jakub Jelinek  

PR target/100305
* gcc.c-torture/compile/pr100305.c: Remove dg-options.  Add PR line.

--- gcc/testsuite/gcc.c-torture/compile/pr100305.c.jj   2021-04-29 
11:07:58.877205739 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr100305.c  2021-04-29 
11:39:42.161152369 +0200
@@ -1,4 +1,4 @@
-/* { dg-options "-O" } */
+/* PR target/100305 */
 
 typedef double v2df __attribute__((vector_size(16)));
 


Jakub



[PATCH] split loop for NE condition.

2021-04-29 Thread Jiufu Guo via Gcc-patches
When there is the possibility that overflow may happen on the loop index,
a few optimizations would not happen. For example code:

foo (int *a, int *b, unsigned k, unsigned n)
{
  while (++k != n)
a[k] = b[k]  + 1;
}

For this code, if "l > n", overflow may happen.  if "l < n" at begining,
it could be optimized (e.g. vectorization).

We can split the loop into two loops:

  while (++k > n)
a[k] = b[k]  + 1;
  while (l++ < n)
a[k] = b[k]  + 1;

then for the second loop, it could be optimized.

This patch is spltting this kind of small loop to achieve better performance.

Bootstrap and regtest pass on ppc64le.  Is this ok for trunk?

Thanks!

Jiufu Guo.

gcc/ChangeLog:

2021-04-29  Jiufu Guo  

* params.opt (max-insns-ne-cond-split): New.
* tree-ssa-loop-split.c (connect_loop_phis): Add new param.
(get_ne_cond_branch): New function.
(split_ne_loop): New function.
(split_loop_on_ne_cond): New function.
(tree_ssa_split_loops): Use split_loop_on_ne_cond.

gcc/testsuite/ChangeLog:
2021-04-29  Jiufu Guo  

* gcc.dg/loop-split1.c: New test.

---
 gcc/params.opt |   4 +
 gcc/testsuite/gcc.dg/loop-split1.c |  28 
 gcc/tree-ssa-loop-split.c  | 219 -
 3 files changed, 247 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/loop-split1.c

diff --git a/gcc/params.opt b/gcc/params.opt
index 2e4cbdd7a71..900b59b5136 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -766,6 +766,10 @@ Min. ratio of insns to prefetches to enable prefetching 
for a loop with an unkno
 Common Joined UInteger Var(param_min_loop_cond_split_prob) Init(30) 
IntegerRange(0, 100) Param Optimization
 The minimum threshold for probability of semi-invariant condition statement to 
trigger loop split.
 
+-param=max-insns-ne-cond-split=
+Common Joined UInteger Var(param_max_insn_ne_cond_split) Init(64) Param 
Optimization
+The maximum threshold for insnstructions number of a loop with ne condition to 
split.
+
 -param=min-nondebug-insn-uid=
 Common Joined UInteger Var(param_min_nondebug_insn_uid) Param
 The minimum UID to be used for a nondebug insn.
diff --git a/gcc/testsuite/gcc.dg/loop-split1.c 
b/gcc/testsuite/gcc.dg/loop-split1.c
new file mode 100644
index 000..4c466aa9f54
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/loop-split1.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fsplit-loops -fdump-tree-lsplit-details" } */
+
+void
+foo (int *a, int *b, unsigned l, unsigned n)
+{
+  while (++l != n)
+a[l] = b[l]  + 1;
+}
+
+void
+foo1 (int *a, int *b, unsigned l, unsigned n)
+{
+  while (l++ != n)
+a[l] = b[l]  + 1;
+}
+
+unsigned
+foo2 (char *a, char *b, unsigned l, unsigned n)
+{
+  while (++l != n)
+if (a[l] != b[l])
+  break;
+
+  return l;
+}
+
+/* { dg-final { scan-tree-dump-times "Loop split" 3 "lsplit" } } */
diff --git a/gcc/tree-ssa-loop-split.c b/gcc/tree-ssa-loop-split.c
index b80b6a75e62..a6d28078e5e 100644
--- a/gcc/tree-ssa-loop-split.c
+++ b/gcc/tree-ssa-loop-split.c
@@ -41,6 +41,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfghooks.h"
 #include "gimple-fold.h"
 #include "gimplify-me.h"
+#include "tree-ssa-loop-ivopts.h"
 
 /* This file implements two kinds of loop splitting.
 
@@ -233,7 +234,8 @@ easy_exit_values (class loop *loop)
this.  The loops need to fulfill easy_exit_values().  */
 
 static void
-connect_loop_phis (class loop *loop1, class loop *loop2, edge new_e)
+connect_loop_phis (class loop *loop1, class loop *loop2, edge new_e,
+  bool use_prev = false)
 {
   basic_block rest = loop_preheader_edge (loop2)->src;
   gcc_assert (new_e->dest == rest);
@@ -248,13 +250,14 @@ connect_loop_phis (class loop *loop1, class loop *loop2, 
edge new_e)
!gsi_end_p (psi_first);
gsi_next (&psi_first), gsi_next (&psi_second))
 {
-  tree init, next, new_init;
+  tree init, next, new_init, prev;
   use_operand_p op;
   gphi *phi_first = psi_first.phi ();
   gphi *phi_second = psi_second.phi ();
 
   init = PHI_ARG_DEF_FROM_EDGE (phi_first, firste);
   next = PHI_ARG_DEF_FROM_EDGE (phi_first, firstn);
+  prev = PHI_RESULT (phi_first);
   op = PHI_ARG_DEF_PTR_FROM_EDGE (phi_second, seconde);
   gcc_assert (operand_equal_for_phi_arg_p (init, USE_FROM_PTR (op)));
 
@@ -279,7 +282,7 @@ connect_loop_phis (class loop *loop1, class loop *loop2, 
edge new_e)
 
   gphi * newphi = create_phi_node (new_init, rest);
   add_phi_arg (newphi, init, skip_first, UNKNOWN_LOCATION);
-  add_phi_arg (newphi, next, new_e, UNKNOWN_LOCATION);
+  add_phi_arg (newphi, use_prev ? prev : next, new_e, UNKNOWN_LOCATION);
   SET_USE (op, new_init);
 }
 }
@@ -1599,6 +1602,213 @@ split_loop_on_cond (struct loop *loop)
   return do_split;
 }
 
+/* Check if the LOOP exit branch likes "if (idx != bound)".
+   if INV is not NULL and the branch is "if (bound != i

Re: [committed] testsuite: Remove dg-options from pr100305.c [PR100305]

2021-04-29 Thread Richard Sandiford via Gcc-patches
Jakub Jelinek  writes:
> Hi!
>
> The test FAILs on i?86-linux (due to -Wpsabi warnings).  But, on closer
> inspection it seems there is another problem, the dg-options in the testcase
> means that the test is compiled with -O0 -O, -O1 -O, -O2 -O, -O3 -O, -Os -O
> etc. options, so effectively is tested multiple times with the same options.
>
> Fixed by dropping the dg-options line, then we have -w by default and iterate
> over all the optimization levels (including the -O).

Gah, sorry about that.  It started life as an aarch64-specific test,
where the dg-options was needed.  I forgot to remove it when moving
the test.

Richard

> Tested on x86_64-linux with
> RUNTESTFLAGS='--target_board=unix\{-m32/-mno-sse,-m32,-m64\} 
> compile.exp=pr100305.c'
> and committed to trunk and 11 as obvious.
>
> 2021-04-29  Jakub Jelinek  
>
>   PR target/100305
>   * gcc.c-torture/compile/pr100305.c: Remove dg-options.  Add PR line.
>
> --- gcc/testsuite/gcc.c-torture/compile/pr100305.c.jj 2021-04-29 
> 11:07:58.877205739 +0200
> +++ gcc/testsuite/gcc.c-torture/compile/pr100305.c2021-04-29 
> 11:39:42.161152369 +0200
> @@ -1,4 +1,4 @@
> -/* { dg-options "-O" } */
> +/* PR target/100305 */
>  
>  typedef double v2df __attribute__((vector_size(16)));
>  
>
>
>   Jakub


Re: [PATCH 1/1] PR100281 Fix SImode pointer handling

2021-04-29 Thread Richard Biener via Gcc-patches
On Wed, Apr 28, 2021 at 1:52 PM Andreas Krebbel  wrote:
>
> On 4/28/21 10:12 AM, Richard Biener wrote:
> > On Wed, Apr 28, 2021 at 8:54 AM Andreas Krebbel via Gcc-patches
> >  wrote:
> >>
> >> The problem appears to be triggered by two locations in the front-end
> >> where non-POINTER_SIZE pointers aren't handled right now.
> >>
> >> 1. An assertion in strip_typedefs is triggered because the alignment
> >> of the types don't match. This in turn is caused by creating the new
> >> type with build_pointer_type instead of taking the type of the
> >> original pointer into account.
> >>
> >> 2. An assertion in cp_convert_to_pointer is triggered which expects
> >> the target type to always have POINTER_SIZE.
> >>
> >> Ok for mainline?
> >>
> >> gcc/cp/ChangeLog:
> >>
> >> PR c++/100281
> >> * cvt.c (cp_convert_to_pointer): Use the size of the target
> >> pointer type.
> >> * tree.c (strip_typedefs): Use build_pointer_type_for_mode for
> >> non-POINTER_SIZE pointers.
> >>
> >> gcc/testsuite/ChangeLog:
> >>
> >> PR c++/100281
> >> * g++.target/s390/pr100281.C: New test.
> >> ---
> >>  gcc/cp/cvt.c |  2 +-
> >>  gcc/cp/tree.c|  5 -
> >>  gcc/testsuite/g++.target/s390/pr100281.C | 10 ++
> >>  3 files changed, 15 insertions(+), 2 deletions(-)
> >>  create mode 100644 gcc/testsuite/g++.target/s390/pr100281.C
> >>
> >> diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
> >> index f1687e804d1..7fa6e8df52b 100644
> >> --- a/gcc/cp/cvt.c
> >> +++ b/gcc/cp/cvt.c
> >> @@ -232,7 +232,7 @@ cp_convert_to_pointer (tree type, tree expr, bool 
> >> dofold,
> >>  {
> >>if (TYPE_PRECISION (intype) == POINTER_SIZE)
> >> return build1 (CONVERT_EXPR, type, expr);
> >> -  expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr,
> >> +  expr = cp_convert (c_common_type_for_size (TYPE_PRECISION (type), 
> >> 0), expr,
> >>  complain);
> >>/* Modes may be different but sizes should be the same.  There
> >>  is supposed to be some integral type that is the same width
> >> diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
> >> index a8bfd5fc053..6f6b732c9c9 100644
> >> --- a/gcc/cp/tree.c
> >> +++ b/gcc/cp/tree.c
> >> @@ -1556,7 +1556,10 @@ strip_typedefs (tree t, bool *remove_attributes, 
> >> unsigned int flags)
> >>  {
> >>  case POINTER_TYPE:
> >>type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
> >> -  result = build_pointer_type (type);
> >> +  if (TYPE_PRECISION (t) == POINTER_SIZE)
> >> +   result = build_pointer_type (type);
> >> +  else
> >> +   result = build_pointer_type_for_mode (type, TYPE_MODE (t), false);
> >
> > I wonder under which circumstances re-using the original mode will fail?  In
> > particular I do not like the TYPE_PRECISION check.  Supposedly you
> > were thinking of playing safe?
> >
> >>break;
> >>  case REFERENCE_TYPE:
> >>type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
> >
> > There's code below with exactly the same issue for reference types which
> > would need adjustments to cp_build_reference_type.
> >
> >> diff --git a/gcc/testsuite/g++.target/s390/pr100281.C 
> >> b/gcc/testsuite/g++.target/s390/pr100281.C
> >> new file mode 100644
> >> index 000..f45798c3879
> >> --- /dev/null
> >> +++ b/gcc/testsuite/g++.target/s390/pr100281.C
> >> @@ -0,0 +1,10 @@
> >> +// PR C++/100281
> >> +// { dg-do compile }
> >> +
> >> +typedef void * __attribute__((mode (SI))) __ptr32_t;
> >> +
> >> +void foo(){
> >> +  unsigned int b = 100;
> >> +  __ptr32_t a;
> >> +  a = b; /* { dg-error "invalid conversion from 'unsigned int' to 
> >> '__ptr32_t'.*" } */
> >> +}
> >> --
> >> 2.30.2
> >>
>
> Like so?

Sth like that - the MAX_MACHINE_MODE thing is a bit ugly
(maybe use VOIDmode?).  Of course should be reviewed by a C++ maintainer.

Richard.

> diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
> index f1687e804d1..7fa6e8df52b 100644
> --- a/gcc/cp/cvt.c
> +++ b/gcc/cp/cvt.c
> @@ -232,7 +232,7 @@ cp_convert_to_pointer (tree type, tree expr, bool dofold,
>  {
>if (TYPE_PRECISION (intype) == POINTER_SIZE)
> return build1 (CONVERT_EXPR, type, expr);
> -  expr = cp_convert (c_common_type_for_size (POINTER_SIZE, 0), expr,
> +  expr = cp_convert (c_common_type_for_size (TYPE_PRECISION (type), 0), 
> expr,
>  complain);
>/* Modes may be different but sizes should be the same.  There
>  is supposed to be some integral type that is the same width
> diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
> index a8bfd5fc053..fe5c414c8d9 100644
> --- a/gcc/cp/tree.c
> +++ b/gcc/cp/tree.c
> @@ -1201,12 +1201,14 @@ vla_type_p (tree t)
>return false;
>  }
>
> -/* Return a reference type node referring to TO_TYPE.  If RVAL is
> -   true, return an rvalue reference type, otherwise return an lvalue
> -   reference type.

Re: [PATCH] rtl-ssa: Fix -fcompare-debug failure [PR100303]

2021-04-29 Thread Richard Biener via Gcc-patches
On Wed, Apr 28, 2021 at 9:07 PM Richard Sandiford via Gcc-patches
 wrote:
>
> This patch fixes an oversight in the handling of debug instructions
> in rtl-ssa.  At the moment (and whether this is a good idea or not
> remains to be seen), we maintain a linear RPO sequence of definitions
> and non-debug uses.  If a register is defined more than once, we use
> a degenerate phi to reestablish a previous definition where necessary.
>
> However, debug instructions shouldn't of course affect codegen,
> so we can't create a new definition just for them.  In those situations
> we instead hang the debug use off the real definition (meaning that
> debug uses do not follow a linear order wrt definitions).  Again,
> it remains to be seen whether that's a good idea.
>
> The problem in the PR was that we weren't taking this into account
> when increasing (or potentially increasing) the live range of an
> existing definition.  We'd create the phi even if it would only
> be used by debug instructions.
>
> The patch goes for the simple but inelegant approach of passing
> a bool to say whether the use is a debug use or not.  I imagine
> this area will need some tweaking based on experience in future.
>
> Tested on aarch64-linux-gnu (where the test also failed).
> OK to install?

OK.

Thanks,
Richard.

> Richard
>
>
> gcc/
> PR rtl-optimization/100303
> * rtl-ssa/accesses.cc (function_info::make_use_available): Take a
> boolean that indicates whether the use will only be used in
> debug instructions.  Treat it in the same way that existing
> cross-EBB debug references would be handled if so.
> (function_info::make_uses_available): Likewise.
> * rtl-ssa/functions.h (function_info::make_uses_available): Update
> prototype accordingly.
> (function_info::make_uses_available): Likewise.
> * fwprop.c (try_fwprop_subst): Update call accordingly.
> ---
>  gcc/fwprop.c|   3 +-
>  gcc/rtl-ssa/accesses.cc |  15 ++--
>  gcc/rtl-ssa/functions.h |   7 +-
>  gcc/testsuite/g++.dg/torture/pr100303.C | 112 
>  4 files changed, 129 insertions(+), 8 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/torture/pr100303.C
>
> diff --git a/gcc/fwprop.c b/gcc/fwprop.c
> index d7203672886..73284a7ae3e 100644
> --- a/gcc/fwprop.c
> +++ b/gcc/fwprop.c
> @@ -606,7 +606,8 @@ try_fwprop_subst (use_info *use, set_info *def,
>if (def_insn->bb () != use_insn->bb ())
>  {
>src_uses = crtl->ssa->make_uses_available (attempt, src_uses,
> -use_insn->bb ());
> +use_insn->bb (),
> +use_insn->is_debug_insn ());
>if (!src_uses.is_valid ())
> return false;
>  }
> diff --git a/gcc/rtl-ssa/accesses.cc b/gcc/rtl-ssa/accesses.cc
> index de3a29edbeb..a55cc8817a7 100644
> --- a/gcc/rtl-ssa/accesses.cc
> +++ b/gcc/rtl-ssa/accesses.cc
> @@ -1242,7 +1242,10 @@ function_info::insert_temp_clobber (obstack_watermark 
> &watermark,
>  }
>
>  // A subroutine of make_uses_available.  Try to make USE's definition
> -// available at the head of BB.  On success:
> +// available at the head of BB.  WILL_BE_DEBUG_USE is true if the
> +// definition will be used only in debug instructions.
> +//
> +// On success:
>  //
>  // - If the use would have the same def () as USE, return USE.
>  //
> @@ -1254,7 +1257,8 @@ function_info::insert_temp_clobber (obstack_watermark 
> &watermark,
>  //
>  // Return null on failure.
>  use_info *
> -function_info::make_use_available (use_info *use, bb_info *bb)
> +function_info::make_use_available (use_info *use, bb_info *bb,
> +  bool will_be_debug_use)
>  {
>set_info *def = use->def ();
>if (!def)
> @@ -1270,7 +1274,7 @@ function_info::make_use_available (use_info *use, 
> bb_info *bb)
>&& single_pred (cfg_bb) == use_bb->cfg_bb ()
>&& remains_available_on_exit (def, use_bb))
>  {
> -  if (def->ebb () == bb->ebb ())
> +  if (def->ebb () == bb->ebb () || will_be_debug_use)
> return use;
>
>resource_info resource = use->resource ();
> @@ -1314,7 +1318,8 @@ function_info::make_use_available (use_info *use, 
> bb_info *bb)
>  // See the comment above the declaration.
>  use_array
>  function_info::make_uses_available (obstack_watermark &watermark,
> -   use_array uses, bb_info *bb)
> +   use_array uses, bb_info *bb,
> +   bool will_be_debug_uses)
>  {
>unsigned int num_uses = uses.size ();
>if (num_uses == 0)
> @@ -1323,7 +1328,7 @@ function_info::make_uses_available (obstack_watermark 
> &watermark,
>auto **new_uses = XOBNEWVEC (watermark, access_info *, num_uses);
>for (unsigned int i = 0; i < num_uses; ++i)
>  {
> -  

[PATCH] tree-optimization/100253 - fix bogus aligned vectorized loads/stores

2021-04-29 Thread Richard Biener
At some point DR_MISALIGNMENT was supposed to be -1 when the
access was not element aligned.  That's obviously not true at this
point so this adjusts both store and load vectorizing to no longer
assume this which in turn allows simplifying the code.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed to
trunk sofar.

2021-04-29  Richard Biener  

PR tree-optimization/100253
* tree-vect-stmts.c (vectorizable_load): Do not assume
element alignment when DR_MISALIGNMENT is -1.
(vectorizable_store): Likewise.

* g++.dg/pr100253.C: New testcase.
---
 gcc/testsuite/g++.dg/pr100253.C | 33 +
 gcc/tree-vect-stmts.c   | 18 --
 2 files changed, 37 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/pr100253.C

diff --git a/gcc/testsuite/g++.dg/pr100253.C b/gcc/testsuite/g++.dg/pr100253.C
new file mode 100644
index 000..0102caa7df8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr100253.C
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-tree-bit-ccp -ftree-slp-vectorize" } */
+
+#include 
+
+struct T
+{
+};
+
+struct S
+{
+  std::vector < std::vector < T > > v;
+  char x;
+  char y[16];
+  char z[16];
+};
+
+S s, g[1];
+
+void
+foo (char *buf)
+{
+  s = g[*buf];
+}
+
+char c;
+
+int
+main ()
+{
+  foo (&c);
+  return 0;
+}
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 4c01e82ff39..bd2a1c89e67 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -8166,6 +8166,7 @@ vectorizable_store (vec_info *vinfo,
  && TREE_CODE (dataref_ptr) == SSA_NAME)
set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
misalign);
+ align = least_bit_hwi (misalign | align);
 
  if (memory_access_type == VMAT_CONTIGUOUS_REVERSE)
{
@@ -8187,7 +8188,6 @@ vectorizable_store (vec_info *vinfo,
  /* Arguments are ready.  Create the new vector stmt.  */
  if (final_mask)
{
- align = least_bit_hwi (misalign | align);
  tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT);
  gcall *call
= gimple_build_call_internal (IFN_MASK_STORE, 4,
@@ -8202,7 +8202,6 @@ vectorizable_store (vec_info *vinfo,
  tree final_len
= vect_get_loop_len (loop_vinfo, loop_lens,
 vec_num * ncopies, vec_num * j + i);
- align = least_bit_hwi (misalign | align);
  tree ptr = build_int_cst (ref_type, align * BITS_PER_UNIT);
  machine_mode vmode = TYPE_MODE (vectype);
  opt_machine_mode new_ovmode
@@ -8241,14 +8240,10 @@ vectorizable_store (vec_info *vinfo,
  : build_int_cst (ref_type, 0));
  if (aligned_access_p (first_dr_info))
;
- else if (DR_MISALIGNMENT (first_dr_info) == -1)
-   TREE_TYPE (data_ref)
- = build_aligned_type (TREE_TYPE (data_ref),
-   align * BITS_PER_UNIT);
  else
TREE_TYPE (data_ref)
  = build_aligned_type (TREE_TYPE (data_ref),
-   TYPE_ALIGN (elem_type));
+   align * BITS_PER_UNIT);
  vect_copy_ref_info (data_ref, DR_REF (first_dr_info->dr));
  new_stmt = gimple_build_assign (data_ref, vec_oprnd);
  vect_finish_stmt_generation (vinfo, stmt_info, new_stmt, gsi);
@@ -9452,10 +9447,10 @@ vectorizable_load (vec_info *vinfo,
&& TREE_CODE (dataref_ptr) == SSA_NAME)
  set_ptr_info_alignment (get_ptr_info (dataref_ptr),
  align, misalign);
+   align = least_bit_hwi (misalign | align);
 
if (final_mask)
  {
-   align = least_bit_hwi (misalign | align);
tree ptr = build_int_cst (ref_type,
  align * BITS_PER_UNIT);
gcall *call
@@ -9472,7 +9467,6 @@ vectorizable_load (vec_info *vinfo,
  = vect_get_loop_len (loop_vinfo, loop_lens,
   vec_num * ncopies,
   vec_num * j + i);
-   align = least_bit_hwi (misalign | align);
tree ptr = build_int_cst (ref_type,
  align * BITS_PER_UNIT);
gcall *call
@@ -9548,14 +9542,10 @@ vectorizable_load (vec_info *vinfo,
  = fold_build2 (MEM_REF, ltype, dataref_ptr

Re: [PATCH v3 2/2] Generate offset adjusted operation for op_by_pieces operations

2021-04-29 Thread Richard Biener via Gcc-patches
On Tue, Apr 27, 2021 at 3:14 AM H.J. Lu  wrote:
>
> Add an overlap_op_by_pieces_p target hook for op_by_pieces operations
> between two areas of memory to generate one offset adjusted operation
> in the smallest integer mode for the remaining bytes on the last piece
> operation of a memory region to avoid doing more than one smaller
> operations.
>
> Pass the RTL information from the previous iteration to m_constfn in
> op_by_pieces operation so that builtin_memset_[read|gen]_str can
> generate the new RTL from the previous RTL.
>
> Tested on Linux/x86-64.

OK.

Thanks,
Richard.

> gcc/
>
> PR middl-end/90773
> * builtins.c (builtin_memcpy_read_str): Add a dummy argument.
> (builtin_strncpy_read_str): Likewise.
> (builtin_memset_read_str): Add an argument for the previous RTL
> information and generate the new RTL from the previous RTL info.
> (builtin_memset_gen_str): Likewise.
> * builtins.h (builtin_strncpy_read_str): Update the prototype.
> (builtin_memset_read_str): Likewise.
> * expr.c (by_pieces_ninsns): If targetm.overlap_op_by_pieces_p()
> returns true, round up size and alignment to the widest integer
> mode for maximum size.
> (pieces_addr::adjust): Add a pointer to by_pieces_prev argument
> and pass it to m_constfn.
> (op_by_pieces_d): Add m_push and m_overlap_op_by_pieces.
> (op_by_pieces_d::op_by_pieces_d): Add a bool argument to
> initialize m_push.  Initialize m_overlap_op_by_pieces with
> targetm.overlap_op_by_pieces_p ().
> (op_by_pieces_d::run): Pass the previous RTL information to
> pieces_addr::adjust and generate overlapping operations if
> m_overlap_op_by_pieces is true.
> (PUSHG_P): New.
> (move_by_pieces_d::move_by_pieces_d): Updated for op_by_pieces_d
> change.
> (store_by_pieces_d::store_by_pieces_d): Updated for op_by_pieces_d
> change.
> (can_store_by_pieces): Use by_pieces_constfn on constfun.
> (store_by_pieces): Use by_pieces_constfn on constfun.  Updated
> for op_by_pieces_d change.
> (clear_by_pieces_1): Add a dummy argument.
> (clear_by_pieces): Updated for op_by_pieces_d change.
> (compare_by_pieces_d::compare_by_pieces_d): Likewise.
> (string_cst_read_str): Add a dummy argument.
> * expr.h (by_pieces_constfn): Add a dummy argument.
> (by_pieces_prev): New.
> * target.def (overlap_op_by_pieces_p): New target hook.
> * config/i386/i386.c (TARGET_OVERLAP_OP_BY_PIECES_P): New.
> * doc/tm.texi.in: Add TARGET_OVERLAP_OP_BY_PIECES_P.
> * doc/tm.texi: Regenerated.
>
> gcc/testsuite/
>
> PR middl-end/90773
> * g++.dg/pr90773-1.h: New test.
> * g++.dg/pr90773-1a.C: Likewise.
> * g++.dg/pr90773-1b.C: Likewise.
> * g++.dg/pr90773-1c.C: Likewise.
> * g++.dg/pr90773-1d.C: Likewise.
> * gcc.target/i386/pr90773-1.c: Likewise.
> * gcc.target/i386/pr90773-2.c: Likewise.
> * gcc.target/i386/pr90773-3.c: Likewise.
> * gcc.target/i386/pr90773-4.c: Likewise.
> * gcc.target/i386/pr90773-5.c: Likewise.
> * gcc.target/i386/pr90773-6.c: Likewise.
> * gcc.target/i386/pr90773-7.c: Likewise.
> * gcc.target/i386/pr90773-8.c: Likewise.
> * gcc.target/i386/pr90773-9.c: Likewise.
> * gcc.target/i386/pr90773-10.c: Likewise.
> * gcc.target/i386/pr90773-11.c: Likewise.
> * gcc.target/i386/pr90773-12.c: Likewise.
> * gcc.target/i386/pr90773-13.c: Likewise.
> * gcc.target/i386/pr90773-14.c: Likewise.
> ---
>  gcc/builtins.c |  36 +--
>  gcc/builtins.h |   6 +-
>  gcc/config/i386/i386.c |   3 +
>  gcc/doc/tm.texi|   7 ++
>  gcc/doc/tm.texi.in |   2 +
>  gcc/expr.c | 105 +
>  gcc/expr.h |  10 +-
>  gcc/target.def |   9 ++
>  gcc/testsuite/g++.dg/pr90773-1.h   |  14 +++
>  gcc/testsuite/g++.dg/pr90773-1a.C  |  13 +++
>  gcc/testsuite/g++.dg/pr90773-1b.C  |   5 +
>  gcc/testsuite/g++.dg/pr90773-1c.C  |   5 +
>  gcc/testsuite/g++.dg/pr90773-1d.C  |  19 
>  gcc/testsuite/gcc.target/i386/pr90773-1.c  |  17 
>  gcc/testsuite/gcc.target/i386/pr90773-10.c |  13 +++
>  gcc/testsuite/gcc.target/i386/pr90773-11.c |  13 +++
>  gcc/testsuite/gcc.target/i386/pr90773-12.c |  11 +++
>  gcc/testsuite/gcc.target/i386/pr90773-13.c |  11 +++
>  gcc/testsuite/gcc.target/i386/pr90773-14.c |  13 +++
>  gcc/testsuite/gcc.target/i386/pr90773-2.c  |  20 
>  gcc/testsuite/gcc.target/i386/pr90773-3.c  |  23 +
>  gcc/testsuite/gcc.target/i386/pr90773-4.c  |  13 +++
>  gcc/testsuite/gcc.ta

Re: [PATCH V7 0/7] Support for the CTF and BTF debug formats

2021-04-29 Thread Richard Biener via Gcc-patches
On Mon, Apr 19, 2021 at 7:30 PM Jose E. Marchesi via Gcc-patches
 wrote:
>
> [Changes from V6:
> - Rebased to today's master.
> - A GC related regression introduced in V5 has been fixed. This
>   regression also uncovered a related bug that has been also fixed in
>   this version.  Basically ctfc_types and ctfc_vars were being
>   incorrectly collected and this was uncovered by the fact V6 moved
>   the call of ctf_finalize from dwarf2out_early_finish to
>   dwarf2out_finish.

Note that this might end up a bad change since with LTO dwarf2out_finish
is run at LTRANS time where the relation to original TUs is lost and
types and declarations are no longer easily accessible.  Of course the
advantage is that you do not need a vehicle to transfer CTF info from
compile to link stage.

> - The patch `dwarf: new dwarf_debuginfo_p predicate' has been approved,
>   but not yet applied upstream.
> - This new version of the patch series is available in
>   https://github.com/oracle/gcc branch oracle/ctf-v7]
>
> Hi people!
>
> Last year we submitted a first patch series introducing support for
> the CTF debugging format in GCC [1].  We got a lot of feedback that
> prompted us to change the approach used to generate the debug info,
> and this patch series is the result of that.
>
> This series also add support for the BTF debug format, which is needed
> by the BPF backend (more on this below.)
>
> This implementation works, but there are several points that need
> discussion and agreement with the upstream community, as they impact
> the way debugging options work.  We are also proposing a way to add
> additional debugging formats in the future.  See below for more
> details.
>
> Finally, a patch makes the BPF GCC backend to use the DWARF debug
> hooks in order to make -gbtf available to it.
>
> [1] https://gcc.gnu.org/legacy-ml/gcc-patches/2019-05/msg01297.html
>
> About CTF
> =
>
> CTF is a debugging format designed in order to express C types in a
> very compact way.  The key is compactness and simplicity.  For more
> information see:
>
> - CTF specification
>   http://www.esperi.org.uk/~oranix/ctf/ctf-spec.pdf
>
> - Compact C-Type support in the GNU toolchain (talk + slides)
>   https://linuxplumbersconf.org/event/4/contributions/396/
>
> - On type de-duplication in CTF (talk + slides)
>   https://linuxplumbersconf.org/event/7/contributions/725/
>
> About BTF
> =
>
> BTF is a debugging format, similar to CTF, that is used in the Linux
> kernel as the debugging format for BPF programs.  From the kernel
> documentation:
>
> "BTF (BPF Type Format) is the metadata format which encodes the debug
>  info related to BPF program/map. The name BTF was used initially to
>  describe data types. The BTF was later extended to include function
>  info for defined subroutines, and line info for source/line
>  information."
>
> Supporting BTF in GCC is important because compiled BPF programs
> (which GCC supports as a target) require the type information in order
> to be loaded and run in diverse kernel versions.  This mechanism is
> known as CO-RE (compile-once, run-everywhere) and is described in the
> "Update of the BPF support in the GNU Toolchain" talk mentioned below.
>
> The BTF is documented in the Linux kernel documentation tree:
> - linux/Documentation/bpf/btf.rst
>
> CTF in the GNU Toolchain
> 
>
> During the last year we have been working in adding support for CTF to
> several components of the GNU toolchain:
>
> - binutils support is already upstream.  It supports linking objects
>   with CTF information with full type de-duplication.
>
> - GDB support is to be sent upstream very shortly.  It makes the
>   debugger capable to use the CTF information whenever available.
>   This is useful in cases where DWARF has been stripped out but CTF is
>   kept.
>
> - GCC support is being discussed and submitted in this series.
>
> Overview of the Implementation
> ==
>
>   dwarf2out.c
>
> The enabled debug formats are hooked in dwarf2out_early_finish.
>
>   dwarf2int.h
>
> Internal interface that exports a few functions and data types
> defined in dwarf2out.c.
>
>   dwarf2ctf.c
>
> Code that tranform the internal GCC DWARF DIEs into CTF container
> structures.  This file uses the dwarf2int.h interface.
>
>   ctfc.c
>   ctfc.h
>
> These two files implement the "CTF container", which is shared
> among CTF and BTF, due to the many similarities between both
> formats.
>
>   ctfout.c
>
> Code that emits assembler with the .ctf section data, from the CTF
> container.
>
>   btfout.c
>
> Code that emits assembler with the .BTF section data, from the CTF
> container.
>
> From debug hooks to debug formats
> =
>
> Our first attempt in adding CTF to GCC used the obvious approach of
> adding a new set of debug hooks as defined in gcc/debug.h.
>
> During our first interaction with the upstream commun

Re: [PATCH V7 1/7] dwarf: add a dwarf2int.h internal interface

2021-04-29 Thread Richard Biener via Gcc-patches
On Mon, Apr 19, 2021 at 7:31 PM Jose E. Marchesi via Gcc-patches
 wrote:
>
> This patch introduces a dwarf2int.h header, to be used by code that
> needs access to the internal DIE structures and their attributes.
>
> The following functions which were previously defined as static in
> dwarf2out.c are now non-static, and extern prototypes for them have
> been added to dwarf2int.h:
>
> - get_AT
> - AT_int
> - get_AT_ref
> - get_AT_string
> - get_AT_class
> - AT_unsigned
> - get_AT_unsigned
> - get_AT_flag
> - add_name_attribute
> - new_die_raw
> - base_type_die
> - lookup_decl_die
> - get_AT_file
>
> Note how this patch doens't change the names of these functions to
> avoid a massive renaming in dwarf2out.c, but n the future we probably
> want these functions to sport a dw_* prefix.

Or maybe namespaces to the rescue?  We can do use dw; in dwarf2out
to avoid the renaming.

OK unless others disagree.

Richard.

> Also, some type definitions have been moved from dwarf2out.c to
> dwarf2int.h:
>
> - dw_attr_node
> - struct dwarf_file_data
>
> Finally, three new accessor functions have been added to dwarf2out.c
> with prototypes in dwarf2int.h:
>
> - dw_get_die_child
> - dw_get_die_sib
> - dw_get_die_tag
>
> 2021-04-14  Jose E. Marchesi  
>
> * dwarf2int.h: New file.
> * dwarf2out.c (get_AT): Function is no longer static.
> (get_AT_string): Likewise.
> (get_AT_flag): Likewise.
> (get_AT_unsigned): Likewise.
> (get_AT_ref): Likewise.
> (new_die_raw): Likewise.
> (lookup_decl_die): Likewise.
> (base_type_die): Likewise.
> (add_name_attribute): Likewise.
> (dw_get_die_tag): New function.
> (dw_get_die_child): Likewise.
> (dw_get_die_sib): Likewise.
> Include dwarf2int.h.
> * gengtype.c: add dwarf2int.h to open_base_files.
> * Makefile.in (GTFILES): Add dwarf2int.h.
> ---
>  gcc/Makefile.in |  1 +
>  gcc/dwarf2int.h | 67 +
>  gcc/dwarf2out.c | 79 -
>  gcc/gengtype.c  |  6 ++--
>  4 files changed, 109 insertions(+), 44 deletions(-)
>  create mode 100644 gcc/dwarf2int.h
>
> diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> index 8a5fb3fd99c..e464e8c65c5 100644
> --- a/gcc/Makefile.in
> +++ b/gcc/Makefile.in
> @@ -2653,6 +2653,7 @@ GTFILES = $(CPPLIB_H) $(srcdir)/input.h 
> $(srcdir)/coretypes.h \
>$(srcdir)/ipa-modref.h $(srcdir)/ipa-modref.c \
>$(srcdir)/ipa-modref-tree.h \
>$(srcdir)/signop.h \
> +  $(srcdir)/dwarf2int.h \
>$(srcdir)/dwarf2out.h \
>$(srcdir)/dwarf2asm.c \
>$(srcdir)/dwarf2cfi.c \
> diff --git a/gcc/dwarf2int.h b/gcc/dwarf2int.h
> new file mode 100644
> index 000..f49f51d957b
> --- /dev/null
> +++ b/gcc/dwarf2int.h
> @@ -0,0 +1,67 @@
> +/* Prototypes for functions manipulating DWARF2 DIEs.
> +   Copyright (C) 2021 Free Software Foundation, Inc.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 3, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +.  */
> +
> +/* This file contains prototypes for functions defined in dwarf2out.c.  It is
> +   intended to be included in source files that need some internal knowledge 
> of
> +   the GCC dwarf structures.  */
> +
> +#ifndef GCC_DWARF2INT_H
> +#define GCC_DWARF2INT_H 1
> +
> +/* Each DIE attribute has a field specifying the attribute kind,
> +   a link to the next attribute in the chain, and an attribute value.
> +   Attributes are typically linked below the DIE they modify.  */
> +
> +typedef struct GTY(()) dw_attr_struct {
> +  enum dwarf_attribute dw_attr;
> +  dw_val_node dw_attr_val;
> +}
> +dw_attr_node;
> +
> +extern dw_attr_node *get_AT (dw_die_ref, enum dwarf_attribute);
> +extern HOST_WIDE_INT AT_int (dw_attr_node *);
> +extern unsigned HOST_WIDE_INT AT_unsigned (dw_attr_node *a);
> +extern dw_die_ref get_AT_ref (dw_die_ref, enum dwarf_attribute);
> +extern const char *get_AT_string (dw_die_ref, enum dwarf_attribute);
> +extern enum dw_val_class AT_class (dw_attr_node *);
> +extern unsigned HOST_WIDE_INT AT_unsigned (dw_attr_node *);
> +extern unsigned get_AT_unsigned (dw_die_ref, enum dwarf_attribute);
> +extern int get_AT_flag (dw_die_ref, enum dwarf_attribute);
> +
> +extern void add_name_attribute (dw_die_ref, const char *);
> +
> +extern dw_die_ref new_die_raw (enum dwarf_tag);
> +extern dw_die_ref base_type_die (tree, bool);
> +
> +extern dw_die_r

Re: [PATCH V7 2/7] dwarf: new dwarf_debuginfo_p predicate

2021-04-29 Thread Richard Biener via Gcc-patches
On Mon, Apr 19, 2021 at 7:32 PM Jose E. Marchesi via Gcc-patches
 wrote:
>
> This patch introduces a dwarf_debuginfo_p predicate that abstracts and
> replaces complex checks on write_symbols.

I've heard you're considering more changes in this area but the patch would
be OK as-is with me as well.

Richard.

> 2021-04-14  Indu Bhagat  
>
> gcc/ChangeLog
>
> * flags.h (dwarf_debuginfo_p): New function declaration.
> * opts.c (dwarf_debuginfo_p): New function definition.
> * config/c6x/c6x.c (c6x_output_file_unwind): Likewise.
> * dwarf2cfi.c (cfi_label_required_p): Likewise.
> (dwarf2out_do_frame): Likewise.
> * final.c (dwarf2_debug_info_emitted_p): Likewise.
> (final_scan_insn_1): Likewise.
> * targhooks.c (default_debug_unwind_info): Likewise.
> * toplev.c (process_options): Likewise.
>
> gcc/c-family/ChangeLog
>
> * c-lex.c (init_c_lex): Use dwarf_debuginfo_p.
> ---
>  gcc/c-family/c-lex.c |  4 ++--
>  gcc/config/c6x/c6x.c |  3 +--
>  gcc/dwarf2cfi.c  |  9 -
>  gcc/final.c  | 15 ++-
>  gcc/flags.h  |  3 +++
>  gcc/opts.c   |  8 
>  gcc/targhooks.c  |  2 +-
>  gcc/toplev.c |  6 ++
>  8 files changed, 27 insertions(+), 23 deletions(-)
>
> diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
> index 6374b72ed2d..5174b22c303 100644
> --- a/gcc/c-family/c-lex.c
> +++ b/gcc/c-family/c-lex.c
> @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "stor-layout.h"
>  #include "c-pragma.h"
>  #include "debug.h"
> +#include "flags.h"
>  #include "file-prefix-map.h" /* remap_macro_filename()  */
>  #include "langhooks.h"
>  #include "attribs.h"
> @@ -87,8 +88,7 @@ init_c_lex (void)
>
>/* Set the debug callbacks if we can use them.  */
>if ((debug_info_level == DINFO_LEVEL_VERBOSE
> -   && (write_symbols == DWARF2_DEBUG
> -  || write_symbols == VMS_AND_DWARF2_DEBUG))
> +   && dwarf_debuginfo_p ())
>|| flag_dump_go_spec != NULL)
>  {
>cb->define = cb_define;
> diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
> index f9ad1e5f6c5..a10e2f8d662 100644
> --- a/gcc/config/c6x/c6x.c
> +++ b/gcc/config/c6x/c6x.c
> @@ -439,8 +439,7 @@ c6x_output_file_unwind (FILE * f)
>  {
>if (flag_unwind_tables || flag_exceptions)
> {
> - if (write_symbols == DWARF2_DEBUG
> - || write_symbols == VMS_AND_DWARF2_DEBUG)
> + if (dwarf_debuginfo_p ())
> asm_fprintf (f, "\t.cfi_sections .debug_frame, .c6xabi.exidx\n");
>   else
> asm_fprintf (f, "\t.cfi_sections .c6xabi.exidx\n");
> diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
> index 362ff3fdac2..c27ac1960b0 100644
> --- a/gcc/dwarf2cfi.c
> +++ b/gcc/dwarf2cfi.c
> @@ -39,7 +39,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "expr.h"  /* init_return_column_size */
>  #include "output.h"/* asm_out_file */
>  #include "debug.h" /* dwarf2out_do_frame, dwarf2out_do_cfi_asm */
> -
> +#include "flags.h" /* dwarf_debuginfo_p */
>
>  /* ??? Poison these here until it can be done generically.  They've been
> totally replaced in this file; make sure it stays that way.  */
> @@ -2289,8 +2289,7 @@ cfi_label_required_p (dw_cfi_ref cfi)
>
>if (dwarf_version == 2
>&& debug_info_level > DINFO_LEVEL_TERSE
> -  && (write_symbols == DWARF2_DEBUG
> - || write_symbols == VMS_AND_DWARF2_DEBUG))
> +  && dwarf_debuginfo_p ())
>  {
>switch (cfi->dw_cfi_opc)
> {
> @@ -3557,9 +3556,9 @@ bool
>  dwarf2out_do_frame (void)
>  {
>/* We want to emit correct CFA location expressions or lists, so we
> - have to return true if we're going to output debug info, even if
> + have to return true if we're going to generate debug info, even if
>   we're not going to output frame or unwind info.  */
> -  if (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
> +  if (dwarf_debuginfo_p ())
>  return true;
>
>if (saved_do_cfi_asm > 0)
> diff --git a/gcc/final.c b/gcc/final.c
> index daae115fef5..cae692062b4 100644
> --- a/gcc/final.c
> +++ b/gcc/final.c
> @@ -1442,7 +1442,8 @@ asm_str_count (const char *templ)
>  static bool
>  dwarf2_debug_info_emitted_p (tree decl)
>  {
> -  if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG)
> +  /* When DWARF2 debug info is not generated internally.  */
> +  if (!dwarf_debuginfo_p ())
>  return false;
>
>if (DECL_IGNORED_P (decl))
> @@ -2330,10 +2331,8 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int 
> optimize_p ATTRIBUTE_UNUSED,
>   break;
>
> case NOTE_INSN_BLOCK_BEG:
> - if (debug_info_level == DINFO_LEVEL_NORMAL
> - || debug_info_level == DINFO_LEVEL_VERBOSE
> - || write_symbols == DWARF2_DEBUG
> - || write_symbols == VMS_AND_DWA

Re: rs6000: add support for powerpc64le-unknown-freebsd

2021-04-29 Thread Piotr Kubaj via Gcc-patches
Hello again,

sorry to reopen this issue, but one part was skipped. It was just now found 
out, because it doesn't cause build issues, but only runtime issues (GCC fails 
to build binaries):
/usr/local/bin/ld: /usr/local/lib/gcc10/libgcc_s.so: undefined reference to 
`.__udivmodti4'
/usr/local/bin/ld: /usr/local/lib/gcc10/libgcc_s.so: undefined reference to 
`.__ctzdi2'
/usr/local/bin/ld: /usr/local/lib/gcc10/libgcc_s.so: undefined reference to 
`.__parityti2'
/usr/local/bin/ld: /usr/local/lib/gcc10/libgcc_s.so: undefined reference to 
`.__enable_execute_stack'

Could you commit the following patch:
--- gcc/configure.orig  2021-04-29 10:19:44 UTC
+++ gcc/configure
@@ -29405,7 +29405,7 @@ $as_echo "#define HAVE_LD_PPC_GNU_ATTR_LONG_DOUBLE 1"
 esac

 case "$target:$tm_file" in
-  powerpc64-*-freebsd* | powerpc64*-*-linux* | 
powerpc*-*-linux*rs6000/biarch64.h*)
+  powerpc64*-*-freebsd* | powerpc64*-*-linux* | 
powerpc*-*-linux*rs6000/biarch64.h*)
   case "$target" in
  *le-*-linux*)
  emul_name="-melf64lppc"
--- gcc/configure.ac.orig   2021-04-29 11:22:30 UTC
+++ gcc/configure.ac
@@ -5871,7 +5871,7 @@ EOF
 esac

 case "$target:$tm_file" in
-  powerpc64-*-freebsd* | powerpc64*-*-linux* | 
powerpc*-*-linux*rs6000/biarch64.h*)
+  powerpc64*-*-freebsd* | powerpc64*-*-linux* | 
powerpc*-*-linux*rs6000/biarch64.h*)
   case "$target" in
  *le-*-linux*)
  emul_name="-melf64lppc"

Thanks,
Piotr Kubaj.

On 20-12-16 16:23:09, Segher Boessenkool wrote:
> On Tue, Dec 15, 2020 at 12:52:05AM +0100, Piotr Kubaj wrote:
> > Yes, there is, thanks for noticing that!
> > 
> > Fixed patch attached.
> 
> Hi!
> 
> Could you send this as plain text?  It now is quoted-printable, which is
> really hard to handle.
> 
> Thanks!
> 
> Hrm, this is really short, I'll just try to fix it by hand...  Wish me
> luck :-)
> 
> 
> Segher

-- 


signature.asc
Description: PGP signature


Re: [PATCH] c++: Substitute into function parms in lexical order [PR96560]

2021-04-29 Thread Patrick Palka via Gcc-patches
On Wed, 28 Apr 2021, Jason Merrill wrote:

> On 4/28/21 2:24 PM, Patrick Palka wrote:
> > This makes tsubst_arg_types substitute into a function's parameter types
> > in left-to-right order instead of right-to-left order, in accordance with
> > DR 1227.
> > 
> > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> > trunk?  [ diff generated with -w to hide noisy whitespace changes ]
> 
> OK. We'll still substitute lambda default args in reverse order, but that
> shouldn't happen in sfinae context, so that shouldn't be a problem.  Maybe add
> an assert (complain & tf_error) in the lambda case?

Apparently cpp2a/lambda-uneval2.C trips over such an assert during
deduction for:

  template 
  auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t));

which makes sense, I suppose.

It looks like we can just move up the default argument processing to
before the recursive call to tsubst_arg_types, as in the below.
Bootstrapped and regtested on x86_64-pc-linux-gnu.

BTW, now that LAMBDA_EXPR has LAMBDA_EXPR_REGEN_INFO I think we have
enough information to defer substituting into lambda default arguments
until they're actually needed.  Would that be something to look into as
a followup patch?

-- >8 --

Subject: [PATCH] c++: Substitute into function parms in lexical order
 [PR96560]

This makes tsubst_arg_types substitute into a function's parameter types
in left-to-right order instead of right-to-left order, in accordance with
DR 1227.

gcc/cp/ChangeLog:

DR 1227
PR c++/96560
* pt.c (tsubst_arg_types): Rearrange so that we substitute into
TYPE_ARG_TYPES in forward order while short circuiting
appropriately.  Adjust formatting.

gcc/testsuite/ChangeLog:

DR 1227
PR c++/96560
* g++.dg/template/sfinae-dr1227.C: New test.
---
 gcc/cp/pt.c   | 51 ++-
 gcc/testsuite/g++.dg/template/sfinae-dr1227.C | 23 +
 2 files changed, 51 insertions(+), 23 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/sfinae-dr1227.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index eaf46659f85..e6d65595e2f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -15068,20 +15068,13 @@ tsubst_arg_types (tree arg_types,
  tsubst_flags_t complain,
  tree in_decl)
 {
-  tree remaining_arg_types;
   tree type = NULL_TREE;
-  int i = 1;
+  int len = 1;
   tree expanded_args = NULL_TREE;
-  tree default_arg;
 
   if (!arg_types || arg_types == void_list_node || arg_types == end)
 return arg_types;
 
-  remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types),
- args, end, complain, in_decl);
-  if (remaining_arg_types == error_mark_node)
-return error_mark_node;
-
   if (PACK_EXPANSION_P (TREE_VALUE (arg_types)))
 {
   /* For a pack expansion, perform substitution on the
@@ -15092,7 +15085,7 @@ tsubst_arg_types (tree arg_types,
 
   if (TREE_CODE (expanded_args) == TREE_VEC)
 /* So that we'll spin through the parameters, one by one.  */
-i = TREE_VEC_LENGTH (expanded_args);
+   len = TREE_VEC_LENGTH (expanded_args);
   else
 {
   /* We only partially substituted into the parameter
@@ -15101,14 +15094,15 @@ tsubst_arg_types (tree arg_types,
   expanded_args = NULL_TREE;
 }
 }
+  else
+type = tsubst (TREE_VALUE (arg_types), args, complain, in_decl);
 
-  while (i > 0) {
---i;
-
+  /* Check if a substituted type is erroneous before substituting into
+ the rest of the chain.  */
+  for (int i = 0; i < len; i++)
+{
   if (expanded_args)
type = TREE_VEC_ELT (expanded_args, i);
-else if (!type)
-  type = tsubst (TREE_VALUE (arg_types), args, complain, in_decl);
 
   if (type == error_mark_node)
return error_mark_node;
@@ -15122,15 +15116,12 @@ tsubst_arg_types (tree arg_types,
}
  return error_mark_node;
}
-
-/* Do array-to-pointer, function-to-pointer conversion, and ignore
-   top-level qualifiers as required.  */
-type = cv_unqualified (type_decays_to (type));
+}
 
   /* We do not substitute into default arguments here.  The standard
  mandates that they be instantiated only when needed, which is
  done in build_over_call.  */
-default_arg = TREE_PURPOSE (arg_types);
+  tree default_arg = TREE_PURPOSE (arg_types);
 
   /* Except that we do substitute default arguments under tsubst_lambda_expr,
  since the new op() won't have any associated template arguments for us
@@ -15139,20 +15130,34 @@ tsubst_arg_types (tree arg_types,
 default_arg = tsubst_copy_and_build (default_arg, args, complain, in_decl,
 false/*fn*/, false/*constexpr*/);
 
+  tree remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types),
+  args, end, complain, in_decl);
+  if (remaining_arg_ty

[SPARC] Small housekeeping work

2021-04-29 Thread Eric Botcazou
Tested on SPARC/Solaris and SPARC64/Linux, applied on the mainline.


2021-04-29  Eric Botcazou  

* config/sparc/sparc.c (gen_load_pcrel_sym): Delete.
(load_got_register): Do the PIC dance here.
(sparc_legitimize_tls_address): Simplify.
(sparc_emit_probe_stack_range): Likewise.
(sparc32_initialize_trampoline): Likewise.
(sparc64_initialize_trampoline): Likewise.
* config/sparc/sparc.md (load_pcrel_sym): Add @ marker.
(probe_stack_range): Likewise.
(flush): Likewise.
(tgd_hi22): Likewise.
(tgd_lo10): Likewise.
(tgd_add): Likewise.
(tgd_call): Likewise.
(tldm_hi22): Likewise.
(tldm_lo10): Likewise.
(tldm_add): Likewise.
(tldm_call): Likewise.
(tldo_hix22): Likewise.
(tldo_lox10): Likewise.
(tldo_add): Likewise.
(tie_hi22): Likewise.
(tie_lo10): Likewise.
(tie_add): Likewise.
(tle_hix22): Likewise.
(tle_lox10): Likewise.
(stack_protect_setsi): Rename to...
(stack_protect_set32): ...this.
(stack_protect_setdi): Rename to...
(stack_protect_set64): ...this.
(stack_protect_set): Adjust calls to above.
(stack_protect_testsi): Rename to...
(stack_protect_test32): ...this.
(stack_protect_testdi): Rename to...
(stack_protect_test64): ...this.
(stack_protect_test): Adjust calls to above.

-- 
Eric Botcazou
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 42ba415255c..3b4d41630f3 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -4213,26 +4213,7 @@ sparc_got (void)
   return got_symbol_rtx;
 }
 
-/* Wrapper around the load_pcrel_sym{si,di} patterns.  */
-
-static rtx
-gen_load_pcrel_sym (rtx op0, rtx op1, rtx op2)
-{
-  int orig_flag_pic = flag_pic;
-  rtx insn;
-
-  /* The load_pcrel_sym{si,di} patterns require absolute addressing.  */
-  flag_pic = 0;
-  if (TARGET_ARCH64)
-insn = gen_load_pcrel_symdi (op0, op1, op2, GEN_INT (REGNO (op0)));
-  else
-insn = gen_load_pcrel_symsi (op0, op1, op2, GEN_INT (REGNO (op0)));
-  flag_pic = orig_flag_pic;
-
-  return insn;
-}
-
-/* Output the load_pcrel_sym{si,di} patterns.  */
+/* Output the load_pcrel_sym pattern.  */
 
 const char *
 output_load_pcrel_sym (rtx *operands)
@@ -4299,8 +4280,15 @@ load_got_register (void)
 	  got_helper_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
 	}
 
-  insn
-	= gen_load_pcrel_sym (got_register_rtx, sparc_got (), got_helper_rtx);
+  /* The load_pcrel_sym{si,di} patterns require absolute addressing.  */
+  const int orig_flag_pic = flag_pic;
+  flag_pic = 0;
+  insn = gen_load_pcrel_sym (Pmode,
+ got_register_rtx,
+ sparc_got (),
+ got_helper_rtx,
+ GEN_INT (GLOBAL_OFFSET_TABLE_REGNUM));
+  flag_pic = orig_flag_pic;
 }
 
   emit_insn (insn);
@@ -4680,22 +4668,11 @@ sparc_legitimize_tls_address (rtx addr)
 	ret = gen_reg_rtx (Pmode);
 	o0 = gen_rtx_REG (Pmode, 8);
 	got = sparc_tls_got ();
-	if (TARGET_ARCH32)
-	  {
-	emit_insn (gen_tgd_hi22si (temp1, addr));
-	emit_insn (gen_tgd_lo10si (temp2, temp1, addr));
-	emit_insn (gen_tgd_addsi (o0, got, temp2, addr));
-	insn = emit_call_insn (gen_tgd_callsi (o0, sparc_tls_get_addr (),
-		   addr, const1_rtx));
-	  }
-	else
-	  {
-	emit_insn (gen_tgd_hi22di (temp1, addr));
-	emit_insn (gen_tgd_lo10di (temp2, temp1, addr));
-	emit_insn (gen_tgd_adddi (o0, got, temp2, addr));
-	insn = emit_call_insn (gen_tgd_calldi (o0, sparc_tls_get_addr (),
-		   addr, const1_rtx));
-	  }
+	emit_insn (gen_tgd_hi22 (Pmode, temp1, addr));
+	emit_insn (gen_tgd_lo10 (Pmode, temp2, temp1, addr));
+	emit_insn (gen_tgd_add (Pmode, o0, got, temp2, addr));
+	insn = emit_call_insn (gen_tgd_call (Pmode, o0, sparc_tls_get_addr (),
+	 addr, const1_rtx));
 	use_reg (&CALL_INSN_FUNCTION_USAGE (insn), o0);
 	RTL_CONST_CALL_P (insn) = 1;
 	insn = get_insns ();
@@ -4711,22 +4688,11 @@ sparc_legitimize_tls_address (rtx addr)
 	ret = gen_reg_rtx (Pmode);
 	o0 = gen_rtx_REG (Pmode, 8);
 	got = sparc_tls_got ();
-	if (TARGET_ARCH32)
-	  {
-	emit_insn (gen_tldm_hi22si (temp1));
-	emit_insn (gen_tldm_lo10si (temp2, temp1));
-	emit_insn (gen_tldm_addsi (o0, got, temp2));
-	insn = emit_call_insn (gen_tldm_callsi (o0, sparc_tls_get_addr (),
-		const1_rtx));
-	  }
-	else
-	  {
-	emit_insn (gen_tldm_hi22di (temp1));
-	emit_insn (gen_tldm_lo10di (temp2, temp1));
-	emit_insn (gen_tldm_adddi (o0, got, temp2));
-	insn = emit_call_insn (gen_tldm_calldi (o0, sparc_tls_get_addr (),
-		const1_rtx));
-	  }
+	emit_insn (gen_tldm_hi22 (Pmode, temp1));
+	emit_insn (gen_tldm_lo10 (Pmode, temp2, temp1));
+	emit_insn (gen_tldm_add (Pmode, o0, got, temp2));
+	insn = emit_call_insn (gen_tldm_call (Pmode, o0, sparc_tls_get_addr (),
+	  const1_rtx));
 	use_reg (&CALL_INSN_FUNCTION_USAGE 

Re: [PATCH 2/3] LTO plugin: use startswith function.

2021-04-29 Thread Richard Biener via Gcc-patches
On Wed, Apr 21, 2021 at 10:13 AM Martin Liska  wrote:
>

OK.

> lto-plugin/ChangeLog:
>
> * lto-plugin.c (LTO_SEGMENT_NAME): Remove.
> (LTO_SYMTAB_PREFIX): Likewise.
> (LTO_SYMTAB_PREFIX_LEN): Likewise.
> (LTO_SYMTAB_EXT_PREFIX): Likewise.
> (LTO_SYMTAB_EXT_PREFIX_LEN): Likewise.
> (LTO_LTO_PREFIX): Likewise.
> (LTO_LTO_PREFIX_LEN): Likewise.
> (OFFLOAD_SECTION): Likewise.
> (OFFLOAD_SECTION_LEN): Likewise.
> (startswith): New function.
> (all_symbols_read_handler): Use it.
> (process_symtab): Likewise.
> (process_symtab_extension): Likewise.
> (process_offload_section): Likewise.
> (process_option): Likewise.
> ---
>  lto-plugin/lto-plugin.c | 29 +
>  1 file changed, 13 insertions(+), 16 deletions(-)
>


Re: [PATCH] lto-wrapper: Use vec data type.

2021-04-29 Thread Richard Biener via Gcc-patches
On Wed, Apr 21, 2021 at 11:12 AM Martin Liška  wrote:
>
> Now living in the 21st century, we don't longer need using the following 
> tuple:
> cl_decoded_option **decoded_options,
>  unsigned int *decoded_options_count)
> but we can rather use a standard (our) vector.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> Ready to be installed?
> Thanks,
> Martin
>
> gcc/ChangeLog:
>
> * lto-wrapper.c (get_options_from_collect_gcc_options): Change
> return type.
> (append_option): Remove.
> (find_option): Rework to use the vector type.
> (remove_option): Remove.
> (merge_and_complain): Use vectors for cl_decoded_option data
> type arguments.
> (append_compiler_options): Likewise.
> (append_diag_options): Likewise.
> (append_linker_options): Likewise.
> (append_offload_options): Likewise.
> (compile_offload_image): Likewise.
> (compile_images_for_offload_targets): Likewise.
> (find_and_merge_options): Likewise.
> (run_gcc): Likewise.
> ---
>  gcc/lto-wrapper.c | 384 --
>  1 file changed, 165 insertions(+), 219 deletions(-)
>
> diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
> index 03a5922f8ea..5ccf729b249 100644
> --- a/gcc/lto-wrapper.c
> +++ b/gcc/lto-wrapper.c
> @@ -138,12 +138,12 @@ maybe_unlink (const char *file)
>  /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
> environment.  */
>
> -static void
> +static vec

bonus points for handling ownership transfer via returning an
auto_vec<> (not sure if possible, but maybe it is).

>  get_options_from_collect_gcc_options (const char *collect_gcc,
> - const char *collect_gcc_options,
> - struct cl_decoded_option 
> **decoded_options,
> - unsigned int *decoded_options_count)
> + const char *collect_gcc_options)
>  {
> +  cl_decoded_option *decoded_options;
> +  unsigned int decoded_options_count;
>struct obstack argv_obstack;
>const char **argv;
>int argc;
> @@ -156,57 +156,49 @@ get_options_from_collect_gcc_options (const char 
> *collect_gcc,
>argv = XOBFINISH (&argv_obstack, const char **);
>
>decode_cmdline_options_to_array (argc, (const char **)argv, CL_DRIVER,
> -  decoded_options, decoded_options_count);
> +  &decoded_options, &decoded_options_count);
> +  vec decoded;
> +  decoded.create (decoded_options_count);
> +  for (unsigned i = 0; i < decoded_options_count; ++i)
> +decoded.quick_push (decoded_options[i]);
> +  free (decoded_options);
> +
>obstack_free (&argv_obstack, NULL);
> +
> +  return decoded;
>  }
>
> -/* Append OPTION to the options array DECODED_OPTIONS with size
> -   DECODED_OPTIONS_COUNT.  */
> +/* Find option in OPTIONS based on OPT_INDEX.  NULL value is returned
> +   if the option is not present.  */
>
> -static void
> -append_option (struct cl_decoded_option **decoded_options,
> -  unsigned int *decoded_options_count,
> -  struct cl_decoded_option *option)
> +static cl_decoded_option *
> +find_option (vec &options, size_t opt_index)
>  {
> -  ++*decoded_options_count;
> -  *decoded_options
> -= (struct cl_decoded_option *)
> -   xrealloc (*decoded_options,
> - (*decoded_options_count
> -  * sizeof (struct cl_decoded_option)));
> -  memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
> - sizeof (struct cl_decoded_option));
> -}
> +  for (unsigned i = 0; i < options.length (); ++i)
> +if (options[i].opt_index == opt_index)
> +  return &options[i];

You're returning a pointer into the vector here...

> -/* Remove option number INDEX from DECODED_OPTIONS, update
> -   DECODED_OPTIONS_COUNT.  */
> +  return NULL;
> +}
>
> -static void
> -remove_option (struct cl_decoded_option **decoded_options,
> -  int index, unsigned int *decoded_options_count)
> +static cl_decoded_option *
> +find_option (vec &options, cl_decoded_option *option)
>  {
> -  --*decoded_options_count;
> -  memmove (&(*decoded_options)[index + 1],
> -  &(*decoded_options)[index],
> -  sizeof (struct cl_decoded_option)
> -  * (*decoded_options_count - index));
> +  return find_option (options, option->opt_index);
>  }
>
>  /* Try to merge and complain about options FDECODED_OPTIONS when applied
> ontop of DECODED_OPTIONS.  */
>
>  static void
> -merge_and_complain (struct cl_decoded_option **decoded_options,
> -   unsigned int *decoded_options_count,
> -   struct cl_decoded_option *fdecoded_options,
> -   unsigned int fdecoded_options_count,
> -   struct cl_decoded_option *decoded_cl_options,
> -   unsigned int deco

Re: [PATCH] c++: remove redundand NULL check.

2021-04-29 Thread Richard Biener via Gcc-patches
On Wed, Apr 21, 2021 at 11:19 AM Martin Liška  wrote:
>
> The check is redundant.
>
> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>
> Ready to be installed?

OK.

> Thanks,
> Martin
>
> gcc/cp/ChangeLog:
>
> PR c++/99616
> * decl.c (grokdeclarator): Remove redundant NULL check.
> ---
>  gcc/cp/decl.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
> index 8e8f37d060e..dc2c79997ee 100644
> --- a/gcc/cp/decl.c
> +++ b/gcc/cp/decl.c
> @@ -12244,7 +12244,7 @@ grokdeclarator (const cp_declarator *declarator,
>   int attr_flags;
>
>   attr_flags = 0;
> - if (declarator == NULL || declarator->kind == cdk_id)
> + if (declarator->kind == cdk_id)
> attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
>   if (declarator->kind == cdk_function)
> attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
> --
> 2.31.1
>


Re: [patch] Add parallelism support to gcov for MinGW platforms

2021-04-29 Thread Richard Biener via Gcc-patches
On Thu, Apr 29, 2021 at 1:20 PM Eric Botcazou  wrote:
>
> Hi,
>
> if you attempt a profiled bootstrap on the MinGW platforms with -jN, N > 1,
> it miserably fails because of profile mismatches all over the place, the
> reason being that gcov has no support for parallelism on these platforms.
>
> The attached patch adds it and, therefore, makes it possible to do a profiled
> bootstrap with -jN, N > 1, on these platforms.
>
> Tested on x86-64/Linux, x86-64/Windows and x86/Windows, OK for the mainline?

OK.

Thanks,
Richard.

>
> 2021-04-29  Eric Botcazou  
>
> libgcc/
> * libgcc/libgcov.h: For the target, define GCOV_LOCKED_WITH_LOCKING if
> __MSVCRT__ and, for the host, define it if HOST_HAS_LK_LOCK.
> * libgcov-driver.c: Add include directives if 
> GCOV_LOCKED_WITH_LOCKING.
> gcc/
> * configure.ac: Check for the presence of sys/locking.h header and for
> whether _LK_LOCK is supported by _locking.
> * configure: Regenerate.
> * config.in: Likewise.
> * gcov-io.h: Define GCOV_LOCKED_WITH_LOCKING if HOST_HAS_LK_LOCK.
> * gcov-io.c (gcov_open): Add support for GCOV_LOCKED_WITH_LOCKING.
> * system.h: Include  if HAVE_SYS_LOCKING_H.
>
> --
> Eric Botcazou


[committed][omp, simt] Handle alternative IV

2021-04-29 Thread Tom de Vries
On 4/22/21 1:46 PM, Tom de Vries wrote:
> On 12/17/20 5:46 PM, Tom de Vries wrote:
>> On 10/15/20 5:05 PM, Tom de Vries wrote:
>>> On 10/2/20 3:21 PM, Tom de Vries wrote:
 Hi,

 Consider the test-case libgomp.c/pr81778.c added in this commit, with
 this core loop (note: CANARY_SIZE set to 0 for simplicity):
 ...
   int s = 1;
   #pragma omp target simd
   for (int i = N - 1; i > -1; i -= s)
 a[i] = 1;
 ...
 which, given that N is 32, sets a[0..31] to 1.

 After omp-expand, this looks like:
 ...
:
   simduid.7 = .GOMP_SIMT_ENTER (simduid.7);
   .omp_simt.8 = .GOMP_SIMT_ENTER_ALLOC (simduid.7);
   D.3193 = -s;
   s.9 = s;
   D.3204 = .GOMP_SIMT_LANE ();
   D.3205 = -s.9;
   D.3206 = (int) D.3204;
   D.3207 = D.3205 * D.3206;
   i = D.3207 + 31;
   D.3209 = 0;
   D.3210 = -s.9;
   D.3211 = D.3210 - i;
   D.3210 = -s.9;
   D.3212 = D.3211 / D.3210;
   D.3213 = (unsigned int) D.3212;
   D.3213 = i >= 0 ? D.3213 : 0;

:
   if (D.3209 < D.3213)
 goto ; [87.50%]
   else
 goto ; [12.50%]

:
   a[i] = 1;
   D.3215 = -s.9;
   D.3219 = .GOMP_SIMT_VF ();
   D.3216 = (int) D.3219;
   D.3220 = D.3215 * D.3216;
   i = D.3220 + i;
   D.3209 = D.3209 + 1;
   goto ; [100.00%]
 ...

 On nvptx, the first time bb6 is executed, i is in the 0..31 range 
 (depending
 on the lane that is executing) at bb entry.

 So we have the following sequence:
 - a[0..31] is set to 1
 - i is updated to -32..-1
 - D.3209 is updated to 1 (being 0 initially)
 - bb19 is executed, and if condition (D.3209 < D.3213) == (1 < 32) 
 evaluates
   to true
 - bb6 is once more executed, which should not happen because all the 
 elements
   that needed to be handled were already handled.
 - consequently, elements that should not be written are written
 - with CANARY_SIZE == 0, we may run into a libgomp error:
   ...
   libgomp: cuCtxSynchronize error: an illegal memory access was encountered
   ...
   and with CANARY_SIZE unmodified, we run into:
   ...
   Expected 0, got 1 at base[-961]
   Aborted (core dumped)
   ...

 The cause of this is as follows:
 - because the step s is a variable rather than a constant, an alternative
   IV (D.3209 in our example) is generated in expand_omp_simd, and the
   loop condition is tested in terms of the alternative IV rather than
   the original IV (i in our example).
 - the SIMT code in expand_omp_simd works by modifying step and initial 
 value.
 - The initial value fd->loop.n1 is loaded into a variable n1, which is
   modified by the SIMT code and then used there-after.
 - The step fd->loop.step is loaded into a variable step, which is is 
 modified
   by the SIMT code, but afterwards there are uses of both step and
   fd->loop.step.
 - There are uses of fd->loop.step in the alternative IV handling code,
   which should use step instead.

 Fix this by introducing an additional variable orig_step, which is not
 modified by the SIMT code and replacing all remaining uses of fd->loop.step
 by either step or orig_step.

 Build on x86_64-linux with nvptx accelerator, tested libgomp.

 This fixes for-5.c and for-6.c FAILs I'm currently seeing on a quadro m1200
 with driver 450.66.

 OK for trunk?

>>>
> 
> Ping^3.
> 

Committed.

Thanks,
- Tom

 [omp, simt] Handle alternative IV

 gcc/ChangeLog:

 2020-10-02  Tom de Vries  

* omp-expand.c (expand_omp_simd): Add step_orig, and replace uses of
fd->loop.step by either step or orig_step.

 libgomp/ChangeLog:

 2020-10-02  Tom de Vries  

* testsuite/libgomp.c/pr81778.c: New test.

 ---
  gcc/omp-expand.c  | 11 
  libgomp/testsuite/libgomp.c/pr81778.c | 48 
 +++
  2 files changed, 54 insertions(+), 5 deletions(-)

 diff --git a/gcc/omp-expand.c b/gcc/omp-expand.c
 index 99cb4f9dda4..80e35ac0294 100644
 --- a/gcc/omp-expand.c
 +++ b/gcc/omp-expand.c
 @@ -6307,6 +6307,7 @@ expand_omp_simd (struct omp_region *region, struct 
 omp_for_data *fd)
n2 = OMP_CLAUSE_DECL (innerc);
  }
tree step = fd->loop.step;
 +  tree orig_step = step; /* May be different from step if is_simt.  */
  
bool is_simt = omp_find_clause (gimple_omp_for_clauses (fd->for_stmt),
  OMP_CLAUSE__SIMT_);
 @@ -6455,7 +6456,7 @@ expand_omp_simd (struct omp_region *region, struct 
 omp_for_data *fd)
tree altv = NULL_TREE, altn2 = NULL_TREE;
if (fd->collapse == 1
&& !broken_loop
 -  && TREE_CODE (fd->loops[

Re: [PATCH v2 09/21] libcc1: add more uses of 'deleter'

2021-04-29 Thread Jeff Law via Gcc-patches



On 4/27/2021 7:01 PM, Tom Tromey wrote:

This changes libcc1 to use the 'deleter' template in a few more
places.  The template and basic specializations are moved to a new
header, then some unmarshall functions are changed to use this code.
This change avoids the need to repeat cleanup code in the
unmarshallers.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* rpc.hh (deleter): Move template and some specializations to
deleter.hh.
(argument_wrapper): Use cc1_plugin::unique_ptr.
* marshall.cc (cc1_plugin::unmarshall): Use
cc1_plugin::unique_ptr.
* marshall-cp.hh (deleter): New specializations.
(unmarshall): Use cc1_plugin::unique_ptr.
* deleter.hh: New file.


OK

jeff



Re: [PATCH v2 10/21] libcc1: use unique_ptr more

2021-04-29 Thread Jeff Law via Gcc-patches



On 4/27/2021 7:01 PM, Tom Tromey wrote:

This changes libcc1 to use unique_ptr in a few more places, removing
some manual memory management.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcp1.cc (struct libcp1) : Use
unique_ptr.
(~libcp1): Remove.
(libcp1_compile, libcp1_set_triplet_regexp)
(libcp1_set_driver_filename): Update.
* libcc1.cc (struct libcc1) : Use
unique_ptr.
(~libcc1): Remove.
(libcc1_set_triplet_regexp, libcc1_set_driver_filename)
(libcc1_compile): Update.


OK

Jeff


Re: [PATCH v2 11/21] libcc1: unify compiler handling

2021-04-29 Thread Jeff Law via Gcc-patches



On 4/27/2021 7:01 PM, Tom Tromey wrote:

Both libcc1 plugins have nearly identical copies of code to find the
underlying compiler.  This seemed wasteful to me, so this patch
unifies the copies.

Two minor API changes were needed.

First, the old code used a back-link from the compiler object to the
plugin object to check the 'verbose' setting.  This patch adds a
'verbose' setting directly to the compiler object instead.

Second, the 'find' method implicitly knew which compiler base name
("gcc" or "g++") to use.  This patch makes this a parameter that is
passed in by the plugin.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcc1.cc (compiler, compiler_triplet_regexp)
(compiler_driver_filename): Remove.
(libcp1::libcp1): Update.
(make_regexp, libcp1::compiler::find)
(libcp1::compiler_triplet_regexp::find)
(libcp1::compiler_driver_filename::find): Remove.
(libcp1_set_verbose, libcp1_set_arguments)
(libcp1_set_triplet_regexp, libcp1_set_driver_filename): Update.
* libcc1.cc (compiler, compiler_triplet_regexp)
(compiler_driver_filename): Remove.
(libcc1::libcc1): Update.
(make_regexp, libcc1::compiler::find)
(libcc1::compiler_triplet_regexp::find)
(libcc1::compiler_driver_filename::find): Remove.
(libcc1_set_verbose, libcc1_set_arguments)
(libcc1_set_triplet_regexp, libcc1_set_driver_filename): Update.
* compiler.cc: New file.
* compiler.hh: New file.
* Makefile.in: Rebuild.
* Makefile.am (libcc1_la_SOURCES): Add compiler.hh, compiler.cc.


OK

Jeff



Re: [PATCH v2 14/21] libcc1: share basic context code

2021-04-29 Thread Jeff Law via Gcc-patches



On 4/27/2021 7:01 PM, Tom Tromey wrote:

Both plugins in libcc1 share a fair amount of boilerplate.  They both
share error-emission code, context management code, and tree GC code.
This patch unifies these two bodies of code, avoiding needless
duplication.

libcc1/ChangeLog
2021-04-27  Tom Tromey  

* libcc1plugin.cc: Move code to context.cc.
* libcp1plugin.cc: Move code to context.cc.
* context.hh: New file.
* context.cc: New file.
* Makefile.in: Rebuild.
* Makefile.am (AM_CPPFLAGS): Add more gcc flags.
(CPPFLAGS_FOR_C, CPPFLAGS_FOR_CXX): Update.
(libcc1plugin_la_SOURCES): Add context.hh, context.cc.
(libcp1plugin_la_SOURCES): Likewise.


OK

jeff



[PATCH 02/12] Allow generating pseudo register with specific alignment

2021-04-29 Thread H.J. Lu via Gcc-patches
gen_reg_rtx tracks stack alignment needed for pseudo registers so that
associated hard registers can be properly spilled onto stack.  But there
are cases where associated hard registers will never be spilled onto
stack.  gen_reg_rtx is changed to take an argument for register alignment
so that stack realignment can be avoided when not needed.

* emit-rtl.c (gen_reg_rtx): Add an argument for register
alignment and use it if it isn't zero.
* explow.c (force_reg): Add an argument for register alignment
and pass it to gen_reg_rtx.
* explow.h (force_reg): Add an argument for register alignment
and default it to 0.
* expr.h (convert_to_mode): Likewise.
(convert_modes): Likewise.
* expr.c (convert_to_mode): Add an argument for register
alignment and pass it to convert_modes.
(convert_modes): Add an argument for register alignment and
pass it to gen_reg_rtx.
---
 gcc/emit-rtl.c |  5 +++--
 gcc/explow.c   |  6 +++---
 gcc/explow.h   |  2 +-
 gcc/expr.c | 10 ++
 gcc/expr.h |  6 --
 gcc/rtl.h  |  2 +-
 6 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 07e908624a0..4accf851d23 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -1160,10 +1160,11 @@ subreg_memory_offset (const_rtx x)
This pseudo is assigned the next sequential register number.  */
 
 rtx
-gen_reg_rtx (machine_mode mode)
+gen_reg_rtx (machine_mode mode, unsigned int align)
 {
   rtx val;
-  unsigned int align = GET_MODE_ALIGNMENT (mode);
+  if (align == 0)
+align = GET_MODE_ALIGNMENT (mode);
 
   gcc_assert (can_create_pseudo_p ());
 
diff --git a/gcc/explow.c b/gcc/explow.c
index b6da277f689..c8673ce512d 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -663,7 +663,7 @@ copy_to_mode_reg (machine_mode mode, rtx x)
since we mark it as a "constant" register.  */
 
 rtx
-force_reg (machine_mode mode, rtx x)
+force_reg (machine_mode mode, rtx x, unsigned int reg_align)
 {
   rtx temp, set;
   rtx_insn *insn;
@@ -673,7 +673,7 @@ force_reg (machine_mode mode, rtx x)
 
   if (general_operand (x, mode))
 {
-  temp = gen_reg_rtx (mode);
+  temp = gen_reg_rtx (mode, reg_align);
   insn = emit_move_insn (temp, x);
 }
   else
@@ -683,7 +683,7 @@ force_reg (machine_mode mode, rtx x)
insn = get_last_insn ();
   else
{
- rtx temp2 = gen_reg_rtx (mode);
+ rtx temp2 = gen_reg_rtx (mode, reg_align);
  insn = emit_move_insn (temp2, temp);
  temp = temp2;
}
diff --git a/gcc/explow.h b/gcc/explow.h
index 698f2a2a21c..621cdd7d356 100644
--- a/gcc/explow.h
+++ b/gcc/explow.h
@@ -40,7 +40,7 @@ extern rtx copy_to_suggested_reg (rtx, rtx, machine_mode);
 
 /* Copy a value to a register if it isn't already a register.
Args are mode (in case value is a constant) and the value.  */
-extern rtx force_reg (machine_mode, rtx);
+extern rtx force_reg (machine_mode, rtx, unsigned int reg_align = 0);
 
 /* Return given rtx, copied into a new temp reg if it was in memory.  */
 extern rtx force_not_mem (rtx);
diff --git a/gcc/expr.c b/gcc/expr.c
index b4c110f8c17..42db4ddbe0a 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -658,9 +658,10 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp)
or by copying to a new temporary with conversion.  */
 
 rtx
-convert_to_mode (machine_mode mode, rtx x, int unsignedp)
+convert_to_mode (machine_mode mode, rtx x, int unsignedp,
+unsigned int reg_align)
 {
-  return convert_modes (mode, VOIDmode, x, unsignedp);
+  return convert_modes (mode, VOIDmode, x, unsignedp, reg_align);
 }
 
 /* Return an rtx for a value that would result
@@ -674,7 +675,8 @@ convert_to_mode (machine_mode mode, rtx x, int unsignedp)
You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode.  */
 
 rtx
-convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
+convert_modes (machine_mode mode, machine_mode oldmode, rtx x,
+  int unsignedp, unsigned int reg_align)
 {
   rtx temp;
   scalar_int_mode int_mode;
@@ -734,7 +736,7 @@ convert_modes (machine_mode mode, machine_mode oldmode, rtx 
x, int unsignedp)
   return simplify_gen_subreg (mode, x, oldmode, 0);
 }
 
-  temp = gen_reg_rtx (mode);
+  temp = gen_reg_rtx (mode, reg_align);
   convert_move (temp, x, unsignedp);
   return temp;
 }
diff --git a/gcc/expr.h b/gcc/expr.h
index 9a2736f69fa..2b06da1a889 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -66,10 +66,12 @@ extern void init_expr (void);
 extern void convert_move (rtx, rtx, int);
 
 /* Convert an rtx to specified machine mode and return the result.  */
-extern rtx convert_to_mode (machine_mode, rtx, int);
+extern rtx convert_to_mode (machine_mode, rtx, int,
+   unsigned int reg_align = 0);
 
 /* Convert an rtx to MODE from OLDMODE and return the result.  */
-extern rtx convert_modes (machine_mode, machine_mode, rtx

[PATCH 00/12] Allow TImode/OImode/XImode in op_by_pieces operations

2021-04-29 Thread H.J. Lu via Gcc-patches
The maximum size of the current op_by_pieces operations are limited by 
MAX_FIXED_MODE_SIZE which is an integer expression for the size in bits
of the largest integer machine mode that should actually be used.  But
a target can use TImode/OImode/XImode, which can be larger than
MAX_FIXED_MODE_SIZE, to perform op_by_pieces operations.  Here are a
set of patches to remove such limitation so that TImode/OImode/XImode
can be used for piecewise move and store:

1. Remove MAX_FIXED_MODE_SIZE limit in alignment_for_piecewise_move.
2. Allow generating pseudo register with specific alignment for hard
registers which will never be spilled onto stack to avoid re-aligning
stack.
3. Add TARGET_READ_MEMSET_VALUE and TARGET_GEN_MEMSET_VALUE to support
target instructions to duplicate QImode value to TImode/OImode/XImode
value for memmset.
4. x86: Avoid stack realignment when copying data
5. x86: Remov MAX_BITSIZE_MODE_ANY_INT.  Only x86 backend defines it.
6. x86: Use TImode/OImode/XImode integers for piecewise move and store.
7. x86: Add tests for TImode/OImode/XImode for piecewise move and store.
8. x86: Adjust existing tests.

On x86-64, SPEC CPU 2017 performance impact is neutral.  Glibc code size
differences with -O2 build are:

 Before After
libc.so 18707181870222
ld.so185120 184984

Some code sequence differences in libc.so are:

Before   
After
mov0x10(%rsp),%edx  mov
0x10(%rsp),%edx
mov%edx,(%rax)  mov
%edx,(%rax)
movzwl 0x14(%rsp),%edx| mov
0x13(%rsp),%edx
mov%dx,0x4(%rax)  | mov
%edx,0x3(%rax)
movzbl 0x16(%rsp),%edx<
mov%dl,0x6(%rax)  <
add%rcx,%raxadd
%rcx,%rax
ret ret

movdqu (%rsi),%xmm1   | movdqu 
(%rcx),%xmm1
mov%rdi,0x20(%rsp)  mov
%rdi,0x20(%rsp)
movups %xmm1,(%rax) movups 
%xmm1,(%rax)
mov0x10(%rsi),%rdx| movdqu 
0xc(%rcx),%xmm2
mov%rdx,0x10(%rax)| movups 
%xmm2,0xc(%rax)
mov0x18(%rsi),%edx| mov
%rax,(%r14,%rdx,8)
mov%edx,0x18(%rax)| add
$0x1,%rdx
mov%rax,(%r14,%rcx,8) | cmp
%r8,%rdx
add$0x1,%rcx  | je 
<__resolv_conf_allocate+0x22d>
cmp%r8,%rcx   | mov
0x20(%rsp),%rsi
je <__resolv_conf_allocate+0x22f> | mov
(%r9,%rdx,8),%rcx

test   %eax,%eaxtest   
%eax,%eax
mov$0xff,%eax   mov
$0xff,%eax
cmove  %eax,%ebxcmove  
%eax,%ebx
movzbl %bl,%ecx   | movd   
%ebx,%xmm0
mov%ebx,0xc(%rsp)   mov
%ebx,0xc(%rsp)
mov%rcx,%rax  | 
punpcklbw %xmm0,%xmm0
mov%rcx,%rsi  | 
punpcklwd %xmm0,%xmm0
mul%rdi   | pshufd 
$0x0,%xmm0,%xmm0
imul   %rdi,%rsi  | movups 
%xmm0,0x50(%r12)
mov%rax,0x50(%r12)| movups 
%xmm0,0x60(%r12)
mov%rcx,%rax  | movups 
%xmm0,0x70(%r12)
add%rdx,%rsi  | movups 
%xmm0,0x80(%r12)
mul%rdi   | movups 
%xmm0,0x90(%r12)
mov%rsi,0x58(%r12)| movups 
%xmm0,0xa0(%r12)
mov%rsi,0x68(%r12)| movups 
%xmm0,0xb0(%r12)
mov%rax,0x60(%r12)| movups 
%xmm0,0xc0(%r12)
mov%rcx,%rax  | movups 
%xmm0,0xd0(%r12)
mul%rdi   | movups 
%xmm0,0xe0(%r12)
mov%rsi,0x78(%r12)| m

[PATCH 07/12] x86: Add AVX2 tests for PR middle-end/90773

2021-04-29 Thread H.J. Lu via Gcc-patches
PR middle-end/90773
* gcc.target/i386/pr90773-20.c: New test.
* gcc.target/i386/pr90773-21.c: Likewise.
* gcc.target/i386/pr90773-22.c: Likewise.
* gcc.target/i386/pr90773-23.c: Likewise.
---
 gcc/testsuite/gcc.target/i386/pr90773-20.c | 13 +
 gcc/testsuite/gcc.target/i386/pr90773-21.c | 13 +
 gcc/testsuite/gcc.target/i386/pr90773-22.c | 13 +
 gcc/testsuite/gcc.target/i386/pr90773-23.c | 13 +
 4 files changed, 52 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr90773-20.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr90773-21.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr90773-22.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr90773-23.c

diff --git a/gcc/testsuite/gcc.target/i386/pr90773-20.c 
b/gcc/testsuite/gcc.target/i386/pr90773-20.c
new file mode 100644
index 000..e61e405f2b6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr90773-20.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=skylake" } */
+
+extern char *dst;
+
+void
+foo (int c)
+{
+  __builtin_memset (dst, c, 33);
+}
+
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, 
\\(%\[\^,\]+\\)" 1 } } */
+/* { dg-final { scan-assembler-times "movb\[\\t \]+.+, 32\\(%\[\^,\]+\\)" 1 } 
} */
diff --git a/gcc/testsuite/gcc.target/i386/pr90773-21.c 
b/gcc/testsuite/gcc.target/i386/pr90773-21.c
new file mode 100644
index 000..16ad17f3cbb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr90773-21.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=skylake" } */
+
+extern char *dst;
+
+void
+foo (int c)
+{
+  __builtin_memset (dst, c, 34);
+}
+
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, 
\\(%\[\^,\]+\\)" 1 } } */
+/* { dg-final { scan-assembler-times "movw\[\\t \]%.*, 32\\(%\[\^,\]+\\)" 1 } 
} */
diff --git a/gcc/testsuite/gcc.target/i386/pr90773-22.c 
b/gcc/testsuite/gcc.target/i386/pr90773-22.c
new file mode 100644
index 000..45a8ff65a84
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr90773-22.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=skylake" } */
+
+extern char *dst;
+
+void
+foo (void)
+{
+  __builtin_memset (dst, 0, 33);
+}
+
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, 
\\(%\[\^,\]+\\)" 1 } } */
+/* { dg-final { scan-assembler-times "movb\[\\t \]+.+, 32\\(%\[\^,\]+\\)" 1 } 
} */
diff --git a/gcc/testsuite/gcc.target/i386/pr90773-23.c 
b/gcc/testsuite/gcc.target/i386/pr90773-23.c
new file mode 100644
index 000..9256ce10ff0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr90773-23.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=skylake" } */
+
+extern char *dst;
+
+void
+foo (void)
+{
+  __builtin_memset (dst, 0, 34);
+}
+
+/* { dg-final { scan-assembler-times "vmovdqu\[\\t \]%ymm\[0-9\]+, 
\\(%\[\^,\]+\\)" 1 } } */
+/* { dg-final { scan-assembler-times "movw\[\\t \]+.+, 32\\(%\[\^,\]+\\)" 1 } 
} */
-- 
2.31.1



[PATCH 04/12] x86: Avoid stack realignment when copying data

2021-04-29 Thread H.J. Lu via Gcc-patches
Pass UNITS_PER_WORD * BITS_PER_UNIT to force_reg, when copying data from
one memory location to another with vector registers, to avoid stack
realignment.

* config/i386/i386-expand.c (ix86_expand_vector_move): Pass
UNITS_PER_WORD * BITS_PER_UNIT to force_reg when copying data
from one memory location to another.
---
 gcc/config/i386/i386-expand.c | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index 1942b46efbf..b3c9b94f717 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -431,7 +431,12 @@ ix86_expand_vector_move (machine_mode mode, rtx operands[])
   && !register_operand (op0, mode)
   && !register_operand (op1, mode))
 {
-  emit_move_insn (op0, force_reg (GET_MODE (op0), op1));
+  /* NB: Don't increase stack alignment requirement when forcing
+operand1 into a pseudo register to copy data from one memory
+location to another since it doen't require spill.  */
+  emit_move_insn (op0,
+ force_reg (GET_MODE (op0), op1,
+(UNITS_PER_WORD * BITS_PER_UNIT)));
   return;
 }
 
-- 
2.31.1



[PATCH 01/12] Update alignment_for_piecewise_move

2021-04-29 Thread H.J. Lu via Gcc-patches
alignment_for_piecewise_move is called only with MOVE_MAX_PIECES or
STORE_MAX_PIECES, which are the number of bytes at a time that we
can move or store efficiently.  We should call mode_for_size without
limit to MAX_FIXED_MODE_SIZE, which is an integer expression for the
size in bits of the largest integer machine mode that should actually
be used, may be smaller than MOVE_MAX_PIECES or STORE_MAX_PIECES, which
may use vector.

* expr.c (alignment_for_piecewise_move): Call mode_for_size
without limit to MAX_FIXED_MODE_SIZE.
---
 gcc/expr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/expr.c b/gcc/expr.c
index e0167b77410..b4c110f8c17 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -746,7 +746,7 @@ static unsigned int
 alignment_for_piecewise_move (unsigned int max_pieces, unsigned int align)
 {
   scalar_int_mode tmode
-= int_mode_for_size (max_pieces * BITS_PER_UNIT, 1).require ();
+= int_mode_for_size (max_pieces * BITS_PER_UNIT, 0).require ();
 
   if (align >= GET_MODE_ALIGNMENT (tmode))
 align = GET_MODE_ALIGNMENT (tmode);
-- 
2.31.1



[PATCH 06/12] x86: Update piecewise move and store

2021-04-29 Thread H.J. Lu via Gcc-patches
We can use TImode/OImode/XImode integers for piecewise move and store.
When vector register is used for piecewise move and store, we don't
increase stack_alignment_needed since vector register spill isn't
required for piecewise move and store.  Since stack_realign_needed is
set to true by checking stack_alignment_estimated set by pseudo vector
register usage, we also need to check stack_realign_needed to eliminate
frame pointer.

gcc/

* config/i386/i386.c (ix86_finalize_stack_frame_flags): Also
check stack_realign_needed for stack realignment.
(ix86_legitimate_constant_p): Always allow CONST_WIDE_INT smaller
than the largest integer supported by vector register.
* config/i386/i386.h (MOVE_MAX): Set to 64.
(MOVE_MAX_PIECES): Set to bytes of the largest integer supported
by vector register.
(STORE_MAX_PIECES): New.

gcc/testsuite/

* gcc.target/i386/pr90773-1.c: Adjust to expect movq for 32-bit.
* gcc.target/i386/pr90773-4.c: Also run for 32-bit.
* gcc.target/i386/pr90773-14.c: Likewise.
* gcc.target/i386/pr90773-15.c: Likewise.
* gcc.target/i386/pr90773-16.c: Likewise.
* gcc.target/i386/pr90773-17.c: Likewise.
---
 gcc/config/i386/i386.c | 21 ---
 gcc/config/i386/i386.h | 31 +-
 gcc/testsuite/gcc.target/i386/pr90773-1.c  | 10 +++
 gcc/testsuite/gcc.target/i386/pr90773-14.c |  2 +-
 gcc/testsuite/gcc.target/i386/pr90773-15.c |  6 ++---
 gcc/testsuite/gcc.target/i386/pr90773-16.c |  2 +-
 gcc/testsuite/gcc.target/i386/pr90773-17.c |  2 +-
 gcc/testsuite/gcc.target/i386/pr90773-4.c  |  2 +-
 8 files changed, 53 insertions(+), 23 deletions(-)

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e6ee3ef630a..8ae0fa764f6 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -7925,8 +7925,17 @@ ix86_finalize_stack_frame_flags (void)
  assumed stack realignment might be needed or -fno-omit-frame-pointer
  is used, but in the end nothing that needed the stack alignment had
  been spilled nor stack access, clear frame_pointer_needed and say we
- don't need stack realignment.  */
-  if ((stack_realign || (!flag_omit_frame_pointer && optimize))
+ don't need stack realignment.
+
+ When vector register is used for piecewise move and store, we don't
+ increase stack_alignment_needed as there is no register spill for
+ piecewise move and store.  Since stack_realign_needed is set to true
+ by checking stack_alignment_estimated which is updated by pseudo
+ vector register usage, we also need to check stack_realign_needed to
+ eliminate frame pointer.  */
+  if ((stack_realign
+   || (!flag_omit_frame_pointer && optimize)
+   || crtl->stack_realign_needed)
   && frame_pointer_needed
   && crtl->is_leaf
   && crtl->sp_is_unchanging
@@ -10385,7 +10394,13 @@ ix86_legitimate_constant_p (machine_mode mode, rtx x)
  /* FALLTHRU */
case E_OImode:
case E_XImode:
- if (!standard_sse_constant_p (x, mode))
+ if (!standard_sse_constant_p (x, mode)
+ && GET_MODE_SIZE (TARGET_AVX512F
+   ? XImode
+   : (TARGET_AVX
+  ? OImode
+  : (TARGET_SSE2
+ ? TImode : DImode))) < GET_MODE_SIZE 
(mode))
return false;
default:
  break;
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 96b46bac238..b3213f85698 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1750,7 +1750,7 @@ typedef struct ix86_args {
 
 /* Max number of bytes we can move from memory to memory
in one reasonably fast instruction.  */
-#define MOVE_MAX 16
+#define MOVE_MAX 64
 
 /* MOVE_MAX_PIECES is the number of bytes at a time which we can
move efficiently, as opposed to  MOVE_MAX which is the maximum
@@ -1761,11 +1761,30 @@ typedef struct ix86_args {
widest mode with MAX_FIXED_MODE_SIZE, we can only use TImode in
64-bit mode.  */
 #define MOVE_MAX_PIECES \
-  ((TARGET_64BIT \
-&& TARGET_SSE2 \
-&& TARGET_SSE_UNALIGNED_LOAD_OPTIMAL \
-&& TARGET_SSE_UNALIGNED_STORE_OPTIMAL) \
-   ? GET_MODE_SIZE (TImode) : UNITS_PER_WORD)
+  ((TARGET_AVX512F && !TARGET_PREFER_AVX256) \
+   ? 64 \
+   : ((TARGET_AVX \
+   && !TARGET_PREFER_AVX128 \
+   && !TARGET_AVX256_SPLIT_UNALIGNED_LOAD \
+   && !TARGET_AVX256_SPLIT_UNALIGNED_STORE) \
+  ? 32 \
+  : ((TARGET_SSE2 \
+ && TARGET_SSE_UNALIGNED_LOAD_OPTIMAL \
+ && TARGET_SSE_UNALIGNED_STORE_OPTIMAL) \
+? 16 : UNITS_PER_WORD)))
+
+/* STORE_MAX_PIECES is the number of bytes at a time that we can
+   store efficiently.  */
+#define STORE_MAX_PIECES \
+  ((TARGET_AVX512F && !TARGET_PREFER_AVX256) \
+   ? 64 \
+   : ((TARGET_AVX \
+   && !T

[PATCH 05/12] Remove MAX_BITSIZE_MODE_ANY_INT

2021-04-29 Thread H.J. Lu via Gcc-patches
It is only defined for i386 and everyone uses the default:

 #define MAX_BITSIZE_MODE_ANY_INT (64*BITS_PER_UNIT)

Whatever problems we had before, they have been fixed now.

* config/i386/i386-modes.def (MAX_BITSIZE_MODE_ANY_INT): Removed.
---
 gcc/config/i386/i386-modes.def | 15 +++
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/gcc/config/i386/i386-modes.def b/gcc/config/i386/i386-modes.def
index dbddfd8e48f..4e7014be034 100644
--- a/gcc/config/i386/i386-modes.def
+++ b/gcc/config/i386/i386-modes.def
@@ -107,19 +107,10 @@ INT_MODE (XI, 64);
 PARTIAL_INT_MODE (HI, 16, P2QI);
 PARTIAL_INT_MODE (SI, 32, P2HI);
 
-/* Mode used for signed overflow checking of TImode.  As
-   MAX_BITSIZE_MODE_ANY_INT is only 160, wide-int.h reserves only that
-   rounded up to multiple of HOST_BITS_PER_WIDE_INT bits in wide_int etc.,
-   so OImode is too large.  For the overflow checking we actually need
-   just 1 or 2 bits beyond TImode precision.  Use 160 bits to have
-   a multiple of 32.  */
+/* Mode used for signed overflow checking of TImode.  For the overflow
+   checking we actually need just 1 or 2 bits beyond TImode precision.
+   Use 160 bits to have a multiple of 32.  */
 PARTIAL_INT_MODE (OI, 160, POI);
 
-/* Keep the OI and XI modes from confusing the compiler into thinking
-   that these modes could actually be used for computation.  They are
-   only holders for vectors during data movement.  Include POImode precision
-   though.  */
-#define MAX_BITSIZE_MODE_ANY_INT (160)
-
 /* The symbol Pmode stands for one of the above machine modes (usually SImode).
The tm.h file specifies which one.  It is not a distinct mode.  */
-- 
2.31.1



[PATCH 09/12] x86: Also pass -mno-avx to pr72839.c

2021-04-29 Thread H.J. Lu via Gcc-patches
Also pass -mno-avx to pr72839.c to avoid copying data with YMM or ZMM
registers.

* gcc.target/i386/pr72839.c: Also pass -mno-avx.
---
 gcc/testsuite/gcc.target/i386/pr72839.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/i386/pr72839.c 
b/gcc/testsuite/gcc.target/i386/pr72839.c
index ea724f70377..6888d9d0a55 100644
--- a/gcc/testsuite/gcc.target/i386/pr72839.c
+++ b/gcc/testsuite/gcc.target/i386/pr72839.c
@@ -1,6 +1,6 @@
 /* { dg-do compile } */
 /* { dg-require-effective-target ia32 } */
-/* { dg-options "-O2 -mtune=lakemont" } */
+/* { dg-options "-O2 -mtune=lakemont -mno-avx" } */
 
 extern char *strcpy (char *, const char *);
 
-- 
2.31.1



[PATCH 03/12] Add TARGET_READ_MEMSET_VALUE/TARGET_GEN_MEMSET_VALUE

2021-04-29 Thread H.J. Lu via Gcc-patches
Add TARGET_READ_MEMSET_VALUE and TARGET_GEN_MEMSET_VALUE to support
target instructions to duplicate QImode value to TImode/OImode/XImode
value for memmset.

gcc/

PR middle-end/90773
* builtins.c (builtin_memset_read_str): Call
targetm.read_memset_value.
(builtin_memset_gen_str): Call targetm.gen_memset_value.
* target.def (read_memset_value): New hook.
(gen_memset_value): Likewise.
* targhooks.c: Inclue "builtins.h".
(default_read_memset_value): New function.
(default_gen_memset_value): Likewise.
* targhooks.h ()default_read_memset_value: New prototype.
(default_gen_memset_value): Likewise.
* config/i386/i386-expand.c (ix86_expand_vector_init_duplicate):
Make it global.
* config/i386/i386-protos.h (ix86_expand_vector_init_duplicate):
New.
* config/i386/i386.c (ix86_gen_memset_value_from_prev): New
function.
(ix86_gen_memset_value): Likewise.
(ix86_read_memset_value): Likewise.
(TARGET_GEN_MEMSET_VALUE): New.
(TARGET_READ_MEMSET_VALUE): Likewise.
* doc/tm.texi.in: Add TARGET_READ_MEMSET_VALUE and
TARGET_GEN_MEMSET_VALUE hooks.
* doc/tm.texi: Regenerated.

gcc/testsuite/

PR middle-end/90773
* gcc.target/i386/pr90773-15.c: New test.
* gcc.target/i386/pr90773-16.c: Likewise.
* gcc.target/i386/pr90773-17.c: Likewise.
* gcc.target/i386/pr90773-18.c: Likewise.
* gcc.target/i386/pr90773-19.c: Likewise.
---
 gcc/builtins.c |  45 +---
 gcc/config/i386/i386-expand.c  |   2 +-
 gcc/config/i386/i386-protos.h  |   2 +
 gcc/config/i386/i386.c | 236 +
 gcc/doc/tm.texi|  16 ++
 gcc/doc/tm.texi.in |   4 +
 gcc/expr.c |   1 -
 gcc/target.def |  20 ++
 gcc/targhooks.c|  54 +
 gcc/targhooks.h|   4 +
 gcc/testsuite/gcc.target/i386/pr90773-15.c |  14 ++
 gcc/testsuite/gcc.target/i386/pr90773-16.c |  14 ++
 gcc/testsuite/gcc.target/i386/pr90773-17.c |  14 ++
 gcc/testsuite/gcc.target/i386/pr90773-18.c |  15 ++
 gcc/testsuite/gcc.target/i386/pr90773-19.c |  14 ++
 15 files changed, 412 insertions(+), 43 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr90773-15.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr90773-16.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr90773-17.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr90773-18.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr90773-19.c

diff --git a/gcc/builtins.c b/gcc/builtins.c
index 2d6bf4a65b4..c5610795eec 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -6586,24 +6586,11 @@ expand_builtin_strncpy (tree exp, rtx target)
previous iteration.  */
 
 rtx
-builtin_memset_read_str (void *data, void *prevp,
+builtin_memset_read_str (void *data, void *prev,
 HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
 scalar_int_mode mode)
 {
-  by_pieces_prev *prev = (by_pieces_prev *) prevp;
-  if (prev != nullptr && prev->data != nullptr)
-{
-  /* Use the previous data in the same mode.  */
-  if (prev->mode == mode)
-   return prev->data;
-}
-
-  const char *c = (const char *) data;
-  char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
-
-  memset (p, *c, GET_MODE_SIZE (mode));
-
-  return c_readstr (p, mode);
+  return targetm.read_memset_value ((const char *) data, prev, mode);
 }
 
 /* Callback routine for store_by_pieces.  Return the RTL of a register
@@ -6613,35 +6600,11 @@ builtin_memset_read_str (void *data, void *prevp,
nullptr, it has the RTL info from the previous iteration.  */
 
 static rtx
-builtin_memset_gen_str (void *data, void *prevp,
+builtin_memset_gen_str (void *data, void *prev,
HOST_WIDE_INT offset ATTRIBUTE_UNUSED,
scalar_int_mode mode)
 {
-  rtx target, coeff;
-  size_t size;
-  char *p;
-
-  by_pieces_prev *prev = (by_pieces_prev *) prevp;
-  if (prev != nullptr && prev->data != nullptr)
-{
-  /* Use the previous data in the same mode.  */
-  if (prev->mode == mode)
-   return prev->data;
-
-  return simplify_gen_subreg (mode, prev->data, prev->mode, 0);
-}
-
-  size = GET_MODE_SIZE (mode);
-  if (size == 1)
-return (rtx) data;
-
-  p = XALLOCAVEC (char, size);
-  memset (p, 1, size);
-  coeff = c_readstr (p, mode);
-
-  target = convert_to_mode (mode, (rtx) data, 1);
-  target = expand_mult (mode, target, coeff, NULL_RTX, 1);
-  return force_reg (mode, target);
+  return targetm.gen_memset_value ((rtx) data, prev, mode);
 }
 
 /* Expand expression EXP, which is a call to the memset builtin.  Return
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index 516440eb

[PATCH 12/12] x86: Update gcc.target/i386/incoming-11.c

2021-04-29 Thread H.J. Lu via Gcc-patches
Expect no stack realignment since we no longer realign stack when
copying data.

* gcc.target/i386/incoming-11.c: Expect no stack realignment.
---
 gcc/testsuite/gcc.target/i386/incoming-11.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/i386/incoming-11.c 
b/gcc/testsuite/gcc.target/i386/incoming-11.c
index a830c96f7d1..4b822684b88 100644
--- a/gcc/testsuite/gcc.target/i386/incoming-11.c
+++ b/gcc/testsuite/gcc.target/i386/incoming-11.c
@@ -15,4 +15,4 @@ void f()
for (i = 0; i < 100; i++) q[i] = 1;
 }
 
-/* { dg-final { scan-assembler "andl\[\\t \]*\\$-16,\[\\t \]*%esp" } } */
+/* { dg-final { scan-assembler-not "andl\[\\t \]*\\$-16,\[\\t \]*%esp" } } */
-- 
2.31.1



[PATCH 10/12] x86: Also pass -mno-avx to cold-attribute-1.c

2021-04-29 Thread H.J. Lu via Gcc-patches
Also pass -mno-avx to pr72839.c to avoid copying data with YMM or ZMM
registers.

* gcc.target/i386/cold-attribute-1.c: Also pass -mno-avx.
---
 gcc/testsuite/gcc.target/i386/cold-attribute-1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/i386/cold-attribute-1.c 
b/gcc/testsuite/gcc.target/i386/cold-attribute-1.c
index 57666ac60b6..658eb3e25bb 100644
--- a/gcc/testsuite/gcc.target/i386/cold-attribute-1.c
+++ b/gcc/testsuite/gcc.target/i386/cold-attribute-1.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -mno-avx" } */
 #include 
 static inline
 __attribute__ ((cold)) void
-- 
2.31.1



[PATCH 08/12] x86: Add tests for piecewise move and store

2021-04-29 Thread H.J. Lu via Gcc-patches
* gcc.target/i386/pieces-memcpy-10.c: New test.
* gcc.target/i386/pieces-memcpy-11.c: Likewise.
* gcc.target/i386/pieces-memcpy-12.c: Likewise.
* gcc.target/i386/pieces-memcpy-13.c: Likewise.
* gcc.target/i386/pieces-memcpy-14.c: Likewise.
* gcc.target/i386/pieces-memcpy-15.c: Likewise.
* gcc.target/i386/pieces-memcpy-16.c: Likewise.
* gcc.target/i386/pieces-memcpy-17.c: Likewise.
* gcc.target/i386/pieces-memcpy-18.c: Likewise.
* gcc.target/i386/pieces-memcpy-19.c: Likewise.
* gcc.target/i386/pieces-memset-1.c: Likewise.
* gcc.target/i386/pieces-memset-2.c: Likewise.
* gcc.target/i386/pieces-memset-3.c: Likewise.
* gcc.target/i386/pieces-memset-4.c: Likewise.
* gcc.target/i386/pieces-memset-5.c: Likewise.
* gcc.target/i386/pieces-memset-6.c: Likewise.
* gcc.target/i386/pieces-memset-7.c: Likewise.
* gcc.target/i386/pieces-memset-8.c: Likewise.
* gcc.target/i386/pieces-memset-9.c: Likewise.
* gcc.target/i386/pieces-memset-10.c: Likewise.
* gcc.target/i386/pieces-memset-11.c: Likewise.
* gcc.target/i386/pieces-memset-12.c: Likewise.
* gcc.target/i386/pieces-memset-13.c: Likewise.
* gcc.target/i386/pieces-memset-14.c: Likewise.
* gcc.target/i386/pieces-memset-15.c: Likewise.
* gcc.target/i386/pieces-memset-16.c: Likewise.
* gcc.target/i386/pieces-memset-17.c: Likewise.
* gcc.target/i386/pieces-memset-18.c: Likewise.
* gcc.target/i386/pieces-memset-19.c: Likewise.
* gcc.target/i386/pieces-memset-20.c: Likewise.
* gcc.target/i386/pieces-memset-21.c: Likewise.
* gcc.target/i386/pieces-memset-22.c: Likewise.
* gcc.target/i386/pieces-memset-23.c: Likewise.
* gcc.target/i386/pieces-memset-24.c: Likewise.
* gcc.target/i386/pieces-memset-25.c: Likewise.
* gcc.target/i386/pieces-memset-26.c: Likewise.
* gcc.target/i386/pieces-memset-27.c: Likewise.
* gcc.target/i386/pieces-memset-28.c: Likewise.
* gcc.target/i386/pieces-memset-29.c: Likewise.
* gcc.target/i386/pieces-memset-30.c: Likewise.
* gcc.target/i386/pieces-memset-31.c: Likewise.
* gcc.target/i386/pieces-memset-32.c: Likewise.
* gcc.target/i386/pieces-memset-33.c: Likewise.
* gcc.target/i386/pieces-memset-34.c: Likewise.
* gcc.target/i386/pieces-memset-35.c: Likewise.
* gcc.target/i386/pieces-memset-36.c: Likewise.
* gcc.target/i386/pieces-memset-37.c: Likewise.
* gcc.target/i386/pieces-memset-38.c: Likewise.
* gcc.target/i386/pieces-memset-39.c: Likewise.
* gcc.target/i386/pieces-memset-40.c: Likewise.
* gcc.target/i386/pieces-memset-41.c: Likewise.
* gcc.target/i386/pieces-memset-42.c: Likewise.
* gcc.target/i386/pieces-memset-43.c: Likewise.
* gcc.target/i386/pieces-memset-44.c: Likewise.
---
 .../gcc.target/i386/pieces-memcpy-10.c | 16 
 .../gcc.target/i386/pieces-memcpy-11.c | 17 +
 .../gcc.target/i386/pieces-memcpy-12.c | 16 
 .../gcc.target/i386/pieces-memcpy-13.c | 16 
 .../gcc.target/i386/pieces-memcpy-14.c | 17 +
 .../gcc.target/i386/pieces-memcpy-15.c | 16 
 .../gcc.target/i386/pieces-memcpy-16.c | 16 
 .../gcc.target/i386/pieces-memcpy-7.c  | 15 +++
 .../gcc.target/i386/pieces-memcpy-8.c  | 14 ++
 .../gcc.target/i386/pieces-memcpy-9.c  | 14 ++
 .../gcc.target/i386/pieces-memset-1.c  | 16 
 .../gcc.target/i386/pieces-memset-10.c | 16 
 .../gcc.target/i386/pieces-memset-11.c | 16 
 .../gcc.target/i386/pieces-memset-12.c | 16 
 .../gcc.target/i386/pieces-memset-13.c | 16 
 .../gcc.target/i386/pieces-memset-14.c | 16 
 .../gcc.target/i386/pieces-memset-15.c | 16 
 .../gcc.target/i386/pieces-memset-16.c | 16 
 .../gcc.target/i386/pieces-memset-17.c | 16 
 .../gcc.target/i386/pieces-memset-18.c | 16 
 .../gcc.target/i386/pieces-memset-19.c | 17 +
 .../gcc.target/i386/pieces-memset-2.c  | 12 
 .../gcc.target/i386/pieces-memset-20.c | 17 +
 .../gcc.target/i386/pieces-memset-21.c | 17 +
 .../gcc.target/i386/pieces-memset-22.c | 17 +
 .../gcc.target/i386/pieces-memset-23.c | 17 +
 .../gcc.target/i386/pieces-memset-24.c | 17 +
 .../gcc.target/i386/pieces-memset-25.c | 17 +
 .../gcc.target/i386

[PATCH 11/12] x86: Also pass -mno-avx to sw-1.c for ia32

2021-04-29 Thread H.J. Lu via Gcc-patches
Also pass -mno-avx to sw-1.c for ia32 since copying data with YMM or ZMM
registers disables shrink-wrapping when the second argument is passed on
stack.

* gcc.target/i386/sw-1.c: Also pass -mno-avx for ia32.
---
 gcc/testsuite/gcc.target/i386/sw-1.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.target/i386/sw-1.c 
b/gcc/testsuite/gcc.target/i386/sw-1.c
index aec095eda62..a9c89fca4ec 100644
--- a/gcc/testsuite/gcc.target/i386/sw-1.c
+++ b/gcc/testsuite/gcc.target/i386/sw-1.c
@@ -1,5 +1,6 @@
 /* { dg-do compile } */
 /* { dg-options "-O2 -mtune=generic -fshrink-wrap -fdump-rtl-pro_and_epilogue" 
} */
+/* { dg-additional-options "-mno-avx" { target ia32 } } */
 /* { dg-skip-if "No shrink-wrapping preformed" { x86_64-*-mingw* } } */
 
 #include 
-- 
2.31.1



[PATCH] i386: Cleanup comparison predicates.

2021-04-29 Thread Uros Bizjak via Gcc-patches
CCCmode is allowed only with GEU and LTU comparison codes.  Also allow
CCGZmode for these two codes.  There is no need to check for trivial FP
comparison operator, ix86_fp_compare_code_to_integer will return
UNKNOWN code for unsupported operators.

2021-04-29  Uroš Bizjak  

gcc/
* config/i386/predicates.md (fcmov_comparison_operator):
Do not check for trivial FP comparison operator.
: Allow CCGZmode.
: Do not allow CCCmode.
(ix86_comparison_operator) : Allow only CCmode.
(ix86_carry_flag_operator): Match only LTU and UNLT code.
Do not check for trivial FP comparison operator.  Allow CCGZmode.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Pushed to master.

Uros.
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index b1df8548af6..04a03a70b46 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -1352,16 +1352,17 @@ (define_predicate "fcmov_comparison_operator"
   enum rtx_code code = GET_CODE (op);
 
   if (inmode == CCFPmode)
-{
-  if (!ix86_trivial_fp_comparison_operator (op, mode))
-   return false;
-  code = ix86_fp_compare_code_to_integer (code);
-}
+code = ix86_fp_compare_code_to_integer (code);
+
   /* i387 supports just limited amount of conditional codes.  */
   switch (code)
 {
-case LTU: case GTU: case LEU: case GEU:
-  if (inmode == CCmode || inmode == CCFPmode || inmode == CCCmode)
+case GEU: case LTU:
+  if (inmode == CCCmode || inmode == CCGZmode)
+   return true;
+  /* FALLTHRU */
+case GTU: case LEU:
+  if (inmode == CCmode || inmode == CCFPmode)
return true;
   return false;
 case ORDERED: case UNORDERED:
@@ -1418,11 +1419,11 @@ (define_predicate "ix86_comparison_operator"
return true;
   return false;
 case GEU: case LTU:
-  if (inmode == CCGZmode)
+  if (inmode == CCCmode || inmode == CCGZmode)
return true;
   /* FALLTHRU */
 case GTU: case LEU:
-  if (inmode == CCmode || inmode == CCCmode || inmode == CCGZmode)
+  if (inmode == CCmode)
return true;
   return false;
 case ORDERED: case UNORDERED:
@@ -1441,20 +1442,14 @@ (define_predicate "ix86_comparison_operator"
 ;; Return true if OP is a valid comparison operator
 ;; testing carry flag to be set.
 (define_predicate "ix86_carry_flag_operator"
-  (match_code "ltu,lt,unlt,gtu,gt,ungt,le,unle,ge,unge,ltgt,uneq")
+  (match_code "ltu,unlt")
 {
   machine_mode inmode = GET_MODE (XEXP (op, 0));
   enum rtx_code code = GET_CODE (op);
 
   if (inmode == CCFPmode)
-{
-  if (!ix86_trivial_fp_comparison_operator (op, mode))
-   return false;
-  code = ix86_fp_compare_code_to_integer (code);
-}
-  else if (inmode == CCCmode)
-   return code == LTU || code == GTU;
-  else if (inmode != CCmode)
+code = ix86_fp_compare_code_to_integer (code);
+  else if (inmode != CCmode && inmode != CCCmode && inmode != CCGZmode)
 return false;
 
   return code == LTU;


Re: [PATCH] c++: Overeager use of deleted function before ADL [PR68942]

2021-04-29 Thread Jason Merrill via Gcc-patches

On 4/28/21 3:03 PM, Patrick Palka wrote:

Here, at template definition time, ordinary name lookup for 'foo(t)'
finds the deleted function, and so we form a CALL_EXPR thereof.  Later
at instantiation time, when initially substituting into this CALL_EXPR
with T=N::A, we end up calling mark_used on this deleted function before
we augment the overload set via ADL and select the right function.

This patch fixes this issue by using tf_conv in order to disable
mark_used during the initial substitution of the function of a CALL_EXPR
when KOENIG_P.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?


Hmm, I suppose this is close enough to the tf_conv case to make sense, 
as we're still figuring out which functions are candidates.  OK.



gcc/cp/ChangeLog:

PR c++/68942
* pt.c (tsubst_copy_and_build) : When KOENIG_P,
add tf_conv to complain during the initial substitution into
the function.

gcc/testsuite/ChangeLog:

PR c++/68942
* g++.dg/template/koenig12.C: New test.
---
  gcc/cp/pt.c  |  6 +-
  gcc/testsuite/g++.dg/template/koenig12.C | 15 +++
  2 files changed, 20 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/template/koenig12.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index d79fecd4949..bed9a22193a 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -20238,7 +20238,11 @@ tsubst_copy_and_build (tree t,
  /* Avoid error about taking the address of a constructor.  */
  function = TREE_OPERAND (function, 0);
  
-	function = tsubst_copy_and_build (function, args, complain,

+   /* When KOENIG_P, we don't want to mark_used a function until
+  after performing ADL, during this substitution we disable
+  mark_used by adding tf_conv to complain (68942).  */
+   function = tsubst_copy_and_build (function, args,
+ complain | (koenig_p * tf_conv),
  in_decl,
  !qualified_p,
  integral_constant_expression_p);
diff --git a/gcc/testsuite/g++.dg/template/koenig12.C 
b/gcc/testsuite/g++.dg/template/koenig12.C
new file mode 100644
index 000..fd05ef5719e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/koenig12.C
@@ -0,0 +1,15 @@
+// PR c++/68942
+// { dg-do compile { target c++11 } }
+
+void foo(...) = delete;
+
+template  void lookup(T t) { foo(t); }
+
+namespace N {
+ struct A { };
+ int foo(A);
+}
+
+int main() {
+  lookup(N::A{});
+}





Re: [PATCH/RFC] Add a new memory gathering optimization for loop (PR98598)

2021-04-29 Thread David Malcolm via Gcc-patches
On Thu, 2021-01-21 at 06:27 +, Feng Xue OS via Gcc-patches wrote:
> This patch implements a new loop optimization according to the proposal
> in RFC given at  
> https://gcc.gnu.org/pipermail/gcc/2021-January/234682.html.
> So do not repeat the idea in this mail. Hope your comments on it.

With the caveat that I'm not an optimization expert (but no one else
seems to have replied), here are some thoughts.

[...snip...]

> Subject: [PATCH 1/3] mgo: Add a new memory gathering optimization for loop
>  [PR98598]

BTW, did you mean to also post patches 2 and 3?


> In nested loops, if scattered memory accesses inside inner loop remain
> unchanged in outer loop, we can sequentialize these loads by caching
> their values into a temporary memory region at the first time, and
> reuse the caching data in following iterations. This way can improve
> efficiency of cpu cache subsystem by reducing its unpredictable activies.

I don't think you've cited any performance numbers so far.  Does the
optimization show a measurable gain on some benchmark(s)?  e.g. is this
ready to run SPEC yet, and how does it do?
 
> To illustrate what the optimization will do, two pieces of pseudo code,
> before and after transformation, are given. Suppose all loads and
> "iter_count" are invariant in outer loop.
> 
> From:
> 
>   outer-loop ()
> {
>   inner-loop (iter, iter_count)
> {
>   Type1 v1 = LOAD (iter);
>   Type2 v2 = LOAD (v1);
>   Type3 v3 = LOAD (v2);
>   ...
>   iter = NEXT (iter);
> }
> }
> 
> To:
> 
>   typedef struct cache_elem
> {
>   bool   init;
>   Type1  c_v1;
>   Type2  c_v2;
>   Type3  c_v3;

Putting the "bool init;" at the front made me think "what about
packing?" but presumably the idea is that every element is accessed in
order, so it presumably benefits speed to have "init" at the top of the
element, right?

> } cache_elem;
> 
>   cache_elem *cache_arr = calloc (iter_count, sizeof (cache_elem));

What if the allocation fails at runtime?  Do we keep an unoptimized
copy of the nested loops around as a fallback and have an unlikely
branch to that copy?

I notice that you're using calloc, presumably to clear all of the
"init" flags (and the whole buffer).

FWIW, this feels like a case where it would be nice to have a thread-
local heap allocation, perhaps something like an obstack implemented in
the standard library - but that's obviously scope creep for this.

Could it make sense to use alloca for small allocations?  (or is that
scope creep?)
 
>   outer-loop ()
> {
>   size_t cache_idx = 0;
> 
>   inner-loop (iter, iter_count)
> {
>   if (!cache_arr[cache_idx]->init)
> {
>   v1 = LOAD (iter);
>   v2 = LOAD (v1);
>   v3 = LOAD (v2);
> 
>   cache_arr[cache_idx]->init = true;
>   cache_arr[cache_idx]->c_v1 = v1;
>   cache_arr[cache_idx]->c_v2 = v2;
>   cache_arr[cache_idx]->c_v3 = v3;
> }
> else
> {
>   v1 = cache_arr[cache_idx]->c_v1;
>   v2 = cache_arr[cache_idx]->c_v2;
>   v3 = cache_arr[cache_idx]->c_v3;
> }
>   ...
>   cache_idx++;
>   iter = NEXT (iter);
> }
> }
> 
>   free (cache_arr);

I see that the pass puts a "free" on every CFG exit from the loop.

What about "longjmp" and C++ exceptions?  Are we guaranteed that "free"
will happen for those ways of exiting the loop?  (should have test
cases for this, I think)


[...]


> 2020-12-25  Feng Xue  
> 
> gcc/
>   PR tree-optimization/98598
>   * Makefile.in (OBJS): Add tree-ssa-loop-mgo.o.
>   * common.opt (-ftree-loop-mgo): New option.
>   * opts.c (default_options_table): Enable -ftree-loop-mgo at -O3+.
>   * params.opt (mgo-max-dep-load-level): New parameter.
>   (mgo-max-cache-elem-size): Likewise.
>   (mgo-min-cache-array-length): Likewise.
>   (mgo-max-cache-array-length): Likewise.
>   * doc/invoke.texi (mgo-max-dep-load-level): Document new parameter.
>   (mgo-max-cache-elem-size): Likewise.
>   (mgo-min-cache-array-length): Likewise.
>   (mgo-max-cache-array-length): Likewise.

Nit: also need to document "-ftree-loop-mgo".

>   * passes.def: Add new pass_loop_mgo pass.
>   * timevar.def (TV_LOOP_MGO): New timevar.
>   * tree-pass.h (make_pass_loop_mgo): New declaration.
>   * tree-ssa-loop-mgo.c: New file.

Nit: new C++ source files should have a .cc extension, rather than .c

> gcc/testsuite/
>   PR tree-optimization/98598
>   * gcc.dg/tree-ssa/mgo/mgo.exp: New file.
>   * gcc.dg/tree-ssa/mgo/mgo-common.h: New test header.
>   * gcc.dg/tree-ssa/mgo/list/list-1.c: New test.
>   * gcc.dg/tree-ssa/mgo/array/simple-1.c: Likewise.
>   * gcc.dg/tree-ssa/mgo/array/simple-2.c: Likewise.
>   * gcc.dg/tree-ssa/mgo/array/simple-3.c: Likewise.
>  

Re: [PATCH] target/100312 - make x86 masked load builtins pure

2021-04-29 Thread Uros Bizjak via Gcc-patches
On Thu, Apr 29, 2021 at 9:25 AM Richard Biener  wrote:

> > > It eventually runs into the gcc_unreachable () at the very end of
> > > ix86_expand_builtin since IX86_BUILTIN_MASKLOADD and friends are
> > > no longer in the range of IX86_BUILTIN__BDESC_SPECIAL_ARGS_FIRST
> > > to IX86_BUILTIN__BDESC_SPECIAL_ARGS_LAST.
> >
> > How about the attached (untested) patch then?
>
> Ah yeah - good idea.
>
> The patch works, bootstrapped and tested on x86_64-unknown-linux-gnu.
>
> As expected it reduces the number of masked load builtins for the
> PR99912 testcase from ~800 to ~350 (at the GIMPLE level).

Thanks, pushed with the following ChangeLog:

i386: Mark x86 masked load builtins pure [PR100312]

Mark x86 AVX and AVX2 masked load builtins pure to enable dead code
elimination and more appropriate alias analysis.

2021-04-29  Uroš Bizjak  
Richard Biener  
gcc/
PR target/100312
* config/i386/i386-builtin.def (IX86_BUILTIN_MASKLOADPD)
(IX86_BUILTIN_MASKLOADPS, IX86_BUILTIN_MASKLOADPD256)
(IX86_BUILTIN_MASKLOADPS256, IX86_BUILTIN_MASKLOADD)
(IX86_BUILTIN_MASKLOADQ, IX86_BUILTIN_MASKLOADD256)
(IX86_BUILTIN_MASKLOADQ256): Move from SPECIAL_ARGS
to PURE_ARGS category.
* config/i386/i386-builtins.c (ix86_init_mmx_sse_builtins):
Handle PURE_ARGS category.
* config/i386/i386-expand.c (ix86_expand_builtin): Ditto.

Uros.


> Thanks,
> Richard.


[PATCH] c++: Implement P2367 changes to avoid some list-initialization

2021-04-29 Thread Patrick Palka via Gcc-patches
This implements the wording changes of P2367R0 "Remove misuses of
list-initialization from Clause 24", modulo the parts that depend
on P1739R4 which we don't yet implement (due to LWG 3407).

Tested on x86_64-pc-linux-gnu, does this look OK for trunk?

libstdc++-v3/ChangeLog:

* include/bits/ranges_util.h (subrange::subrange): Avoid
list-initialization in delegating constructor.
* include/std/ranges (single_view): Replace implicit guide
with explicit deduction guide that decays its argument.
(_Single::operator()): Avoid CTAD when constructing the
single_view object.
(_Iota::operator()): Avoid list-initialization.
(__detail::__can_filter_view, _Filter::operator()): Likewise.
(__detail::__can_transform_view, _Transform::operator()): Likewise.
(take_view::begin): Likewise.
(__detail::__can_take_view, _Take::operator()): Likewise.
(__detail::__can_take_while_view, _TakeWhile::operator()): Likewise.
(__detail::__can_drop_view, _Drop::operator()): Likewise.
(__detail::__can_drop_while_view, _DropWhile::operator()): Likewise.
(split_view::split_view): Use views::single when initializing
_M_pattern.
(__detail::__can_split_view, _Split::operator()): Avoid
list-initialization.
(_Counted::operator()): Likewise.
* testsuite/std/ranges/p2367.cc: New test.
---
 libstdc++-v3/include/bits/ranges_util.h|  2 +-
 libstdc++-v3/include/std/ranges| 55 --
 libstdc++-v3/testsuite/std/ranges/p2367.cc | 48 +++
 3 files changed, 78 insertions(+), 27 deletions(-)
 create mode 100644 libstdc++-v3/testsuite/std/ranges/p2367.cc

diff --git a/libstdc++-v3/include/bits/ranges_util.h 
b/libstdc++-v3/include/bits/ranges_util.h
index 9d51e1b874e..589886eb157 100644
--- a/libstdc++-v3/include/bits/ranges_util.h
+++ b/libstdc++-v3/include/bits/ranges_util.h
@@ -251,7 +251,7 @@ namespace ranges
  && convertible_to, _Sent>
constexpr
subrange(_Rng&& __r) requires (!_S_store_size)
-   : subrange{ranges::begin(__r), ranges::end(__r)}
+   : subrange(ranges::begin(__r), ranges::end(__r))
{ }
 
   template
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 74075a2d6d3..a3779d1ed0c 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -246,6 +246,9 @@ namespace ranges
   [[no_unique_address]] __detail::__box<_Tp> _M_value;
 };
 
+  template
+single_view(_Tp) -> single_view<_Tp>;
+
   namespace __detail
   {
 template
@@ -597,7 +600,7 @@ namespace views
 template
   constexpr auto
   operator()(_Tp&& __e) const
-  { return single_view{std::forward<_Tp>(__e)}; }
+  { return single_view>(std::forward<_Tp>(__e)); }
   };
 
   inline constexpr _Single single{};
@@ -607,12 +610,12 @@ namespace views
 template
   constexpr auto
   operator()(_Tp&& __e) const
-  { return iota_view{std::forward<_Tp>(__e)}; }
+  { return iota_view(std::forward<_Tp>(__e)); }
 
 template
   constexpr auto
   operator()(_Tp&& __e, _Up&& __f) const
-  { return iota_view{std::forward<_Tp>(__e), std::forward<_Up>(__f)}; }
+  { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
   };
 
   inline constexpr _Iota iota{};
@@ -1336,7 +1339,7 @@ namespace views::__adaptor
 {
   template
concept __can_filter_view
- = requires { filter_view{std::declval<_Range>(), 
std::declval<_Pred>()}; };
+ = requires { filter_view(std::declval<_Range>(), 
std::declval<_Pred>()); };
 } // namespace __detail
 
 struct _Filter : __adaptor::_RangeAdaptor<_Filter>
@@ -1346,7 +1349,7 @@ namespace views::__adaptor
constexpr auto
operator()(_Range&& __r, _Pred&& __p) const
{
- return filter_view{std::forward<_Range>(__r), 
std::forward<_Pred>(__p)};
+ return filter_view(std::forward<_Range>(__r), 
std::forward<_Pred>(__p));
}
 
   using _RangeAdaptor<_Filter>::operator();
@@ -1717,7 +1720,7 @@ namespace views::__adaptor
 {
   template
concept __can_transform_view
- = requires { transform_view{std::declval<_Range>(), 
std::declval<_Fp>()}; };
+ = requires { transform_view(std::declval<_Range>(), 
std::declval<_Fp>()); };
 } // namespace __detail
 
 struct _Transform : __adaptor::_RangeAdaptor<_Transform>
@@ -1727,7 +1730,7 @@ namespace views::__adaptor
constexpr auto
operator()(_Range&& __r, _Fp&& __f) const
{
- return transform_view{std::forward<_Range>(__r), 
std::forward<_Fp>(__f)};
+ return transform_view(std::forward<_Range>(__r), 
std::forward<_Fp>(__f));
}
 
   using _RangeAdaptor<_Transform>::operator();
@@ -1813,11 +1816,11 @@ namespace views::__adaptor
else
  {
auto __sz = size

[committed] Trivial fix to get nios2 building again

2021-04-29 Thread Jeff Law via Gcc-patches
The recent improvements to complex divide added this nugget to 
c-cppbuiltins:



#ifdef HAVE_adddf3
  builtin_define_with_int_value ("__LIBGCC_HAVE_HWDBL__",
 HAVE_adddf3);
#endif

This is breaking the nios2 port:

In file included from ./tm.h:33,
 from ../../../../../gcc/gcc/target.h:52,
 from ../../../../../gcc/gcc/c-family/c-cppbuiltin.c:23:
../../../../../gcc/gcc/c-family/c-cppbuiltin.c: In function ‘void 
c_cpp_builtins(cpp_reader*)’:
./insn-flags.h:50:22: error: ‘nios2_fpu_insn_enabled’ was not declared 
in this scope

   50 | #define HAVE_adddf3 (nios2_fpu_insn_enabled (n2fpu_faddd))
  |  ^~
../../../../../gcc/gcc/c-family/c-cppbuiltin.c:1387:7: note: in 
expansion of macro ‘HAVE_adddf3’

 1387 |   HAVE_adddf3);
  |   ^~~


This comes from this in nios2.md:

(define_insn "3"
  [(set (match_operand:F 0 "register_operand"    "=r")
    (FOP3:F (match_operand:F 1 "register_operand" "r")
    (match_operand:F 2 "register_operand" "r")))]
  "nios2_fpu_insn_enabled (n2fpu_f)"
  { return nios2_fpu_insn_asm (n2fpu_f); }
  [(set_attr "type" "custom")])

Note the function call in the insn's condition.


While there are restrictions for conditions in named patterns, a 
function call that just looks at what insns are enabled for the current 
target would be considered OK.



The fix here is pretty simple.  We just need to move the prototype in 
nios2-protos.h into a different part of that file that isn't guarded on 
RTX_CODE.  That's enough to get the compiler building again.  I'll 
respin the Jenkins job to validate things further.


I wouldn't be terribly surprised to see other problems of this nature.


Jeff

commit 449d7b40f6f6be8d7f9aa7232c73b0371f0963bf
Author: Jeff Law 
Date:   Thu Apr 29 09:08:56 2021 -0600

Fix nios2 build failure

gcc

* config/nios2/nios2-protos.h (nios2_fpu_insn_enabled): Move outside
of RTX_CODE guard.

diff --git a/gcc/config/nios2/nios2-protos.h b/gcc/config/nios2/nios2-protos.h
index df5d0c97316..b831b0fdcc2 100644
--- a/gcc/config/nios2/nios2-protos.h
+++ b/gcc/config/nios2/nios2-protos.h
@@ -28,6 +28,7 @@ extern void nios2_expand_prologue (void);
 extern void nios2_expand_epilogue (bool);
 extern bool nios2_expand_return (void);
 extern void nios2_function_profiler (FILE *, int);
+extern bool nios2_fpu_insn_enabled (enum n2fpu_code);
 
 #ifdef RTX_CODE
 extern bool nios2_large_constant_p (rtx);
@@ -46,7 +47,6 @@ extern bool nios2_validate_compare (machine_mode, rtx *, rtx 
*, rtx *);
 extern bool nios2_validate_fpu_compare (machine_mode, rtx *, rtx *, rtx *,
bool);
 
-extern bool nios2_fpu_insn_enabled (enum n2fpu_code);
 extern const char * nios2_fpu_insn_asm (enum n2fpu_code);
 extern const char * nios2_add_insn_asm (rtx_insn *, rtx *);
 


Re: [PATCH] lto-wrapper: Use vec data type.

2021-04-29 Thread Martin Sebor via Gcc-patches

On 4/29/21 6:22 AM, Richard Biener via Gcc-patches wrote:

On Wed, Apr 21, 2021 at 11:12 AM Martin Liška  wrote:


Now living in the 21st century, we don't longer need using the following tuple:
cl_decoded_option **decoded_options,
  unsigned int *decoded_options_count)
but we can rather use a standard (our) vector.

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

Ready to be installed?
Thanks,
Martin

gcc/ChangeLog:

 * lto-wrapper.c (get_options_from_collect_gcc_options): Change
 return type.
 (append_option): Remove.
 (find_option): Rework to use the vector type.
 (remove_option): Remove.
 (merge_and_complain): Use vectors for cl_decoded_option data
 type arguments.
 (append_compiler_options): Likewise.
 (append_diag_options): Likewise.
 (append_linker_options): Likewise.
 (append_offload_options): Likewise.
 (compile_offload_image): Likewise.
 (compile_images_for_offload_targets): Likewise.
 (find_and_merge_options): Likewise.
 (run_gcc): Likewise.
---
  gcc/lto-wrapper.c | 384 --
  1 file changed, 165 insertions(+), 219 deletions(-)

diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 03a5922f8ea..5ccf729b249 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -138,12 +138,12 @@ maybe_unlink (const char *file)
  /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
 environment.  */

-static void
+static vec


bonus points for handling ownership transfer via returning an
auto_vec<> (not sure if possible, but maybe it is).


The auto_vec move ctor you added makes it possible.  It matches either
a plain vec argument or an auto_vec.

(The copy ctor patch I submitted earlier this week matches in contexts
where the argument cannot be moved.)

Martin





  get_options_from_collect_gcc_options (const char *collect_gcc,
- const char *collect_gcc_options,
- struct cl_decoded_option 
**decoded_options,
- unsigned int *decoded_options_count)
+ const char *collect_gcc_options)
  {
+  cl_decoded_option *decoded_options;
+  unsigned int decoded_options_count;
struct obstack argv_obstack;
const char **argv;
int argc;
@@ -156,57 +156,49 @@ get_options_from_collect_gcc_options (const char 
*collect_gcc,
argv = XOBFINISH (&argv_obstack, const char **);

decode_cmdline_options_to_array (argc, (const char **)argv, CL_DRIVER,
-  decoded_options, decoded_options_count);
+  &decoded_options, &decoded_options_count);
+  vec decoded;
+  decoded.create (decoded_options_count);
+  for (unsigned i = 0; i < decoded_options_count; ++i)
+decoded.quick_push (decoded_options[i]);
+  free (decoded_options);
+
obstack_free (&argv_obstack, NULL);
+
+  return decoded;
  }

-/* Append OPTION to the options array DECODED_OPTIONS with size
-   DECODED_OPTIONS_COUNT.  */
+/* Find option in OPTIONS based on OPT_INDEX.  NULL value is returned
+   if the option is not present.  */

-static void
-append_option (struct cl_decoded_option **decoded_options,
-  unsigned int *decoded_options_count,
-  struct cl_decoded_option *option)
+static cl_decoded_option *
+find_option (vec &options, size_t opt_index)
  {
-  ++*decoded_options_count;
-  *decoded_options
-= (struct cl_decoded_option *)
-   xrealloc (*decoded_options,
- (*decoded_options_count
-  * sizeof (struct cl_decoded_option)));
-  memcpy (&(*decoded_options)[*decoded_options_count - 1], option,
- sizeof (struct cl_decoded_option));
-}
+  for (unsigned i = 0; i < options.length (); ++i)
+if (options[i].opt_index == opt_index)
+  return &options[i];


You're returning a pointer into the vector here...


-/* Remove option number INDEX from DECODED_OPTIONS, update
-   DECODED_OPTIONS_COUNT.  */
+  return NULL;
+}

-static void
-remove_option (struct cl_decoded_option **decoded_options,
-  int index, unsigned int *decoded_options_count)
+static cl_decoded_option *
+find_option (vec &options, cl_decoded_option *option)
  {
-  --*decoded_options_count;
-  memmove (&(*decoded_options)[index + 1],
-  &(*decoded_options)[index],
-  sizeof (struct cl_decoded_option)
-  * (*decoded_options_count - index));
+  return find_option (options, option->opt_index);
  }

  /* Try to merge and complain about options FDECODED_OPTIONS when applied
 ontop of DECODED_OPTIONS.  */

  static void
-merge_and_complain (struct cl_decoded_option **decoded_options,
-   unsigned int *decoded_options_count,
-   struct cl_decoded_option *fdecoded_options,
-   unsigned int fdecoded_options_count,
-  

Regression with recent change

2021-04-29 Thread Jeff Law via Gcc-patches

This change:

985b3a6837dee7001e6b618f073ed74f0edf5787 is the first bad commit
commit 985b3a6837dee7001e6b618f073ed74f0edf5787
Author: H.J. Lu 
Date:   Mon Jun 10 09:57:15 2019 -0700

    Generate offset adjusted operation for op_by_pieces operations

    Add an overlap_op_by_pieces_p target hook for op_by_pieces operations
    between two areas of memory to generate one offset adjusted operation
    in the smallest integer mode for the remaining bytes on the last piece
    operation of a memory region to avoid doing more than one smaller
    operations.

    Pass the RTL information from the previous iteration to m_constfn in
    op_by_pieces operation so that builtin_memset_[read|gen]_str can
    generate the new RTL from the previous RTL.

    Tested on Linux/x86-64.

    gcc/

    PR middle-end/90773
    * builtins.c (builtin_memcpy_read_str): Add a dummy argument.
    (builtin_strncpy_read_str): Likewise.
    (builtin_memset_read_str): Add an argument for the previous RTL
    information and generate the new RTL from the previous RTL 
info.

    (builtin_memset_gen_str): Likewise.
    * builtins.h (builtin_strncpy_read_str): Update the prototype.
    (builtin_memset_read_str): Likewise.
    * expr.c (by_pieces_ninsns): If 
targetm.overlap_op_by_pieces_p()

    returns true, round up size and alignment to the widest integer
    mode for maximum size.
    (pieces_addr::adjust): Add a pointer to by_pieces_prev argument
    and pass it to m_constfn.
    (op_by_pieces_d): Add m_push and m_overlap_op_by_pieces.
    (op_by_pieces_d::op_by_pieces_d): Add a bool argument to
    initialize m_push.  Initialize m_overlap_op_by_pieces with
    targetm.overlap_op_by_pieces_p ().
    (op_by_pieces_d::run): Pass the previous RTL information to
    pieces_addr::adjust and generate overlapping operations if
    m_overlap_op_by_pieces is true.
    (PUSHG_P): New.
    (move_by_pieces_d::move_by_pieces_d): Updated for 
op_by_pieces_d

    change.
    (store_by_pieces_d::store_by_pieces_d): Updated for 
op_by_pieces_d

    change.
    (can_store_by_pieces): Use by_pieces_constfn on constfun.
    (store_by_pieces): Use by_pieces_constfn on constfun. Updated
    for op_by_pieces_d change.
    (clear_by_pieces_1): Add a dummy argument.
    (clear_by_pieces): Updated for op_by_pieces_d change.
    (compare_by_pieces_d::compare_by_pieces_d): Likewise.
    (string_cst_read_str): Add a dummy argument.
    * expr.h (by_pieces_constfn): Add a dummy argument.
    (by_pieces_prev): New.
    * target.def (overlap_op_by_pieces_p): New target hook.
    * config/i386/i386.c (TARGET_OVERLAP_OP_BY_PIECES_P): New.
    * doc/tm.texi.in: Add TARGET_OVERLAP_OP_BY_PIECES_P.
    * doc/tm.texi: Regenerated.


Is causing regressions on the fr30-elf port:


fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 168)
fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 174)
fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 180)
fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 186)
fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 193)
fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 201)
fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 265)
fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 274)
fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 282)
fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 289)
fr30-sim: gcc.dg/Wstringop-overflow-27.c (test for excess errors)
fr30-sim: gcc.dg/Wstringop-overflow-27.c malloc note (test for warnings, 
line 288)

fr30-sim: gcc.dg/Wstringop-overflow-27.c note (test for warnings, line 264)
fr30-sim: gcc.dg/Wstringop-overflow-27.c note (test for warnings, line 273)
fr30-sim: gcc.dg/Wstringop-overflow-27.c vla note (test for warnings, 
line 281)



I haven't done any analysis other then bisecting the regression.


Full logs are here:

http://3.14.90.209:8080/job/fr30-elf/1258/console


Thanks,

Jeff



[PATCH] Fix PR bootstrap/100327 (_divkf3.c) on PowerPC

2021-04-29 Thread Michael Meissner via Gcc-patches
Fix PR bootstrap/100327 (_divkf3.c) on PowerPC.

This patch fixes the PowerPC _divkf3.c module to use the appropriate
FLT128 constants if long double is not IEEE 128-bit.

I have tested this patch by doing a bootstrap on a little endian power9
system running Linux.  Can I check this into the trunk?

gcc/
2021-04-29  Michael Meissner  

PR bootstrap/100327
* config/rs6000/_divkf3.c (RBIG, RMIN, RMIN2, RMINSCAL): Use the
appropriate FLT128 constant if long double is not IEEE 128-bit.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797
--- /home/meissner/tmp/gcc-tmp/dDj7PV__divkc3.c 2021-04-29 10:32:37.669452599 
-0500
+++ libgcc/config/rs6000/_divkc3.c  2021-04-29 10:27:10.388470401 -0500
@@ -38,10 +38,10 @@ see the files COPYING3 and COPYING.RUNTI
 #endif
 
 #ifndef __LONG_DOUBLE_IEEE128__
-#define RBIG   (__LIBGCC_KF_MAX__ / 2)
-#define RMIN   (__LIBGCC_KF_MIN__)
-#define RMIN2  (__LIBGCC_KF_EPSILON__)
-#define RMINSCAL (1 / __LIBGCC_KF_EPSILON__)
+#define RBIG   (__FLT128_MAX__ / 2)
+#define RMIN   (__FLT128_MIN__)
+#define RMIN2  (__FLT128_EPSILON__)
+#define RMINSCAL (1 / __FLT128_EPSILON__)
 #define RMAX2  (RBIG * RMIN2)
 #else
 #define RBIG   (__LIBGCC_TF_MAX__ / 2)


Re: [PATCH v2] Add line debug info for virtual thunks [PR97937]

2021-04-29 Thread Bernd Edlinger
Hi!


I've re-based and re-tested this patch on current trunk.
Otherwise the patch is unchanged, from the previous v2 version.

This patch is fixing two issues with functions where we
do not have proper debug info:

1. Functions without line-numbers at all, are excluded from
the CU's address range in the debug info.  This makes the
debugger not display any line numbers but instead the debugger
steps into assembler.

2. Functions with a declaration line number show this line
number instead of a completely unrelated line-number from a
different function that was emitted before the current one.

So, since we are again in stage 1:
Is it OK for trunk?


Thanks
Bernd.


On 1/13/21 3:59 PM, Bernd Edlinger wrote:
> Hi,
> 
> this is a new improved version of my patch.
> The previous patch had two defects:
> It failed with -ffunction-section.  Although
> the line info was emitted, that was not working
> since the debug_ranges did not contain the
> thunk.
> And secondly it failed to address the case of
> functions without any source line information.
> 
> The new pattch addresses both cases, of DECL_IGNORED_P
> functions:
> 
> In the case of virtual thunks we emit the line
> number from the declaration.
> Other than the previous version this patch
> also explicitly adds the virtual thunk to the
> debug_ranges and debug_aranges.  If that is not
> done, the debugger does not recognize the line
> table for these functions.
> 
> But if that location info is unavailable,
> the function is explicitly removed from the
> debug_ranges and debug_aranges.  That has
> the same effect as a theoretical .noloc assembler
> directive.
> 
> 
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> Is it OK for trunk?
> 
> 
> Thanks
> Bernd.
> 
From 6f057870153999ef63d89e40cee930bf0cd1d688 Mon Sep 17 00:00:00 2001
From: Bernd Edlinger 
Date: Tue, 12 Jan 2021 16:27:53 +0100
Subject: [PATCH] Add line debug info for virtual thunks

There is no debug info when the DECL_IGNORED_P flag
is set.  But sometimes we have the line info of the
function decl, as in the case of on virtual thunks.
So instead of no line info at all, we emit at least
the location of the function decl.
On the other side, there are DECL_IGNORED_P functions
which do not have any source line info at all.
Remove those from the debug_range info, to make it
clear for the debugger that the line info for these
functions is invalid.  This has the effect that the
debugger will not step into the function without
debug info.

2021-04-29  Bernd Edlinger  

	PR ipa/97937
	* debug.h (gcc_debug_hooks): Add set_ignored_loc function pointer.
	* dwarf2out.h (dw_fde_node::ignored_debug): New data item.
	* dbxout.c (dbx_debug_hooks, xcoff_debug_hooks): Add dummy
	set_ignored_loc callbacks.
	* debug.c (do_nothing_debug_hooks): Likewise.
	* vmsdbgout.c (vmsdbg_debug_hooks): Likewise.
	* dwarf2out.c (text_section_used, cold_text_section_used): Remove.
	(in_text_section_p, last_text_label, last_cold_label,
	switch_text_ranges, switch_cold_ranges): New data items.
	(dwarf2out_note_section_used): Remove.
	(dwarf2out_begin_prologue): Set fde->ignored_debug and
	in_text_section_p.
	(mark_ignored_debug_section): New helper function.
	(dwarf2out_end_epilogue, dwarf2out_switch_text_section): Call
	mark_ignored_debug_section.
	(dwarf2_debug_hooks): Use dwarf2out_set_ignored_loc.
	(dwarf2_lineno_debug_hooks): Use dummy for set_ignored_loc.
	(size_of_aranges): Adjust formula for multi-part text ranges size.
	(output_aranges): Output multi-part text ranges.
	(dwarf2out_set_ignored_loc): New callback function.
	(dwarf2out_finish): Output multi-part text ranges.
	(dwarf2out_c_finalize): Clear new data items.
	* final.c (final_start_function_1): Call set_ignored_loc callback.
	(final_scan_insn_1): Likewise.
	* ggc-page.c (gt_ggc_mx): New helper function.
	* stringpool.c (gt_pch_nx): Likewise.
---
 gcc/dbxout.c |   2 +
 gcc/debug.c  |   1 +
 gcc/debug.h  |   4 +
 gcc/dwarf2out.c  | 244 +++
 gcc/dwarf2out.h  |   2 +
 gcc/final.c  |   8 ++
 gcc/ggc-page.c   |   6 ++
 gcc/stringpool.c |   6 ++
 gcc/vmsdbgout.c  |   1 +
 9 files changed, 224 insertions(+), 50 deletions(-)

diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 70b635c..d20527b 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -362,6 +362,7 @@ const struct gcc_debug_hooks dbx_debug_hooks =
   dbxout_end_block,
   debug_true_const_tree,	 /* ignore_block */
   dbxout_source_line,		 /* source_line */
+  debug_nothing_int_int_charstar,	 /* set_ignored_loc */
   dbxout_begin_prologue,	 /* begin_prologue */
   debug_nothing_int_charstar,	 /* end_prologue */
   debug_nothing_int_charstar,	 /* begin_epilogue */
@@ -409,6 +410,7 @@ const struct gcc_debug_hooks xcoff_debug_hooks =
   xcoffout_end_block,
   debug_true_const_tree,	 /* ignore_block */
   xcoffout_source_line,
+  debug_nothing_int_int_charstar,	 /* set_ignored_loc */
   xcoffout_begin_prologu

Re: [PATCH] Fix PR bootstrap/100327 (_divkf3.c) on PowerPC

2021-04-29 Thread Joseph Myers
On Thu, 29 Apr 2021, Michael Meissner via Gcc-patches wrote:

> Fix PR bootstrap/100327 (_divkf3.c) on PowerPC.
> 
> This patch fixes the PowerPC _divkf3.c module to use the appropriate
> FLT128 constants if long double is not IEEE 128-bit.
> 
> I have tested this patch by doing a bootstrap on a little endian power9
> system running Linux.  Can I check this into the trunk?

Why aren't the __LIBGCC_KF_* macros defined?  If there's a bug in the 
logic to define macros for all floating-point modes supported by libgcc, 
it should be fixed there.  If there's some reason that can't work, the 
commit message needs to explain in more detail.

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


Re: [PATCH] Fix PR bootstrap/100327 (_divkf3.c) on PowerPC

2021-04-29 Thread Michael Meissner via Gcc-patches
On Thu, Apr 29, 2021 at 04:31:50PM +, Joseph Myers wrote:
> On Thu, 29 Apr 2021, Michael Meissner via Gcc-patches wrote:
> 
> > Fix PR bootstrap/100327 (_divkf3.c) on PowerPC.
> > 
> > This patch fixes the PowerPC _divkf3.c module to use the appropriate
> > FLT128 constants if long double is not IEEE 128-bit.
> > 
> > I have tested this patch by doing a bootstrap on a little endian power9
> > system running Linux.  Can I check this into the trunk?
> 
> Why aren't the __LIBGCC_KF_* macros defined?  If there's a bug in the 
> logic to define macros for all floating-point modes supported by libgcc, 
> it should be fixed there.  If there's some reason that can't work, the 
> commit message needs to explain in more detail.

As Richard points out, the default libgcc_floating_mode_supported_p returns
false for these types.  If you add a target hook to return true for these
types, the c-cppbuiltin.c then aborts because there is no suffix for these
types.  There is no target hook to define strings to add new suffixes (or
prefixes).

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797


Re: [PATCH] Fix PR bootstrap/100327 (_divkf3.c) on PowerPC

2021-04-29 Thread Joseph Myers
On Thu, 29 Apr 2021, Michael Meissner via Gcc-patches wrote:

> On Thu, Apr 29, 2021 at 04:31:50PM +, Joseph Myers wrote:
> > On Thu, 29 Apr 2021, Michael Meissner via Gcc-patches wrote:
> > 
> > > Fix PR bootstrap/100327 (_divkf3.c) on PowerPC.
> > > 
> > > This patch fixes the PowerPC _divkf3.c module to use the appropriate
> > > FLT128 constants if long double is not IEEE 128-bit.
> > > 
> > > I have tested this patch by doing a bootstrap on a little endian power9
> > > system running Linux.  Can I check this into the trunk?
> > 
> > Why aren't the __LIBGCC_KF_* macros defined?  If there's a bug in the 
> > logic to define macros for all floating-point modes supported by libgcc, 
> > it should be fixed there.  If there's some reason that can't work, the 
> > commit message needs to explain in more detail.
> 
> As Richard points out, the default libgcc_floating_mode_supported_p returns
> false for these types.  If you add a target hook to return true for these
> types, the c-cppbuiltin.c then aborts because there is no suffix for these
> types.  There is no target hook to define strings to add new suffixes (or
> prefixes).

Presumably the code works with the __FLT128_* macros as used in your 
patch.  Those should expand to constants using the f128 suffix.  So there 
*is* an available suffix here (f128).  Why doesn't the code there, which 
checks all the available _FloatN and _FloatNx types for any with the right 
machine mode, find that suffix?

(The target hook indeed can't return true for modes that don't have any 
corresponding suffix, e.g. IFmode.  The modes for which it returns true 
may need to depend on the options passed to the compiler.)

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


[pushed] c++: Add testcase for already fixed PR [PR94102]

2021-04-29 Thread Marek Polacek via Gcc-patches
We correctly accept this testcase since r11-1571.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/testsuite/ChangeLog:

PR c++/94102
* g++.dg/cpp1z/class-deduction87.C: New test.
---
 gcc/testsuite/g++.dg/cpp1z/class-deduction87.C | 15 +++
 1 file changed, 15 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp1z/class-deduction87.C

diff --git a/gcc/testsuite/g++.dg/cpp1z/class-deduction87.C 
b/gcc/testsuite/g++.dg/cpp1z/class-deduction87.C
new file mode 100644
index 000..37296a435c4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/class-deduction87.C
@@ -0,0 +1,15 @@
+// PR c++/94102
+// { dg-do compile { target c++17 } }
+
+namespace std {
+  template  using decay_t = _Tp;
+}
+template  struct Merged : B... {
+  template  Merged(T... t) : B(t)... {}
+};
+template  Merged(T...) -> Merged...>;
+int main() {
+  auto l1 = [] {};
+  auto l2 = [](int i) { return i; };
+  Merged(l1, l2);
+}

base-commit: fb9f5e1028df0fe6f2ff9d220efd75970e46bff0
-- 
2.31.1



[PATCH] Don't use nullptr return from simplify_gen_subreg

2021-04-29 Thread H.J. Lu via Gcc-patches
On Thu, Apr 29, 2021 at 8:52 AM Jeff Law  wrote:
>
> This change:
>
> 985b3a6837dee7001e6b618f073ed74f0edf5787 is the first bad commit
> commit 985b3a6837dee7001e6b618f073ed74f0edf5787
> Author: H.J. Lu 
> Date:   Mon Jun 10 09:57:15 2019 -0700
>
>  Generate offset adjusted operation for op_by_pieces operations
>
>  Add an overlap_op_by_pieces_p target hook for op_by_pieces operations
>  between two areas of memory to generate one offset adjusted operation
>  in the smallest integer mode for the remaining bytes on the last piece
>  operation of a memory region to avoid doing more than one smaller
>  operations.
>
>  Pass the RTL information from the previous iteration to m_constfn in
>  op_by_pieces operation so that builtin_memset_[read|gen]_str can
>  generate the new RTL from the previous RTL.
>
>  Tested on Linux/x86-64.
>
>  gcc/
>
>  PR middle-end/90773
>  * builtins.c (builtin_memcpy_read_str): Add a dummy argument.
>  (builtin_strncpy_read_str): Likewise.
>  (builtin_memset_read_str): Add an argument for the previous RTL
>  information and generate the new RTL from the previous RTL
> info.
>  (builtin_memset_gen_str): Likewise.
>  * builtins.h (builtin_strncpy_read_str): Update the prototype.
>  (builtin_memset_read_str): Likewise.
>  * expr.c (by_pieces_ninsns): If
> targetm.overlap_op_by_pieces_p()
>  returns true, round up size and alignment to the widest integer
>  mode for maximum size.
>  (pieces_addr::adjust): Add a pointer to by_pieces_prev argument
>  and pass it to m_constfn.
>  (op_by_pieces_d): Add m_push and m_overlap_op_by_pieces.
>  (op_by_pieces_d::op_by_pieces_d): Add a bool argument to
>  initialize m_push.  Initialize m_overlap_op_by_pieces with
>  targetm.overlap_op_by_pieces_p ().
>  (op_by_pieces_d::run): Pass the previous RTL information to
>  pieces_addr::adjust and generate overlapping operations if
>  m_overlap_op_by_pieces is true.
>  (PUSHG_P): New.
>  (move_by_pieces_d::move_by_pieces_d): Updated for
> op_by_pieces_d
>  change.
>  (store_by_pieces_d::store_by_pieces_d): Updated for
> op_by_pieces_d
>  change.
>  (can_store_by_pieces): Use by_pieces_constfn on constfun.
>  (store_by_pieces): Use by_pieces_constfn on constfun. Updated
>  for op_by_pieces_d change.
>  (clear_by_pieces_1): Add a dummy argument.
>  (clear_by_pieces): Updated for op_by_pieces_d change.
>  (compare_by_pieces_d::compare_by_pieces_d): Likewise.
>  (string_cst_read_str): Add a dummy argument.
>  * expr.h (by_pieces_constfn): Add a dummy argument.
>  (by_pieces_prev): New.
>  * target.def (overlap_op_by_pieces_p): New target hook.
>  * config/i386/i386.c (TARGET_OVERLAP_OP_BY_PIECES_P): New.
>  * doc/tm.texi.in: Add TARGET_OVERLAP_OP_BY_PIECES_P.
>  * doc/tm.texi: Regenerated.
>
>
> Is causing regressions on the fr30-elf port:
>
>
> fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 168)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 174)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 180)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 186)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 193)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 201)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 265)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 274)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 282)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c  (test for warnings, line 289)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c (test for excess errors)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c malloc note (test for warnings,
> line 288)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c note (test for warnings, line 264)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c note (test for warnings, line 273)
> fr30-sim: gcc.dg/Wstringop-overflow-27.c vla note (test for warnings,
> line 281)
>
>
> I haven't done any analysis other then bisecting the regression.
>
>
> Full logs are here:
>
> http://3.14.90.209:8080/job/fr30-elf/1258/console
>

Check nullptr return from simplify_gen_subreg.  Don't use it if it is
nullptr.

OK for master?

Thanks.

-- 
H.J.
From 7722dc817fb413f5a4887c8a38ab7b30ab39a33b Mon Sep 17 00:00:00 2001
From: "H.J. Lu" 
Date: Thu, 29 Apr 2021 11:12:09 -0700
Subject: [PATCH] Don't use nullptr return from simplify_gen_subreg

Check nullptr return from simplify_gen_subreg.  Don't use it if it is
nullptr.

	PR middle-end/90773
	* builtins

[pushed] c++: unset COMPOUND_LITERAL_P [PR100079]

2021-04-29 Thread Jason Merrill via Gcc-patches
Once a CONSTRUCTOR has been digested and used as an initializer, it no
longer represents a compound literal by itself, so we can clear the flag,
letting us use it consistently to distinguish between digested and
undigested initializer-lists.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog:

* pt.c (get_template_parm_object): Add assert.
* semantics.c (finish_compound_literal): Clear TREE_HAS_CONSTRUCTOR.
* tree.c (zero_init_expr_p): Check TREE_HAS_CONSTRUCTOR.
* typeck2.c (store_init_value): Likewise.
---
 gcc/cp/cp-tree.h   | 6 --
 gcc/cp/pt.c| 2 +-
 gcc/cp/semantics.c | 8 ++--
 gcc/cp/tree.c  | 8 ++--
 gcc/cp/typeck2.c   | 6 ++
 5 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index cb254e0adea..e80902a2139 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -4407,7 +4407,7 @@ more_aggr_init_expr_args_p (const 
aggr_init_expr_arg_iterator *iter)
When appearing in a SAVE_EXPR, it means that underneath
is a call to a constructor.
 
-   When appearing in a CONSTRUCTOR, the expression is a
+   When appearing in a CONSTRUCTOR, the expression is an unconverted
compound literal.
 
When appearing in a FIELD_DECL, it means that this field
@@ -4419,7 +4419,9 @@ more_aggr_init_expr_args_p (const 
aggr_init_expr_arg_iterator *iter)
   (TREE_CODE (NODE) == CONSTRUCTOR && TREE_TYPE (NODE) == init_list_type_node)
 
 /* True if NODE is a compound-literal, i.e., a brace-enclosed
-   initializer cast to a particular type.  */
+   initializer cast to a particular type.  This is mostly only set during
+   template parsing; once the initializer has been digested into an actual
+   value of the type, the expression is represented by a TARGET_EXPR.  */
 #define COMPOUND_LITERAL_P(NODE) \
   (TREE_CODE (NODE) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (NODE))
 
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index eaf46659f85..3cd803f2f81 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7157,7 +7157,7 @@ get_template_parm_object (tree expr, tsubst_flags_t 
complain)
 return error_mark_node;
 
   /* This is no longer a compound literal.  */
-  TREE_HAS_CONSTRUCTOR (expr) = 0;
+  gcc_assert (!TREE_HAS_CONSTRUCTOR (expr));
 
   tree name = mangle_template_parm_object (expr);
   tree decl = get_global_binding (name);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 3a6468fd5f3..319a3a816ed 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3177,9 +3177,13 @@ finish_compound_literal (tree type, tree 
compound_literal,
 }
 
   /* Represent other compound literals with TARGET_EXPR so we produce
- an lvalue, but can elide copies.  */
+ a prvalue, and can elide copies.  */
   if (!VECTOR_TYPE_P (type))
-compound_literal = get_target_expr_sfinae (compound_literal, complain);
+{
+  /* The CONSTRUCTOR is now an initializer, not a compound literal.  */
+  TREE_HAS_CONSTRUCTOR (compound_literal) = false;
+  compound_literal = get_target_expr_sfinae (compound_literal, complain);
+}
 
   return compound_literal;
 }
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index a8bfd5fc053..3a20cd33fdc 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -4684,13 +4684,9 @@ zero_init_expr_p (tree t)
 return null_member_pointer_value_p (t);
   if (TREE_CODE (t) == CONSTRUCTOR)
 {
-  if (CONSTRUCTOR_IS_DEPENDENT (t)
+  if (COMPOUND_LITERAL_P (t)
  || BRACE_ENCLOSED_INITIALIZER_P (t))
-   /* Undigested, conversions might change the zeroness.
-
-  Other COMPOUND_LITERAL_P in template context are also undigested,
-  but there isn't currently a way to distinguish between them and
-  COMPOUND_LITERAL_P from non-template context that are digested.  */
+   /* Undigested, conversions might change the zeroness.  */
return false;
   for (constructor_elt &elt : CONSTRUCTOR_ELTS (t))
{
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 4e9632f6a7d..ce3016c780d 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -818,6 +818,12 @@ store_init_value (tree decl, tree init, vec** 
cleanups, int flags)
   /* Handle aggregate NSDMI in non-constant initializers, too.  */
   value = replace_placeholders (value, decl);
 
+  /* A COMPOUND_LITERAL_P CONSTRUCTOR is the syntactic form; by the time we get
+ here it should have been digested into an actual value for the type.  */
+  gcc_checking_assert (TREE_CODE (value) != CONSTRUCTOR
+  || processing_template_decl
+  || !TREE_HAS_CONSTRUCTOR (value));
+
   /* If the initializer is not a constant, fill in DECL_INITIAL with
  the bits that are constant, and then return an expression that
  will perform the dynamic initialization.  */

base-commit: 449d7b40f6f6be8d7f9aa7232c73b0371f0963bf
-- 
2.27.0



[pushed] c++: constant expressions are evaluated [PR93314]

2021-04-29 Thread Jason Merrill via Gcc-patches
My GCC 11 patch for PR93314 turned off cp_unevaluated_operand while
processing an id-expression that names a non-static data member, but the
broader issue is that in general, a constant-expression is evaluated even in
an unevaluated operand.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog:

* cp-tree.h (cp_evaluated): Add reset parm to constructor.
* parser.c (cp_parser_constant_expression): Change
allow_non_constant_p to int.  Use cp_evaluated.
(cp_parser_initializer_clause): Pass 2 to allow_non_constant_p.
* semantics.c (finish_id_expression_1): Don't mess with
cp_unevaluated_operand here.
---
 gcc/cp/cp-tree.h   |  5 +++--
 gcc/cp/parser.c| 15 +++
 gcc/cp/semantics.c | 10 --
 3 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e80902a2139..d3639e33460 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5482,9 +5482,10 @@ class cp_evaluated
 public:
   int uneval;
   int inhibit;
-  cp_evaluated ()
+  cp_evaluated (bool reset = true)
 : uneval(cp_unevaluated_operand), inhibit(c_inhibit_evaluation_warnings)
-  { cp_unevaluated_operand = c_inhibit_evaluation_warnings = 0; }
+  { if (reset)
+  cp_unevaluated_operand = c_inhibit_evaluation_warnings = 0; }
   ~cp_evaluated ()
   { cp_unevaluated_operand = uneval;
 c_inhibit_evaluation_warnings = inhibit; }
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index e1b1617da68..9603a1ef594 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2163,7 +2163,7 @@ static enum tree_code cp_parser_assignment_operator_opt
 static cp_expr cp_parser_expression
   (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false, bool = false);
 static cp_expr cp_parser_constant_expression
-  (cp_parser *, bool = false, bool * = NULL, bool = false);
+  (cp_parser *, int = 0, bool * = NULL, bool = false);
 static cp_expr cp_parser_builtin_offsetof
   (cp_parser *);
 static cp_expr cp_parser_lambda_expression
@@ -10374,13 +10374,15 @@ cp_parser_expression (cp_parser* parser, cp_id_kind * 
pidk,
   If ALLOW_NON_CONSTANT_P a non-constant expression is silently
   accepted.  If ALLOW_NON_CONSTANT_P is true and the expression is not
   constant, *NON_CONSTANT_P is set to TRUE.  If ALLOW_NON_CONSTANT_P
-  is false, NON_CONSTANT_P should be NULL.  If STRICT_P is true,
+  is false, NON_CONSTANT_P should be NULL.  If ALLOW_NON_CONSTANT_P is
+  greater than 1, this isn't really a constant-expression, only a
+  potentially constant-evaluated expression.  If STRICT_P is true,
   only parse a conditional-expression, otherwise parse an
   assignment-expression.  See below for rationale.  */
 
 static cp_expr
 cp_parser_constant_expression (cp_parser* parser,
-  bool allow_non_constant_p,
+  int allow_non_constant_p,
   bool *non_constant_p,
   bool strict_p)
 {
@@ -10416,6 +10418,11 @@ cp_parser_constant_expression (cp_parser* parser,
   parser->allow_non_integral_constant_expression_p
 = (allow_non_constant_p || cxx_dialect >= cxx11);
   parser->non_integral_constant_expression_p = false;
+
+  /* A manifestly constant-evaluated expression is evaluated even in an
+ unevaluated operand.  */
+  cp_evaluated ev (/*reset if*/allow_non_constant_p <= 1);
+
   /* Although the grammar says "conditional-expression", when not STRICT_P,
  we parse an "assignment-expression", which also permits
  "throw-expression" and the use of assignment operators.  In the case
@@ -24239,7 +24246,7 @@ cp_parser_initializer_clause (cp_parser* parser, bool* 
non_constant_p)
 {
   initializer
= cp_parser_constant_expression (parser,
-   /*allow_non_constant_p=*/true,
+   /*allow_non_constant_p=*/2,
non_constant_p);
 }
   else
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 319a3a816ed..6224f49f189 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4097,12 +4097,6 @@ finish_id_expression_1 (tree id_expression,
 
  cp_warn_deprecated_use_scopes (scope);
 
- /* In a constant-expression context, turn off cp_unevaluated_operand
-so finish_non_static_data_member will complain (93314).  */
- auto eval = make_temp_override (cp_unevaluated_operand);
- if (integral_constant_expression_p && TREE_CODE (decl) == FIELD_DECL)
-   cp_unevaluated_operand = 0;
-
  if (TYPE_P (scope))
decl = finish_qualified_id_expr (scope,
 decl,
@@ -4116,10 +4110,6 @@ finish_id_expression_1 (tree id_expression,
}
   else if (TREE_CODE (decl) == FIELD_DECL)
{
- auto eval = make_temp_override (cp_unevaluated_operand);
- if (integral_constant_expression_p)
-   cp_une

[pushed] c++: ICE with anonymous union [PR97974]

2021-04-29 Thread Jason Merrill via Gcc-patches
While working on the GCC 11 patch, it occurred to me that we could move
the errors about invalid members from finish_struct_anon_r to here, so we
properly get a diagnostic in g++.law/union4.C.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog:

PR c++/97974
* class.c (finish_struct_anon_r): Drop complain parm.
Remove non-field diagnostic.
(finish_struct_anon): Adjust.
* decl.c (fixup_anonymous_aggr): Move non-field diagnostic here.

gcc/testsuite/ChangeLog:

PR c++/97974
* g++.old-deja/g++.law/union4.C: Add expected diagnostic.
---
 gcc/cp/class.c  | 34 ++--
 gcc/cp/decl.c   | 45 ++---
 gcc/testsuite/g++.old-deja/g++.law/union4.C |  2 +-
 3 files changed, 44 insertions(+), 37 deletions(-)

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 2cf527e4a84..d693b438668 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3023,7 +3023,7 @@ warn_hidden (tree t)
 /* Recursive helper for finish_struct_anon.  */
 
 static void
-finish_struct_anon_r (tree field, bool complain)
+finish_struct_anon_r (tree field)
 {
   for (tree elt = TYPE_FIELDS (TREE_TYPE (field)); elt; elt = DECL_CHAIN (elt))
 {
@@ -3039,34 +3039,6 @@ finish_struct_anon_r (tree field, bool complain)
  || TYPE_UNNAMED_P (TREE_TYPE (elt
continue;
 
-  if (complain
- && (TREE_CODE (elt) != FIELD_DECL
- || (TREE_PRIVATE (elt) || TREE_PROTECTED (elt
-   {
- /* We already complained about static data members in
-finish_static_data_member_decl.  */
- if (!VAR_P (elt))
-   {
- auto_diagnostic_group d;
- if (permerror (DECL_SOURCE_LOCATION (elt),
-TREE_CODE (TREE_TYPE (field)) == UNION_TYPE
-? "%q#D invalid; an anonymous union may "
-"only have public non-static data members"
-: "%q#D invalid; an anonymous struct may "
-"only have public non-static data members", elt))
-   {
- static bool hint;
- if (flag_permissive && !hint)
-   {
- hint = true;
- inform (DECL_SOURCE_LOCATION (elt),
- "this flexibility is deprecated and will be "
- "removed");
-   }
-   }
-   }
-   }
-
   TREE_PRIVATE (elt) = TREE_PRIVATE (field);
   TREE_PROTECTED (elt) = TREE_PROTECTED (field);
 
@@ -3084,7 +3056,7 @@ finish_struct_anon_r (tree field, bool complain)
 int j=A().i;  */
   if (DECL_NAME (elt) == NULL_TREE
  && ANON_AGGR_TYPE_P (TREE_TYPE (elt)))
-   finish_struct_anon_r (elt, /*complain=*/false);
+   finish_struct_anon_r (elt);
 }
 }
 
@@ -3103,7 +3075,7 @@ finish_struct_anon (tree t)
 
   if (DECL_NAME (field) == NULL_TREE
  && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
-   finish_struct_anon_r (field, /*complain=*/true);
+   finish_struct_anon_r (field);
 }
 }
 
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 60dc2bf182d..e51c1b09652 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5005,12 +5005,47 @@ fixup_anonymous_aggr (tree t)
   TYPE_HAS_COPY_ASSIGN (t) = 0;
   TYPE_HAS_CONST_COPY_ASSIGN (t) = 0;
 
-  /* Splice the implicitly generated functions out of TYPE_FIELDS.  */
+  /* Splice the implicitly generated functions out of TYPE_FIELDS and diagnose
+ invalid members.  */
   for (tree probe, *prev_p = &TYPE_FIELDS (t); (probe = *prev_p);)
-if (TREE_CODE (probe) == FUNCTION_DECL && DECL_ARTIFICIAL (probe))
-  *prev_p = DECL_CHAIN (probe);
-else
-  prev_p = &DECL_CHAIN (probe);
+{
+  if (TREE_CODE (probe) == FUNCTION_DECL && DECL_ARTIFICIAL (probe))
+   *prev_p = DECL_CHAIN (probe);
+  else
+   prev_p = &DECL_CHAIN (probe);
+
+  if (DECL_ARTIFICIAL (probe)
+ && (!DECL_IMPLICIT_TYPEDEF_P (probe)
+ || TYPE_ANON_P (TREE_TYPE (probe
+   continue;
+
+  if (TREE_CODE (probe) != FIELD_DECL
+ || (TREE_PRIVATE (probe) || TREE_PROTECTED (probe)))
+   {
+ /* We already complained about static data members in
+finish_static_data_member_decl.  */
+ if (!VAR_P (probe))
+   {
+ auto_diagnostic_group d;
+ if (permerror (DECL_SOURCE_LOCATION (probe),
+TREE_CODE (t) == UNION_TYPE
+? "%q#D invalid; an anonymous union may "
+"only have public non-static data members"
+: "%q#D invalid; an anonymous struct may "
+"only have public non-static data members", probe))
+   {
+ static bool hint;
+ if (flag_permis

[pushed] c++: Fix friend attributes [PR51344]

2021-04-29 Thread Jason Merrill via Gcc-patches
51344 was a problem with calling save_template_attributes twice for the same
friend function: once from do_friend and once from grokmethod.  The 2012
patch for the bug avoided creating an infinite loop when this happens, but
it's better to avoid the duplication in the first place.  This also restores
the dependent attributes to the beginning of the attribute list, as
originally intended.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog:

PR c++/51344
* decl2.c (grokfield): Call cplus_decl_attributes for friend.
(save_template_attributes): Use chainon.
* friend.c (do_friend): Remove attrlist parm.
* cp-tree.h (do_friend): Adjust.
* class.c (add_implicitly_declared_members): Adjust.
* decl.c (grokdeclarator): Adjust.
---
 gcc/cp/cp-tree.h |  2 +-
 gcc/cp/class.c   |  2 +-
 gcc/cp/decl.c|  3 +--
 gcc/cp/decl2.c   | 10 +++---
 gcc/cp/friend.c  |  9 +
 gcc/cp/pt.c  | 51 ++--
 6 files changed, 34 insertions(+), 43 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d3639e33460..368d9f5adf7 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6848,7 +6848,7 @@ extern void mark_exp_read (tree);
 extern int is_friend   (tree, tree);
 extern void make_friend_class  (tree, tree, bool);
 extern void add_friend (tree, tree, bool);
-extern tree do_friend  (tree, tree, tree, tree,
+extern tree do_friend  (tree, tree, tree,
 enum overload_flags, bool);
 
 extern void set_global_friend  (tree);
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index d693b438668..dad3849d44f 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3314,7 +3314,7 @@ add_implicitly_declared_members (tree t, tree* 
access_decls,
bool is_friend = DECL_CONTEXT (space) != t;
if (is_friend)
  do_friend (NULL_TREE, DECL_NAME (eq), eq,
-NULL_TREE, NO_SPECIAL, true);
+NO_SPECIAL, true);
else
  {
add_method (t, eq, false);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index e51c1b09652..d1e73373660 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -13758,8 +13758,7 @@ grokdeclarator (const cp_declarator *declarator,
  }
 
decl = do_friend (ctype, unqualified_id, decl,
- *attrlist, flags,
- funcdef_flag);
+ flags, funcdef_flag);
return decl;
  }
else
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a82960fb39c..89f874a32cc 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -974,7 +974,11 @@ grokfield (const cp_declarator *declarator,
   if ((TREE_CODE (value) == FUNCTION_DECL
|| TREE_CODE (value) == TEMPLATE_DECL)
   && DECL_CONTEXT (value) != current_class_type)
-return value;
+{
+  if (attrlist)
+   cplus_decl_attributes (&value, attrlist, 0);
+  return value;
+}
 
   /* Need to set this before push_template_decl.  */
   if (VAR_P (value))
@@ -1278,9 +1282,9 @@ save_template_attributes (tree *attr_p, tree *decl_p, int 
flags)
 
   tree old_attrs = *q;
 
-  /* Merge the late attributes at the beginning with the attribute
+  /* Place the late attributes at the beginning of the attribute
  list.  */
-  late_attrs = merge_attributes (late_attrs, *q);
+  late_attrs = chainon (late_attrs, *q);
   if (*q != late_attrs
   && !DECL_P (*decl_p)
   && !(flags & ATTR_FLAG_TYPE_IN_PLACE))
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index ee73adb1677..4f6288414d9 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -475,7 +475,7 @@ make_friend_class (tree type, tree friend_type, bool 
complain)
 
 tree
 do_friend (tree ctype, tree declarator, tree decl,
-  tree attrlist, enum overload_flags flags,
+  enum overload_flags flags,
   bool funcdef_flag)
 {
   gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
@@ -488,13 +488,6 @@ do_friend (tree ctype, tree declarator, tree decl,
 error ("friend declaration %qD may not have virt-specifiers",
   decl);
 
-  /* Unfortunately, we have to handle attributes here.  Normally we would
- handle them in start_decl_1, but since this is a friend decl start_decl_1
- never gets to see it.  */
-
-  /* Set attributes here so if duplicate decl, will have proper attributes.  */
-  cplus_decl_attributes (&decl, attrlist, 0);
-
   if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)
 {
   declarator = TREE_OPERAND (declarator, 0);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3cd803f2f81..e65f7469484 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11659,7 +11659,6 @@ static bool
 apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,

[pushed] c++: Use empty field in constexpr eval.

2021-04-29 Thread Jason Merrill via Gcc-patches
In discussion of PR98463, Jakub noted that cxx_fold_indirect_ref_1 was
bailing out early for empty bases even when we do have fields for them (in
C++17 mode or later).  This corrects that.

Tested x86_64-pc-linux-gnu, applying to trunk.

gcc/cp/ChangeLog:

* constexpr.c (cxx_fold_indirect_ref_1): Only set *empty_base if we
don't find a field.
---
 gcc/cp/constexpr.c | 38 ++
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index fa7eaed945a..9481a5bfd3c 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -4734,28 +4734,17 @@ cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, 
location_t loc, tree type,
 {
   tree optype = TREE_TYPE (op);
   unsigned HOST_WIDE_INT const_nunits;
-  if (off == 0)
-{
-  if (similar_type_p (optype, type))
-   return op;
-  /* Also handle conversion to an empty base class, which
-is represented with a NOP_EXPR.  */
-  /* *(foo *)&complexfoo => __real__ complexfoo */
-  else if (TREE_CODE (optype) == COMPLEX_TYPE
-  && similar_type_p (type, TREE_TYPE (optype)))
-   return build1_loc (loc, REALPART_EXPR, type, op);
-}
-  /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
+  if (off == 0 && similar_type_p (optype, type))
+return op;
   else if (TREE_CODE (optype) == COMPLEX_TYPE
-  && similar_type_p (type, TREE_TYPE (optype))
-  && tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off)
-return build1_loc (loc, IMAGPART_EXPR, type, op);
-  if (is_empty_class (type)
-  && CLASS_TYPE_P (optype)
-  && DERIVED_FROM_P (type, optype))
+  && similar_type_p (type, TREE_TYPE (optype)))
 {
-  *empty_base = true;
-  return op;
+  /* *(foo *)&complexfoo => __real__ complexfoo */
+  if (off == 0)
+   return build1_loc (loc, REALPART_EXPR, type, op);
+  /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
+  else if (tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off)
+   return build1_loc (loc, IMAGPART_EXPR, type, op);
 }
   /* ((foo*)&vectorfoo)[x] => BIT_FIELD_REF */
   else if (VECTOR_TYPE_P (optype)
@@ -4834,6 +4823,15 @@ cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, 
location_t loc, tree type,
  return ret;
  }
  }
+  /* Also handle conversion to an empty base class, which
+is represented with a NOP_EXPR.  */
+  if (is_empty_class (type)
+ && CLASS_TYPE_P (optype)
+ && DERIVED_FROM_P (type, optype))
+   {
+ *empty_base = true;
+ return op;
+   }
 }
 
   return NULL_TREE;

base-commit: 449d7b40f6f6be8d7f9aa7232c73b0371f0963bf
prerequisite-patch-id: 39f358d55a4ba496b673d13e00215152266caa54
prerequisite-patch-id: f0d6c56fe2c9e16572f0760fb223f6d4df3e859e
prerequisite-patch-id: 8188da37013371fd5864b80fb0cc5ad4596a1ff6
prerequisite-patch-id: f9c0d88147525dd47cab54ddfdde9341b7b10a4c
-- 
2.27.0



[PATCH] Disable section anchors for VAR_DECLs if -fdata-sections

2021-04-29 Thread David Edelsohn via Gcc-patches
-fdata-sections places data symbols into their own, unique, named sections.
-fsection-anchors create an anchor to access neighboring symbols
within a section.

When both are enabled, a separate section anchor is created for each
symbol, which provides no benefit.

This patch updates the common gating function use_blocks_for_decl_p() to
return false if -fdata-sections is enabled.  Constants still can
be placed into
object blocks because constants use a separate, different gating function.

Bootstrapped on powerpc-ibm-aix7.2.3.0

Okay?

Thanks, David

gcc/ChangeLog:

* varasm.c (use_blocks_for_decl_p): Don't use section anchors
for VAR_DECLs if -fdata-sections enabled.

diff --git a/gcc/varasm.c b/gcc/varasm.c
index 3ecf9e039bb..ac256ef65e5 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1340,6 +1340,12 @@ use_blocks_for_decl_p (tree decl)
 {
   struct symtab_node *snode;

+  /* Don't create object blocks if each DECL is placed into a separate
+ section because that will uselessly create a section anchor for
+ each DECL.  */
+  if (flag_data_sections)
+return false;
+
   /* Only data DECLs can be placed into object blocks.  */
   if (!VAR_P (decl) && TREE_CODE (decl) != CONST_DECL)
 return false;


Re: preprocessor: Handle digit separators in #line [PR82359]

2021-04-29 Thread Joseph Myers
I've now committed this patch as preparation for further digit separator 
fixes and enabling digit separators for C2x, but would still welcome any 
C++ maintainer comments.

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


New Swedish PO file for 'gcc' (version 11.1.0)

2021-04-29 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 Swedish team of translators.  The file is available at:

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

(This file, 'gcc-11.1.0.sv.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 V7 4/7] CTF/BTF debug formats

2021-04-29 Thread Indu Bhagat via Gcc-patches

Hello,

On 4/29/21 5:10 AM, Richard Biener wrote:

On Thu, 29 Apr 2021, Jose E. Marchesi wrote:


This commit introduces support for generating CTF debugging
information and BTF debugging information from GCC.


Comments inline.


Thanks for your reviews.

My responses and questions inline at respective points.

Indu


+void
+btf_finalize (void)
+{
+  btf_info_section = NULL;
+
+  /* Clear preprocessing state.  */
+  num_vars_added = 0;
+  holes.release ();
+  voids.release ();
+  funcs.release ();
+  for (size_t i = 0; i < datasecs.length (); i++)
+datasecs[i].entries.release ();
+  datasecs.release ();
+
+  ggc_free (btf_var_ids);


I think you want to NULL btf_var_ids after this.



ACK. Will take care of this and the other comments' occurences in btfout.c.


diff --git a/gcc/ctfc.h b/gcc/ctfc.h
new file mode 100644
index 000..092faa0b2c3
--- /dev/null
+++ b/gcc/ctfc.h
@@ -0,0 +1,413 @@
+/* ctfc.h - Declarations and definitions related to the CTF container.
+   Copyright (C) 2019,2021 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+.  */
+
+/* This file defines the data structures and functions used by the compiler
+   to generate the CTF debug info.  The definitions below are compiler internal
+   representations and closely reflect the CTF format requirements in .
+
+   The contents of the CTF container are used eventually for emission of both
+   CTF (ctfout.c) and BTF debug info (btfout.c), as the two type debug formats
+   are close cousins.  */
+
+#ifndef GCC_CTFC_H
+#define GCC_CTFC_H 1
+
+#include "config.h"
+#include "system.h"
+#include "tree.h"
+#include "fold-const.h"
+#include "dwarf2ctf.h"
+#include "ctf.h"
+#include "btf.h"
+
+/* Invalid CTF type ID definition.  */
+
+#define CTF_NULL_TYPEID 0
+
+/* Value to start generating the CTF type ID from.  */
+
+#define CTF_INIT_TYPEID 1
+
+/* CTF type ID.  */
+
+typedef unsigned long ctf_id_t;
+
+/* CTF string table element (list node).  */
+
+typedef struct GTY ((chain_next ("%h.cts_next"))) ctf_string


I know that DWARF takes the lead here but do all these have to
live in GC memory?  The reason the DWARF bits do is that they
point to 'tree' and that trees point to DIEs.



Not entirely sure what you mean here ? Do you mean to not tag it as GC 
root and avoid traversal for GC marking the individual strings ?



+/* CTF container structure.
+   It is the context passed around when generating ctf debug info.  There is
+   one container per translation unit.  */
+
+typedef struct GTY (()) ctf_container
+{
+  /* CTF Preamble.  */
+  unsigned short ctfc_magic;
+  unsigned char ctfc_version;
+  unsigned char ctfc_flags;
+  unsigned int ctfc_cuname_offset;
+
+  /* CTF types.  */
+  hash_table  * GTY (()) ctfc_types;
+  /* CTF variables.  */
+  hash_table  * GTY (()) ctfc_vars;
+
+  /* CTF string table.  */
+  ctf_strtable_t ctfc_strtable;
+  /* Auxilliary string table.  At this time, used for keeping func arg names
+ for BTF.  */
+  ctf_strtable_t ctfc_aux_strtable;
+
+  unsigned long ctfc_num_types;


You are using unsigned char, short and long - if those should correspond
to types with a specific bit width then please use stdint types.  GCC
still runs on 32bit hosts where 'unsigned long' can be 32bits.

Not sure if the number of types can be bigger than 2 billion on 64bit
hosts ... (GCC is happily using unsigned int for such counts elsewhere,
like DECL_UID is just unsigned int).



Ok. I will take a look and switch to stdint types where applicable.


+  unsigned long ctfc_num_stypes;
+  unsigned long ctfc_num_global_funcs;
+  unsigned long ctfc_num_global_objts;
+
+  /* Number of vlen bytes - the variable length portion after ctf_type_t and
+ ctf_stype_t in the CTF section.  This is used to calculate the offsets in
+ the CTF header.  */
+  unsigned long ctfc_num_vlen_bytes;
+
+  /* Next CTF type id to assign.  */
+  ctf_id_t ctfc_nextid;
+  /* List of pre-processed CTF Variables.  CTF requires that the variables
+ appear in the sorted order of their names.  */
+  ctf_dvdef_t ** GTY ((length ("%h.ctfc_vars ? %h.ctfc_vars->elements () : 
0"))) ctfc_vars_list;
+  /* List of pre-processed CTF types.  CTF requires that a shared type must
+ appear before the type that uses it.  For the compiler, this means types
+ are emitted in sorted order of their type IDs.  */
+  ctf_dtdef_t ** GTY ((length ("%h.ctfc_types ? %

[PATCH] i386: Optimize carry flag comparisons a bit

2021-04-29 Thread Uros Bizjak via Gcc-patches
In ix86_int_compare, opportunistically swap operands of GTU and LEU comparisons
to emit carry flag comparison, with the expectation that the comparison will
combine to *add3_carry_0 or *sub3_carry_0 insn pattern.

Do not use ix86_expand_carry_flag_compare because this function prefers
carry flag comparisons too much - it forces the constants into registers
and/or emits additional arithmetic instructions to convert simple
comparisons into carry flag comparisons - but simply swap operands to
convert GTU and LEU comparisons into GEU and LTU ones.

Also, change the insn predicates of *add3_carry_0 and
*sub3_carry_0 insn patterns to allow more combine opportunities
with memory operands.

2021-04-29  Uroš Bizjak  

gcc/
* config/i386/i386-expand.c (ix86_expand_int_compare):
Swap operands of GTU and LEU comparison to emit carry flag comparison.
* config/i386/i386.md (*add3_carry_0): Change insn
predicate to allow more combine opportunities with memory operands.
(*sub3_carry_0): Ditto.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Pushed to master.

Uros.
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index 76990628150..fee4d07b7fd 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -2658,6 +2658,14 @@ ix86_expand_int_compare (enum rtx_code code, rtx op0, 
rtx op1)
   machine_mode cmpmode;
   rtx tmp, flags;
 
+  /* Swap operands to emit carry flag comparison.  */
+  if ((code == GTU || code == LEU)
+  && nonimmediate_operand (op1, VOIDmode))
+{
+  std::swap (op0, op1);
+  code = swap_condition (code);
+}
+
   cmpmode = SELECT_CC_MODE (code, op0, op1);
   flags = gen_rtx_REG (cmpmode, FLAGS_REG);
 
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index eff189f17b4..b7f3e36a70c 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -6777,7 +6777,7 @@ (define_insn "*add3_carry_0"
[(match_operand 2 "flags_reg_operand") (const_int 0)])
  (match_operand:SWI 1 "nonimmediate_operand" "0")))
(clobber (reg:CC FLAGS_REG))]
-  "ix86_unary_operator_ok (PLUS, mode, operands)"
+  "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
   "adc{}\t{$0, %0|%0, 0}"
   [(set_attr "type" "alu")
(set_attr "use_carry" "1")
@@ -6919,7 +6919,7 @@ (define_insn "*sub3_carry_0"
  (match_operator:SWI 3 "ix86_carry_flag_operator"
[(match_operand 2 "flags_reg_operand") (const_int 0)])))
(clobber (reg:CC FLAGS_REG))]
-  "ix86_unary_operator_ok (MINUS, mode, operands)"
+  "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
   "sbb{}\t{$0, %0|%0, 0}"
   [(set_attr "type" "alu")
(set_attr "use_carry" "1")


Re: [PATCH, libstdc++] GLIBCXX_HAVE_INT64_T

2021-04-29 Thread David Edelsohn via Gcc-patches
On Fri, Jan 8, 2021 at 1:37 PM Jonathan Wakely  wrote:
>
> On 06/01/21 19:41 -0500, David Edelsohn wrote:
> >Thanks for clarifying the issue.
> >
> >As you implicitly point out, GCC knows the type of INT64 and defines
> >the macro __INT64_TYPE__ .  The revised code can use that directly,
> >such as:
> >
> >#if defined(_GLIBCXX_HAVE_INT64_T_LONG) \
> >|| defined(_GLIBCXX_HAVE_INT64_T_LONG_LONG)
> >   typedef __INT64_TYPE__   streamoff;
> > #elif defined(_GLIBCXX_HAVE_INT64_T)
> >   typedef int64_t streamoff;
> > #else
> >   typedef long long streamoff;
> > #endif
> >
> >Are there any additional issues not addressed by that approach, other
> >than possible further simplification?
>
> That avoids the ABI break that Jakub pointed out. But I think we can
> simplify it further, as in the attached patch.
>
> This uses __INT64_TYPE__ if that's defined, and long long otherwise. I
> think that should be equivalent in all practical cases (I can imagine
> some strange target where __INT64_TYPE__ is defined by the compiler,
> but int64_t isn't defined when the configure checks look for it, and
> so the current code would use long long and with my patch would use
> __INT64_TYPE__ which could be long ... but I think in practice that's
> unlikely. It was probably more likely in older releases where the
> configure test would have been done with -std=gnu++98 and so int64_t
> might not have been declared by libc's , but if that was the
> case then any ABI break it caused happened years ago.

Hi, Jonathan

Polite ping.

Now that GCC 11.1 has been released, can this patch be applied to
libstdc++?  As I replied at the time to Jakub's concerns, both Clang
(since 3.0.0) and ICC (since at least 16.0.0) have defined
__INT64_TYPE__ .

Thanks, David


Re: [PATCH, libstdc++] GLIBCXX_HAVE_INT64_T

2021-04-29 Thread Jonathan Wakely via Gcc-patches

On 29/04/21 16:06 -0400, David Edelsohn wrote:

On Fri, Jan 8, 2021 at 1:37 PM Jonathan Wakely  wrote:


On 06/01/21 19:41 -0500, David Edelsohn wrote:
>Thanks for clarifying the issue.
>
>As you implicitly point out, GCC knows the type of INT64 and defines
>the macro __INT64_TYPE__ .  The revised code can use that directly,
>such as:
>
>#if defined(_GLIBCXX_HAVE_INT64_T_LONG) \
>|| defined(_GLIBCXX_HAVE_INT64_T_LONG_LONG)
>   typedef __INT64_TYPE__   streamoff;
> #elif defined(_GLIBCXX_HAVE_INT64_T)
>   typedef int64_t streamoff;
> #else
>   typedef long long streamoff;
> #endif
>
>Are there any additional issues not addressed by that approach, other
>than possible further simplification?

That avoids the ABI break that Jakub pointed out. But I think we can
simplify it further, as in the attached patch.

This uses __INT64_TYPE__ if that's defined, and long long otherwise. I
think that should be equivalent in all practical cases (I can imagine
some strange target where __INT64_TYPE__ is defined by the compiler,
but int64_t isn't defined when the configure checks look for it, and
so the current code would use long long and with my patch would use
__INT64_TYPE__ which could be long ... but I think in practice that's
unlikely. It was probably more likely in older releases where the
configure test would have been done with -std=gnu++98 and so int64_t
might not have been declared by libc's , but if that was the
case then any ABI break it caused happened years ago.


Hi, Jonathan

Polite ping.

Now that GCC 11.1 has been released, can this patch be applied to
libstdc++?  As I replied at the time to Jakub's concerns, both Clang
(since 3.0.0) and ICC (since at least 16.0.0) have defined
__INT64_TYPE__ .


Yes, I'll push that tomorrow.



Re: [PATCH] c++: Implement P2367 changes to avoid some list-initialization

2021-04-29 Thread Jonathan Wakely via Gcc-patches

On 29/04/21 11:04 -0400, Patrick Palka via Libstdc++ wrote:

This implements the wording changes of P2367R0 "Remove misuses of
list-initialization from Clause 24", modulo the parts that depend
on P1739R4 which we don't yet implement (due to LWG 3407).

Tested on x86_64-pc-linux-gnu, does this look OK for trunk?


OK, thanks.



Re: [PATCH] Fix PR bootstrap/100327 (_divkf3.c) on PowerPC

2021-04-29 Thread Michael Meissner via Gcc-patches
On Thu, Apr 29, 2021 at 04:48:07PM +, Joseph Myers wrote:
> On Thu, 29 Apr 2021, Michael Meissner via Gcc-patches wrote:
> 
> > On Thu, Apr 29, 2021 at 04:31:50PM +, Joseph Myers wrote:
> > > On Thu, 29 Apr 2021, Michael Meissner via Gcc-patches wrote:
> > > 
> > > > Fix PR bootstrap/100327 (_divkf3.c) on PowerPC.
> > > > 
> > > > This patch fixes the PowerPC _divkf3.c module to use the appropriate
> > > > FLT128 constants if long double is not IEEE 128-bit.
> > > > 
> > > > I have tested this patch by doing a bootstrap on a little endian power9
> > > > system running Linux.  Can I check this into the trunk?
> > > 
> > > Why aren't the __LIBGCC_KF_* macros defined?  If there's a bug in the 
> > > logic to define macros for all floating-point modes supported by libgcc, 
> > > it should be fixed there.  If there's some reason that can't work, the 
> > > commit message needs to explain in more detail.
> > 
> > As Richard points out, the default libgcc_floating_mode_supported_p returns
> > false for these types.  If you add a target hook to return true for these
> > types, the c-cppbuiltin.c then aborts because there is no suffix for these
> > types.  There is no target hook to define strings to add new suffixes (or
> > prefixes).
> 
> Presumably the code works with the __FLT128_* macros as used in your 
> patch.  Those should expand to constants using the f128 suffix.  So there 
> *is* an available suffix here (f128).  Why doesn't the code there, which 
> checks all the available _FloatN and _FloatNx types for any with the right 
> machine mode, find that suffix?

Good point.  I will submit a new patch after this message.

> (The target hook indeed can't return true for modes that don't have any 
> corresponding suffix, e.g. IFmode.  The modes for which it returns true 
> may need to depend on the options passed to the compiler.)

Yes that is the tricky part.  Due to decisions made earlier, if long double
uses the IEEE 128-bit format, the _Float128/__float128 support uses TFmode and
not KFmode.  But I was able to build bootstrap compiler with normal IBM
extended long double, and a non-bootstrap compiler with IEEE 128-bit.  I will
build the bootstrap IEEE 128-bit compiler shortly.

-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797


[PATCH, V2] Define KFmode constants for libgcc.

2021-04-29 Thread Michael Meissner via Gcc-patches
[PATCH, V2] Define KFmode constants for libgcc.

This patch defines the constants needed for libgcc for the PowerPC
specific IEEE 128-bit floating point types (KFmode).  The 4/28 changes to
libgcc need these constants defined.

We only define the KFmode constants if IEEE 128-bit floating point is
supported, but long double does not use the IEEE 128-bit format.  If long
double uses the IEEE 128-bit format, it will use TFmode and not KFmode.

With this patch, we don't have to modify _divkc3.c to use the FLT128
constants.  Instead, the -fbuilting-libgcc option will build the appropriate
__LIBGCC_KF_* macros.

I have built a bootstrap compiler on a little endian power9 system and it
finished.  Previously it had crashed in building libgcc.  I also build a
non-bootstrap compiler where the default long double format is IEEE 128-bit and
it built ok

Can I check this into the trunk for GCC 12?

gcc/
2021-04-29  Michael Meissner  

PR bootstrap/100327
* config/rs6000/rs6000.c
(TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P): Define.
(rs6000_iibgcc_floating_mode_supported_p): New target hook.
---
 gcc/config/rs6000/rs6000.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index cdeb049986f..23485027d85 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1569,6 +1569,10 @@ static const struct attribute_spec 
rs6000_attribute_table[] =
 #undef TARGET_SCALAR_MODE_SUPPORTED_P
 #define TARGET_SCALAR_MODE_SUPPORTED_P rs6000_scalar_mode_supported_p
 
+#undef TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P
+#define TARGET_LIBGCC_FLOATING_MODE_SUPPORTED_P \
+  rs6000_libgccc_floating_mode_supported_p
+
 #undef TARGET_VECTOR_MODE_SUPPORTED_P
 #define TARGET_VECTOR_MODE_SUPPORTED_P rs6000_vector_mode_supported_p
 
@@ -24089,6 +24093,31 @@ rs6000_scalar_mode_supported_p (scalar_mode mode)
 return default_scalar_mode_supported_p (mode);
 }
 
+/* Target hook for libgcc_floating_mode_supported_p.  */
+
+static bool
+rs6000_libgccc_floating_mode_supported_p (scalar_float_mode mode)
+{
+  switch (mode)
+{
+case E_SFmode:
+case E_DFmode:
+case E_TFmode:
+  return true;
+
+  /* We only return true for KFmode if IEEE 128-bit types are supported, 
and
+if long double does not use the IEEE 128-bit format.  If long double
+uses the IEEE 128-bit format, it will use TFmode and not KFmode.
+Because the code will not use KFmode in that case, there will be aborts
+because it can't find KFmode in the Floatn types.  */
+case E_KFmode:
+  return TARGET_FLOAT128_TYPE && !TARGET_IEEEQUAD;
+
+default:
+  return false;
+}
+}
+
 /* Target hook for vector_mode_supported_p.  */
 static bool
 rs6000_vector_mode_supported_p (machine_mode mode)
-- 
2.22.0


-- 
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797


Re: [PATCH] [RISCV] Add Pattern for builtin overflow

2021-04-29 Thread Jim Wilson
On Wed, Apr 28, 2021 at 4:04 PM Andrew Waterman  wrote:

> > This is a good suggestion, but in the interests of making forward
> progress here, I'd like to accept the patch and then file these as
> bugzillas as ways to further improve the patch.
>
> Agreed, these potential improvements are definitely not blockers.
>

Turns out Levy had time to work on the patch after all, and submitted a
fourth version with your improvements.

Jim


Re: [PATCH V7 4/7] CTF/BTF debug formats

2021-04-29 Thread Indu Bhagat via Gcc-patches

On 4/29/21 1:02 PM, Indu Bhagat wrote:



+{
+  dw_die_ref c;
+
+  if (!ctf_do_die (die))
+    return;
+
+  FOR_EACH_CHILD (die, c, ctf_do_die (c));
+}
+
  /* Perform any cleanups needed after the early debug generation pass
 has run.  */
@@ -32471,6 +32491,16 @@ dwarf2out_early_finish (const char *filename)
    print_die (comp_unit_die (), dump_file);
  }
+  /* Generate CTF debug info.  */
+  if ((ctf_debug_info_level > CTFINFO_LEVEL_NONE
+   || btf_debug_info_level > BTFINFO_LEVEL_NONE) && lang_GNU_C ())
+    {
+  ctf_debug_init ();
+  debug_format_do_cu (comp_unit_die ());
+  for (limbo_die_node *node = limbo_die_list; node; node = 
node->next)

+    debug_format_do_cu (node->die);
+    }
+


Since you have support to copy .ctf sections for LTO you have to write
those here.  And you have to care for fat LTO objects which for dwarf
results in two sets of .debug_info - I suppose for CTF you can share
the section for the fat and the LTO part though?  So why are you
writing the CFT debug in dwarf2out_finish now?


The change to writing CTF/BTF debug information in dwarf2out_finish 
instead of dwarf2out_early_finish, at this time, was driven by the needs 
of BTF. A BTF section has entries of kind BTF_KIND_DATASEC which 
essentially give information about which section a variable is in (.bss, 
.rodata, .text). This information is available later on in the 
compilation process and hence, BTF needed a longer lifetime of the CTF 
container to update the information in the CTF container. In general, 
keeping any future needs that may come up, it seemed like a better 
design point to defer the ctf_debug_finalize to dwarf2out_finish 
(assuming we work out it out with LTO).


Umm..what I wrote wrt BTF was incorrect. The larger lifetime of CTF 
container is currently needed specifically for the BPF CO-RE 
relocations. They will be generated in the BPF backend, but only at 
'expand' time, which is much later than when dwarf2out_early_finish 
happens. Strictly speaking, for BTF only (without BPF CO-RE support, 
which will go in .BTF.ext) it is not necessary.




Can you elaborate on what it means to say "we have two sets of 
.debug_info for fat LTO objects" ?


I am also lost a bit by the comment on "share the section for the fat 
and LTO part though". If it helps, from what I can reason, I can add 
that I do not see how in LTO mode, the CTF of a compilation unit will 
shift at all between the compile phase and the LTO phase. This should be 
true for CTF V3 atleast. But for V4, this may not be true...


For a moment, for the sake of this question, if we establish that 
CTF/BTF generation always feeds off DWARF DIEs (so there is no need to 
access type/decl tree nodes), what will it take to keep LTO support 
while keeping ctf_debug_finalize in dwarf2out_finish ?




  1   2   >