[PATCH] Fix LTO type mismatch warning on transparent union

2024-05-29 Thread Eric Botcazou
Hi,

Ada doesn't have an equivalent to transparent union types in GNU C so, when it 
needs to interface a C function that takes a parameter of a transparent union 
type, GNAT uses the type of the first member of the union on the Ada side 
(which is the type used to determine the passing mechanism of the parameter).  
This works fine, except that LTO may warn about it; for the attached testcase:

.> gcc -c t.c -O2 -flto -D_GNU_SOURCE
.> gnatmake -q p -O2 -flto -largs t.o

q.ads:6:12: warning: type of 'q__c_getpeername' does not match original 
declaration [-Wlto-type-mismatch]
6 |   function C_Getpeername
  |^
/usr/include/sys/socket.h:130:12: note: type mismatch in parameter 2
  130 | extern int getpeername (int __fd, __SOCKADDR_ARG __addr,
  |^
/usr/include/sys/socket.h:130:12: note: 'getpeername' was previously declared 
here
/usr/include/sys/socket.h:130:12: note: code may be misoptimized unless '-fno-
strict-aliasing' is used


The attached patch recognizes the situation and checks the compatibility with 
the type of the first member of the union in this case.

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


2024-05-29  Eric Botcazou  

* lto/lto-symtab.cc (warn_type_compatibility_p): Deal with
parameters whose type is a transparent union specially.

-- 
Eric Botcazoudiff --git a/gcc/lto/lto-symtab.cc b/gcc/lto/lto-symtab.cc
index a40218beac5..ca5a79610bb 100644
--- a/gcc/lto/lto-symtab.cc
+++ b/gcc/lto/lto-symtab.cc
@@ -233,8 +233,20 @@ warn_type_compatibility_p (tree prevailing_type, tree type,
 	   parm1 && parm2;
 	   parm1 = TREE_CHAIN (parm1),
 	   parm2 = TREE_CHAIN (parm2))
-	lev |= warn_type_compatibility_p (TREE_VALUE (parm1),
-	  TREE_VALUE (parm2), false);
+	/* If a function with a transparent union parameter is interfaced
+	   with another type, check that the latter is compatible with the
+	   type of the first field of the union, which is the type used to
+	   set the calling convention for the argument.  */
+	if (TREE_CODE (TREE_VALUE (parm1)) == UNION_TYPE
+		&& TYPE_TRANSPARENT_AGGR (TREE_VALUE (parm1))
+		&& TREE_CODE (TREE_VALUE (parm2)) != UNION_TYPE
+		&& common_or_extern)
+	  lev |= warn_type_compatibility_p
+		   (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (parm1))),
+			TREE_VALUE (parm2), false);
+	else
+	  lev |= warn_type_compatibility_p (TREE_VALUE (parm1),
+		TREE_VALUE (parm2), false);
 	  if (parm1 || parm2)
 	lev |= odr_p ? 3 : 1;
 	}
with Interfaces.C; use Interfaces.C;
with System;

with Q; use Q;

procedure P is
  L : aliased unsigned;
  I : int := C_Getpeername (0, System.Null_Address, L'Access);

begin
  null;
end;
with Interfaces.C;
with System;

package Q is

  function C_Getpeername
  (S   : Interfaces.C.int;
   Name: System.Address;
   Namelen : not null access Interfaces.C.unsigned) return Interfaces.C.int;
  pragma Import (C, C_Getpeername, "getpeername");

  procedure Foo;
  pragma Import (C, Foo, "foo");

end Q;
#include 
#include 

void foo (void)
{
  int i = getpeername (0, NULL, NULL);
}


[Ada] Fix PR ada/115270

2024-05-29 Thread Eric Botcazou
This fixes the link failure of the GNAT tools on 32-bit SPARC/Linux (as well 
as on 32-bit PowerPC/Linux probably) coming from an incorrect binding to the 
64-bit compare-and-exchange builtin.

Tested by Rainer on 32-bit SPARC/Linux, applied on mainline and 14 branch.


2024-05-29  Eric Botcazou  

PR ada/115270
* Makefile.rtl (PowerPC/Linux): Use libgnat/s-atopri__32.ads for
the 32-bit library.
(SPARC/Linux): Likewise.

-- 
Eric Botcazoudiff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 570d0b2703d..0f5ebb87d73 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -2266,15 +2266,18 @@ ifeq ($(strip $(filter-out powerpc% linux%,$(target_cpu) $(target_os))),)
   system.ads

[gcc r14-10258] Fix link failure of GNAT tools on 32-bit SPARC/Linux

2024-05-29 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:fba2843b9b35b9700155677f90555700b6ad4e16

commit r14-10258-gfba2843b9b35b9700155677f90555700b6ad4e16
Author: Eric Botcazou 
Date:   Wed May 29 12:06:32 2024 +0200

Fix link failure of GNAT tools on 32-bit SPARC/Linux

There is an incorrect binding to the 64-bit compare-and-exchange builtin.

gcc/ada/
PR ada/115270
* Makefile.rtl (PowerPC/Linux): Use libgnat/s-atopri__32.ads for
the 32-bit library.
(SPARC/Linux): Likewise.

Diff:
---
 gcc/ada/Makefile.rtl | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 6e1ca305faf..32cbdb69247 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -2238,15 +2238,18 @@ ifeq ($(strip $(filter-out powerpc% 
linux%,$(target_cpu) $(target_os))),)
   system.ads

[gcc r15-894] Fix link failure of GNAT tools on 32-bit SPARC/Linux

2024-05-29 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:9c6e75a6d1cc2858fc945266a5edb700edb44389

commit r15-894-g9c6e75a6d1cc2858fc945266a5edb700edb44389
Author: Eric Botcazou 
Date:   Wed May 29 12:06:32 2024 +0200

Fix link failure of GNAT tools on 32-bit SPARC/Linux

There is an incorrect binding to the 64-bit compare-and-exchange builtin.

gcc/ada/
PR ada/115270
* Makefile.rtl (PowerPC/Linux): Use libgnat/s-atopri__32.ads for
the 32-bit library.
(SPARC/Linux): Likewise.

Diff:
---
 gcc/ada/Makefile.rtl | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 570d0b2703d..0f5ebb87d73 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -2266,15 +2266,18 @@ ifeq ($(strip $(filter-out powerpc% 
linux%,$(target_cpu) $(target_os))),)
   system.ads

[c-family] Small enhancement to implementation of -fdump-ada-spec

2024-05-24 Thread Eric Botcazou
This lets it recognize more preprocessing floating constants.

Tested on x86-64/Linux, applied on the mainline.


2024-05-24  Eric Botcazou  

* c-ada-spec.cc (is_cpp_float): New predicate.
(dump_number): Deal with more preprocessing floating constants.
(dump_ada_macros) : Use is_cpp_float.

-- 
Eric Botcazoudiff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc
index 8f0849bd427..0bea923220b 100644
--- a/gcc/c-family/c-ada-spec.cc
+++ b/gcc/c-family/c-ada-spec.cc
@@ -113,6 +113,26 @@ macro_length (const cpp_macro *macro, int *supported, int *buffer_len,
   (*buffer_len)++;
 }
 
+/* Return true if NUMBER is a preprocessing floating-point number.  */
+
+static bool
+is_cpp_float (unsigned char *number)
+{
+  /* In C, a floating constant need not have a point.  */
+  while (*number != '\0')
+{
+  if (*number == '.')
+	return true;
+  else if ((*number == 'e' || *number == 'E')
+	   && (*(number + 1) == '+' || *(number + 1) == '-'))
+	return true;
+  else
+	number++;
+}
+
+  return false;
+}
+
 /* Dump all digits/hex chars from NUMBER to BUFFER and return a pointer
to the character after the last character written.  If FLOAT_P is true,
this is a floating-point number.  */
@@ -120,12 +140,45 @@ macro_length (const cpp_macro *macro, int *supported, int *buffer_len,
 static unsigned char *
 dump_number (unsigned char *number, unsigned char *buffer, bool float_p)
 {
-  while (*number != '\0'
-	 && *number != (float_p ? 'F' : 'U')
-	 && *number != (float_p ? 'f' : 'u')
-	 && *number != 'l'
-	 && *number != 'L')
-*buffer++ = *number++;
+  /* In Ada, a real literal is a numeric literal that includes a point.  */
+  if (float_p)
+{
+  bool point_seen = false;
+
+  while (*number != '\0')
+	{
+	  if (ISDIGIT (*number))
+	*buffer++ = *number++;
+	  else if (*number == '.')
+	{
+	  *buffer++ = *number++;
+	  point_seen = true;
+	}
+	  else if ((*number == 'e' || *number == 'E')
+		   && (*(number + 1) == '+' || *(number + 1) == '-'))
+	{
+	  if (!point_seen)
+		{
+		  *buffer++ = '.';
+		  *buffer++ = '0';
+		  point_seen = true;
+		}
+	   *buffer++ = *number++;
+	   *buffer++ = *number++;
+	}
+	  else
+	break;
+	}
+}
+
+  /* An integer literal is a numeric literal without a point.  */
+  else
+while (*number != '\0'
+	   && *number != 'U'
+	   && *number != 'u'
+	   && *number != 'l'
+	   && *number != 'L')
+  *buffer++ = *number++;
 
   return buffer;
 }
@@ -450,7 +503,7 @@ dump_ada_macros (pretty_printer *pp, const char* file)
 
 			  default:
 /* Dump floating-point constant unmodified.  */
-if (strchr ((const char *)tmp, '.'))
+if (is_cpp_float (tmp))
   buffer = dump_number (tmp, buffer, true);
 else
   {
@@ -480,8 +533,7 @@ dump_ada_macros (pretty_printer *pp, const char* file)
 
 			default:
 			  buffer
-			= dump_number (tmp, buffer,
-	   strchr ((const char *)tmp, '.'));
+			= dump_number (tmp, buffer, is_cpp_float (tmp));
 			  break;
 		  }
 		break;


[gcc r15-826] Small enhancement to implementation of -fdump-ada-spec

2024-05-24 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:73eef7a04453d01147cbf4642fe6626350dded75

commit r15-826-g73eef7a04453d01147cbf4642fe6626350dded75
Author: Eric Botcazou 
Date:   Fri May 24 19:48:18 2024 +0200

Small enhancement to implementation of -fdump-ada-spec

This lets it recognize more preprocessing floating constants.

gcc/c-family/
* c-ada-spec.cc (is_cpp_float): New predicate.
(dump_number): Deal with more preprocessing floating constants.
(dump_ada_macros) : Use is_cpp_float.

Diff:
---
 gcc/c-family/c-ada-spec.cc | 70 --
 1 file changed, 61 insertions(+), 9 deletions(-)

diff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc
index 8f0849bd427..0bea923220b 100644
--- a/gcc/c-family/c-ada-spec.cc
+++ b/gcc/c-family/c-ada-spec.cc
@@ -113,6 +113,26 @@ macro_length (const cpp_macro *macro, int *supported, int 
*buffer_len,
   (*buffer_len)++;
 }
 
+/* Return true if NUMBER is a preprocessing floating-point number.  */
+
+static bool
+is_cpp_float (unsigned char *number)
+{
+  /* In C, a floating constant need not have a point.  */
+  while (*number != '\0')
+{
+  if (*number == '.')
+   return true;
+  else if ((*number == 'e' || *number == 'E')
+  && (*(number + 1) == '+' || *(number + 1) == '-'))
+   return true;
+  else
+   number++;
+}
+
+  return false;
+}
+
 /* Dump all digits/hex chars from NUMBER to BUFFER and return a pointer
to the character after the last character written.  If FLOAT_P is true,
this is a floating-point number.  */
@@ -120,12 +140,45 @@ macro_length (const cpp_macro *macro, int *supported, int 
*buffer_len,
 static unsigned char *
 dump_number (unsigned char *number, unsigned char *buffer, bool float_p)
 {
-  while (*number != '\0'
-&& *number != (float_p ? 'F' : 'U')
-&& *number != (float_p ? 'f' : 'u')
-&& *number != 'l'
-&& *number != 'L')
-*buffer++ = *number++;
+  /* In Ada, a real literal is a numeric literal that includes a point.  */
+  if (float_p)
+{
+  bool point_seen = false;
+
+  while (*number != '\0')
+   {
+ if (ISDIGIT (*number))
+   *buffer++ = *number++;
+ else if (*number == '.')
+   {
+ *buffer++ = *number++;
+ point_seen = true;
+   }
+ else if ((*number == 'e' || *number == 'E')
+  && (*(number + 1) == '+' || *(number + 1) == '-'))
+   {
+ if (!point_seen)
+   {
+ *buffer++ = '.';
+ *buffer++ = '0';
+ point_seen = true;
+   }
+  *buffer++ = *number++;
+  *buffer++ = *number++;
+   }
+ else
+   break;
+   }
+}
+
+  /* An integer literal is a numeric literal without a point.  */
+  else
+while (*number != '\0'
+  && *number != 'U'
+  && *number != 'u'
+  && *number != 'l'
+  && *number != 'L')
+  *buffer++ = *number++;
 
   return buffer;
 }
@@ -450,7 +503,7 @@ dump_ada_macros (pretty_printer *pp, const char* file)
 
  default:
/* Dump floating-point constant unmodified.  */
-   if (strchr ((const char *)tmp, '.'))
+   if (is_cpp_float (tmp))
  buffer = dump_number (tmp, buffer, true);
else
  {
@@ -480,8 +533,7 @@ dump_ada_macros (pretty_printer *pp, const char* file)
 
default:
  buffer
-   = dump_number (tmp, buffer,
-  strchr ((const char *)tmp, '.'));
+   = dump_number (tmp, buffer, is_cpp_float (tmp));
  break;
  }
break;


[c-family] Another small fix to implementation of -fdump-ada-spec

2024-05-23 Thread Eric Botcazou
This avoids generating invalid Ada code for functions with a multidimensional 
array parameter and also cleans things up left and right.

Tested on x86-64/Linux, applied on the mainline.


2024-05-23  Eric Botcazou  

* c-ada-spec.cc (check_type_name_conflict): Add guard.
(is_char_array): Simplify.
(dump_ada_array_type): Use strip_array_types.
(dump_ada_node) : Deal with anonymous array types.
(dump_nested_type): Use strip_array_types.

-- 
Eric Botcazoudiff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc
index 46fee30b6b9..8f0849bd427 100644
--- a/gcc/c-family/c-ada-spec.cc
+++ b/gcc/c-family/c-ada-spec.cc
@@ -1558,7 +1558,7 @@ check_type_name_conflict (pretty_printer *buffer, tree t)
   while (TREE_CODE (tmp) == POINTER_TYPE && !TYPE_NAME (tmp))
 tmp = TREE_TYPE (tmp);
 
-  if (TREE_CODE (tmp) != FUNCTION_TYPE)
+  if (TREE_CODE (tmp) != FUNCTION_TYPE && tmp != error_mark_node)
 {
   const char *s;
 
@@ -1788,17 +1788,9 @@ dump_sloc (pretty_printer *buffer, tree node)
 static bool
 is_char_array (tree t)
 {
-  int num_dim = 0;
-
-  while (TREE_CODE (t) == ARRAY_TYPE)
-{
-  num_dim++;
-  t = TREE_TYPE (t);
-}
-
-  return num_dim == 1
-	 && TREE_CODE (t) == INTEGER_TYPE
-	 && id_equal (DECL_NAME (TYPE_NAME (t)), "char");
+  return TREE_CODE (t) == ARRAY_TYPE
+	 && TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
+	 && id_equal (DECL_NAME (TYPE_NAME (TREE_TYPE (t))), "char");
 }
 
 /* Dump in BUFFER an array type NODE in Ada syntax.  SPC is the indentation
@@ -1821,9 +1813,7 @@ dump_ada_array_type (pretty_printer *buffer, tree node, int spc)
   /* Print the component type.  */
   if (!char_array)
 {
-  tree tmp = node;
-  while (TREE_CODE (tmp) == ARRAY_TYPE)
-	tmp = TREE_TYPE (tmp);
+  tree tmp = strip_array_types (node);
 
   pp_string (buffer, " of ");
 
@@ -2350,6 +2340,11 @@ dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 		  && DECL_ORIGINAL_TYPE (DECL_CHAIN (stub)) == ref_type)
 		ref_type = TREE_TYPE (DECL_CHAIN (stub));
 
+		  /* If this is a pointer to an anonymous array type, then use
+		 the name of the component type.  */
+		  else if (!type_name && is_access)
+		ref_type = strip_array_types (ref_type);
+
 		  /* Generate "access " instead of "access "
 		 if the subtype comes from another file, because subtype
 		 declarations do not contribute to the limited view of a
@@ -2639,10 +2634,7 @@ dump_nested_type (pretty_printer *buffer, tree field, tree t, int spc)
   if (!bitmap_set_bit (dumped_anonymous_types, TYPE_UID (field_type)))
 	return;
 
-  /* Recurse on the element type if need be.  */
-  tmp = TREE_TYPE (field_type);
-  while (TREE_CODE (tmp) == ARRAY_TYPE)
-	tmp = TREE_TYPE (tmp);
+  tmp = strip_array_types (field_type);
   decl = get_underlying_decl (tmp);
   if (decl
 	  && !DECL_NAME (decl)


[gcc r15-795] Another small fix to implementation of -fdump-ada-spec

2024-05-23 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:0b3b6a8df77b0ae15078402ea5fb933d6fccd585

commit r15-795-g0b3b6a8df77b0ae15078402ea5fb933d6fccd585
Author: Eric Botcazou 
Date:   Thu May 23 18:26:12 2024 +0200

Another small fix to implementation of -fdump-ada-spec

This avoids generating invalid Ada code for function with a multidimensional
array parameter and also cleans things up left and right.

gcc/c-family/
* c-ada-spec.cc (check_type_name_conflict): Add guard.
(is_char_array): Simplify.
(dump_ada_array_type): Use strip_array_types.
(dump_ada_node) : Deal with anonymous array types.
(dump_nested_type): Use strip_array_types.

Diff:
---
 gcc/c-family/c-ada-spec.cc | 30 +++---
 1 file changed, 11 insertions(+), 19 deletions(-)

diff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc
index 46fee30b6b9..8f0849bd427 100644
--- a/gcc/c-family/c-ada-spec.cc
+++ b/gcc/c-family/c-ada-spec.cc
@@ -1558,7 +1558,7 @@ check_type_name_conflict (pretty_printer *buffer, tree t)
   while (TREE_CODE (tmp) == POINTER_TYPE && !TYPE_NAME (tmp))
 tmp = TREE_TYPE (tmp);
 
-  if (TREE_CODE (tmp) != FUNCTION_TYPE)
+  if (TREE_CODE (tmp) != FUNCTION_TYPE && tmp != error_mark_node)
 {
   const char *s;
 
@@ -1788,17 +1788,9 @@ dump_sloc (pretty_printer *buffer, tree node)
 static bool
 is_char_array (tree t)
 {
-  int num_dim = 0;
-
-  while (TREE_CODE (t) == ARRAY_TYPE)
-{
-  num_dim++;
-  t = TREE_TYPE (t);
-}
-
-  return num_dim == 1
-&& TREE_CODE (t) == INTEGER_TYPE
-&& id_equal (DECL_NAME (TYPE_NAME (t)), "char");
+  return TREE_CODE (t) == ARRAY_TYPE
+&& TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
+&& id_equal (DECL_NAME (TYPE_NAME (TREE_TYPE (t))), "char");
 }
 
 /* Dump in BUFFER an array type NODE in Ada syntax.  SPC is the indentation
@@ -1821,9 +1813,7 @@ dump_ada_array_type (pretty_printer *buffer, tree node, 
int spc)
   /* Print the component type.  */
   if (!char_array)
 {
-  tree tmp = node;
-  while (TREE_CODE (tmp) == ARRAY_TYPE)
-   tmp = TREE_TYPE (tmp);
+  tree tmp = strip_array_types (node);
 
   pp_string (buffer, " of ");
 
@@ -2350,6 +2340,11 @@ dump_ada_node (pretty_printer *buffer, tree node, tree 
type, int spc,
  && DECL_ORIGINAL_TYPE (DECL_CHAIN (stub)) == ref_type)
ref_type = TREE_TYPE (DECL_CHAIN (stub));
 
+ /* If this is a pointer to an anonymous array type, then use
+the name of the component type.  */
+ else if (!type_name && is_access)
+   ref_type = strip_array_types (ref_type);
+
  /* Generate "access " instead of "access "
 if the subtype comes from another file, because subtype
 declarations do not contribute to the limited view of a
@@ -2639,10 +2634,7 @@ dump_nested_type (pretty_printer *buffer, tree field, 
tree t, int spc)
   if (!bitmap_set_bit (dumped_anonymous_types, TYPE_UID (field_type)))
return;
 
-  /* Recurse on the element type if need be.  */
-  tmp = TREE_TYPE (field_type);
-  while (TREE_CODE (tmp) == ARRAY_TYPE)
-   tmp = TREE_TYPE (tmp);
+  tmp = strip_array_types (field_type);
   decl = get_underlying_decl (tmp);
   if (decl
  && !DECL_NAME (decl)


[gcc r14-10233] Fix internal error in seh_cfa_offset with -O2 -fno-omit-frame-pointer

2024-05-22 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:2f0e0862406a17bb8bf4ad948ae22916bae092a0

commit r14-10233-g2f0e0862406a17bb8bf4ad948ae22916bae092a0
Author: Eric Botcazou 
Date:   Wed May 22 18:10:39 2024 +0200

Fix internal error in seh_cfa_offset with -O2 -fno-omit-frame-pointer

The problem directly comes from the -ffold-mem-offsets pass messing up with
the prologue and the frame-related instructions, which is a no-no with SEH,
so the fix simply disconnects the pass in these circumstances.

gcc/
PR rtl-optimization/115038
* fold-mem-offsets.cc (fold_offsets): Return 0 if the defining
instruction of the register is frame related.

gcc/testsuite/
* g++.dg/opt/fmo1.C: New test.

Diff:
---
 gcc/fold-mem-offsets.cc |  2 +-
 gcc/testsuite/g++.dg/opt/fmo1.C | 25 +
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/gcc/fold-mem-offsets.cc b/gcc/fold-mem-offsets.cc
index 2e15b05529e..84b9623058b 100644
--- a/gcc/fold-mem-offsets.cc
+++ b/gcc/fold-mem-offsets.cc
@@ -491,7 +491,7 @@ fold_offsets (rtx_insn *insn, rtx reg, bool analyze, bitmap 
foldable_insns)
 {
   rtx_insn *def = get_single_def_in_bb (insn, reg);
 
-  if (!def || GET_CODE (PATTERN (def)) != SET)
+  if (!def || RTX_FRAME_RELATED_P (def) || GET_CODE (PATTERN (def)) != SET)
 return 0;
 
   rtx dest = SET_DEST (PATTERN (def));
diff --git a/gcc/testsuite/g++.dg/opt/fmo1.C b/gcc/testsuite/g++.dg/opt/fmo1.C
new file mode 100644
index 000..f0ae624c61a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/fmo1.C
@@ -0,0 +1,25 @@
+// PR rtl-optimization/115038
+// Reported by Christoph Reiter 
+
+// { dg-do compile }
+// { dg-options "-O2 -fno-omit-frame-pointer" }
+
+struct d {
+  d();
+};
+
+struct e {
+  e() : c(1.0) {}
+  float c;
+};
+
+class k {
+  d g;
+  e h;
+};
+
+class a {
+  k f;
+} a;
+
+k b;


[gcc r15-776] Fix internal error in seh_cfa_offset with -O2 -fno-omit-frame-pointer

2024-05-22 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:f14ef5cfd4c1ba1d34afda9174935e40d3c0a3ce

commit r15-776-gf14ef5cfd4c1ba1d34afda9174935e40d3c0a3ce
Author: Eric Botcazou 
Date:   Wed May 22 18:10:39 2024 +0200

Fix internal error in seh_cfa_offset with -O2 -fno-omit-frame-pointer

The problem directly comes from the -ffold-mem-offsets pass messing up with
the prologue and the frame-related instructions, which is a no-no with SEH,
so the fix simply disconnects the pass in these circumstances.

gcc/
PR rtl-optimization/115038
* fold-mem-offsets.cc (fold_offsets): Return 0 if the defining
instruction of the register is frame related.

gcc/testsuite/
* g++.dg/opt/fmo1.C: New test.

Diff:
---
 gcc/fold-mem-offsets.cc |  2 +-
 gcc/testsuite/g++.dg/opt/fmo1.C | 25 +
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/gcc/fold-mem-offsets.cc b/gcc/fold-mem-offsets.cc
index 2e15b05529e..84b9623058b 100644
--- a/gcc/fold-mem-offsets.cc
+++ b/gcc/fold-mem-offsets.cc
@@ -491,7 +491,7 @@ fold_offsets (rtx_insn *insn, rtx reg, bool analyze, bitmap 
foldable_insns)
 {
   rtx_insn *def = get_single_def_in_bb (insn, reg);
 
-  if (!def || GET_CODE (PATTERN (def)) != SET)
+  if (!def || RTX_FRAME_RELATED_P (def) || GET_CODE (PATTERN (def)) != SET)
 return 0;
 
   rtx dest = SET_DEST (PATTERN (def));
diff --git a/gcc/testsuite/g++.dg/opt/fmo1.C b/gcc/testsuite/g++.dg/opt/fmo1.C
new file mode 100644
index 000..f0ae624c61a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/fmo1.C
@@ -0,0 +1,25 @@
+// PR rtl-optimization/115038
+// Reported by Christoph Reiter 
+
+// { dg-do compile }
+// { dg-options "-O2 -fno-omit-frame-pointer" }
+
+struct d {
+  d();
+};
+
+struct e {
+  e() : c(1.0) {}
+  float c;
+};
+
+class k {
+  d g;
+  e h;
+};
+
+class a {
+  k f;
+} a;
+
+k b;


[Ada] Fix PR ada/115168

2024-05-21 Thread Eric Botcazou
Recent changes made to the runtime library broke again its build on Solaris 
because it uses Solaris threads instead of POSIX threads on this platform.

Tested by Rainer, applied on the mainline.


2024-05-21  Eric Botcazou  

PR ada/115168
* libgnarl/s-taprop__solaris.adb (Initialize): Fix pasto.
* libgnat/s-oslock__solaris.ads (Owner_Int): Delete.
(Owner_ID): Change the designated type to Integer.

-- 
Eric Botcazoudiff --git a/gcc/ada/libgnarl/s-taprop__solaris.adb b/gcc/ada/libgnarl/s-taprop__solaris.adb
index 09f90e6e204..6d05e8db004 100644
--- a/gcc/ada/libgnarl/s-taprop__solaris.adb
+++ b/gcc/ada/libgnarl/s-taprop__solaris.adb
@@ -424,7 +424,7 @@ package body System.Task_Primitives.Operations is
 
begin
   Environment_Task_Id := Environment_Task;
-  Self_ID.Common.LL.Thread := thr_self;
+  Environment_Task.Common.LL.Thread := thr_self;
 
   Interrupt_Management.Initialize;
 
diff --git a/gcc/ada/libgnat/s-oslock__solaris.ads b/gcc/ada/libgnat/s-oslock__solaris.ads
index cc5a83df02e..56a242c8070 100644
--- a/gcc/ada/libgnat/s-oslock__solaris.ads
+++ b/gcc/ada/libgnat/s-oslock__solaris.ads
@@ -42,10 +42,7 @@ package System.OS_Locks is
type Private_Task_Serial_Number is mod 2 ** Long_Long_Integer'Size;
--  Used to give each task a unique serial number
 
-   type Owner_Int is new Integer;
-   for Owner_Int'Alignment use Standard'Maximum_Alignment;
-
-   type Owner_ID is access all Owner_Int;
+   type Owner_ID is access all Integer;
 
function To_Owner_ID is
  new Ada.Unchecked_Conversion (System.Address, Owner_ID);


[gcc r15-751] Fix Ada runtime library breakage on Solaris (bis)

2024-05-21 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:7b215c867629e095a4ac403bd026b6eb293962b4

commit r15-751-g7b215c867629e095a4ac403bd026b6eb293962b4
Author: Eric Botcazou 
Date:   Tue May 21 11:11:02 2024 +0200

Fix Ada runtime library breakage on Solaris (bis)

Recent changes made to the runtime library broke again its build on Solaris
because it uses Solaris threads instead of POSIX threads on this platform.

gcc/ada/
PR ada/115168
* libgnarl/s-taprop__solaris.adb (Initialize): Fix pasto.
* libgnat/s-oslock__solaris.ads (Owner_Int): Delete.
(Owner_ID): Change the designated type to Integer.

Diff:
---
 gcc/ada/libgnarl/s-taprop__solaris.adb | 2 +-
 gcc/ada/libgnat/s-oslock__solaris.ads  | 5 +
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/gcc/ada/libgnarl/s-taprop__solaris.adb 
b/gcc/ada/libgnarl/s-taprop__solaris.adb
index 09f90e6e204..6d05e8db004 100644
--- a/gcc/ada/libgnarl/s-taprop__solaris.adb
+++ b/gcc/ada/libgnarl/s-taprop__solaris.adb
@@ -424,7 +424,7 @@ package body System.Task_Primitives.Operations is
 
begin
   Environment_Task_Id := Environment_Task;
-  Self_ID.Common.LL.Thread := thr_self;
+  Environment_Task.Common.LL.Thread := thr_self;
 
   Interrupt_Management.Initialize;
 
diff --git a/gcc/ada/libgnat/s-oslock__solaris.ads 
b/gcc/ada/libgnat/s-oslock__solaris.ads
index cc5a83df02e..56a242c8070 100644
--- a/gcc/ada/libgnat/s-oslock__solaris.ads
+++ b/gcc/ada/libgnat/s-oslock__solaris.ads
@@ -42,10 +42,7 @@ package System.OS_Locks is
type Private_Task_Serial_Number is mod 2 ** Long_Long_Integer'Size;
--  Used to give each task a unique serial number
 
-   type Owner_Int is new Integer;
-   for Owner_Int'Alignment use Standard'Maximum_Alignment;
-
-   type Owner_ID is access all Owner_Int;
+   type Owner_ID is access all Integer;
 
function To_Owner_ID is
  new Ada.Unchecked_Conversion (System.Address, Owner_ID);


[PATCH] Fix PR rtl-optimization/115038

2024-05-20 Thread Eric Botcazou
Hi,

this is a regression present on mainline and 14 branch under the form of an 
ICE in seh_cfa_offset from config/i386/winnt.cc on the attached C++ testcase 
compiled with -O2 -fno-omit-frame-pointer.

The problem directly comes from the -ffold-mem-offsets pass messing up with 
the prologue and the frame-related instructions, which is a no-no with SEH, so 
the fix simply disconnects the pass in these circumstances, the question being 
whether this should be done unconditionally as in the fix or only with SEH.

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


2024-05-20  Eric Botcazou  

PR rtl-optimization/115038
* fold-mem-offsets.cc (fold_offsets): Return 0 if the defining
instruction of the register is frame related.


2024-05-20  Eric Botcazou  

* g++.dg/opt/fmo1.C: New test.

-- 
Eric Botcazoudiff --git a/gcc/fold-mem-offsets.cc b/gcc/fold-mem-offsets.cc
index 2e15b05529e..84b9623058b 100644
--- a/gcc/fold-mem-offsets.cc
+++ b/gcc/fold-mem-offsets.cc
@@ -491,7 +491,7 @@ fold_offsets (rtx_insn *insn, rtx reg, bool analyze, bitmap foldable_insns)
 {
   rtx_insn *def = get_single_def_in_bb (insn, reg);
 
-  if (!def || GET_CODE (PATTERN (def)) != SET)
+  if (!def || RTX_FRAME_RELATED_P (def) || GET_CODE (PATTERN (def)) != SET)
 return 0;
 
   rtx dest = SET_DEST (PATTERN (def));
// PR rtl-optimization/115038
// Reported by Christoph Reiter 

// { dg-do compile }
// { dg-options "-O2 -fno-omit-frame-pointer" }

struct d {
  d();
};

struct e {
  e() : c(1.0) {}
  float c;
};

class k {
  d g;
  e h;
};

class a {
  k f;
} a;

k b;


Re: [PATCH] Add widening expansion of MULT_HIGHPART_EXPR for integral modes

2024-05-19 Thread Eric Botcazou
Hi,

> Just notice that this patch may result in some ICE when build libc++ for the
> riscv port, details as below. Please note not all configuration can
> reproduce this issue, feel free to ping me if you cannot reproduce this
> issue. CC more riscv port people for awareness.

Sorry for the breakage, fixed thus, applied as obvious.


* optabs-query.cc (can_mult_highpart_p): Test for the existence of
a wider mode instead of requiring it.

-- 
Eric Botcazoudiff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc
index de145be7075..5149de57468 100644
--- a/gcc/optabs-query.cc
+++ b/gcc/optabs-query.cc
@@ -510,17 +510,16 @@ int
 can_mult_highpart_p (machine_mode mode, bool uns_p)
 {
   optab op;
-  scalar_int_mode int_mode;
+  scalar_int_mode int_mode, wider_mode;
 
   op = uns_p ? umul_highpart_optab : smul_highpart_optab;
   if (optab_handler (op, mode) != CODE_FOR_nothing)
 return 1;
 
   /* If the mode is integral, synth from widening or larger operations.  */
-  if (is_a  (mode, _mode))
+  if (is_a  (mode, _mode)
+  && GET_MODE_WIDER_MODE (int_mode).exists (_mode))
 {
-  scalar_int_mode wider_mode = GET_MODE_WIDER_MODE (int_mode).require ();
-
   op = uns_p ? umul_widen_optab : smul_widen_optab;
   if (convert_optab_handler (op, wider_mode, mode) != CODE_FOR_nothing)
 	return 2;


[gcc r15-649] Fix oversight in latest change to can_mult_highpart_p

2024-05-19 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:3db8dd4139a7a5ce941684f1fc05ee0652e35544

commit r15-649-g3db8dd4139a7a5ce941684f1fc05ee0652e35544
Author: Eric Botcazou 
Date:   Sun May 19 11:38:40 2024 +0200

Fix oversight in latest change to can_mult_highpart_p

gcc/
* optabs-query.cc (can_mult_highpart_p): Test for the existence of
a wider mode instead of requiring it.

Diff:
---
 gcc/optabs-query.cc | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc
index de145be7075f..5149de57468d 100644
--- a/gcc/optabs-query.cc
+++ b/gcc/optabs-query.cc
@@ -510,17 +510,16 @@ int
 can_mult_highpart_p (machine_mode mode, bool uns_p)
 {
   optab op;
-  scalar_int_mode int_mode;
+  scalar_int_mode int_mode, wider_mode;
 
   op = uns_p ? umul_highpart_optab : smul_highpart_optab;
   if (optab_handler (op, mode) != CODE_FOR_nothing)
 return 1;
 
   /* If the mode is integral, synth from widening or larger operations.  */
-  if (is_a  (mode, _mode))
+  if (is_a  (mode, _mode)
+  && GET_MODE_WIDER_MODE (int_mode).exists (_mode))
 {
-  scalar_int_mode wider_mode = GET_MODE_WIDER_MODE (int_mode).require ();
-
   op = uns_p ? umul_widen_optab : smul_widen_optab;
   if (convert_optab_handler (op, wider_mode, mode) != CODE_FOR_nothing)
return 2;


[Ada] Fix PR ada/115133

2024-05-17 Thread Eric Botcazou
The recent changes made to the runtime library broke its build on Solaris 
because it uses Solaris threads instead of POSIX threads on this platform.

Tested by Rainer, applied on the mainline.


2024-05-17  Eric Botcazou  
Rainer Orth  

PR ada/115133
* libgnarl/s-osinte__solaris.ads (mutex_t): Fix typo.
* libgnarl/s-taprop__solaris.adb (Record_Lock): Add conversion.
(Check_Sleep): Likewise.
(Record_Wakeup): Likewise.
(Check_Unlock): Likewise.
* libgnarl/s-tasini.adb (Initialize_RTS_Lock): Add pragma Import
on the overlaid variable.
(Finalize_RTS_Lock): Likewise.
(Acquire_RTS_Lock): Likewise.
(Release_RTS_Lock): Likewise.
* libgnarl/s-taspri__solaris.ads (To_RTS_Lock_Ptr): New instance
of Ada.Unchecked_Conversion.
* libgnat/s-oslock__solaris.ads: Add with clause for
Ada.Unchecked_Conversion.
(array_type_9): Add missing name qualification.
(record_type_3): Likewise.
(mutex_t): Fix formatting.

-- 
Eric Botcazoudiff --git a/gcc/ada/libgnarl/s-osinte__solaris.ads b/gcc/ada/libgnarl/s-osinte__solaris.ads
index 12ad52bb48e..3703697ef44 100644
--- a/gcc/ada/libgnarl/s-osinte__solaris.ads
+++ b/gcc/ada/libgnarl/s-osinte__solaris.ads
@@ -298,7 +298,7 @@ package System.OS_Interface is
 
function To_thread_t is new Ada.Unchecked_Conversion (Integer, thread_t);
 
-   subtype mutex_t is System.OS_Lock.mutex_t;
+   subtype mutex_t is System.OS_Locks.mutex_t;
 
type cond_t is limited private;
 
diff --git a/gcc/ada/libgnarl/s-taprop__solaris.adb b/gcc/ada/libgnarl/s-taprop__solaris.adb
index 88b77b09820..82e51b8d25c 100644
--- a/gcc/ada/libgnarl/s-taprop__solaris.adb
+++ b/gcc/ada/libgnarl/s-taprop__solaris.adb
@@ -1399,7 +1399,7 @@ package body System.Task_Primitives.Operations is
   P := Self_ID.Common.LL.Locks;
 
   if P /= null then
- L.Next := P;
+ L.Next := To_RTS_Lock_Ptr (P);
   end if;
 
   Self_ID.Common.LL.Locking := null;
@@ -1440,7 +1440,7 @@ package body System.Task_Primitives.Operations is
 
   Self_ID.Common.LL.L.Owner := null;
   P := Self_ID.Common.LL.Locks;
-  Self_ID.Common.LL.Locks := Self_ID.Common.LL.Locks.Next;
+  Self_ID.Common.LL.Locks := To_Lock_Ptr (Self_ID.Common.LL.Locks.Next);
   P.Next := null;
   return True;
end Check_Sleep;
@@ -1468,7 +1468,7 @@ package body System.Task_Primitives.Operations is
   P := Self_ID.Common.LL.Locks;
 
   if P /= null then
- L.Next := P;
+ L.Next := To_RTS_Lock_Ptr (P);
   end if;
 
   Self_ID.Common.LL.Locking := null;
@@ -1549,7 +1549,7 @@ package body System.Task_Primitives.Operations is
 
   L.Owner := null;
   P := Self_ID.Common.LL.Locks;
-  Self_ID.Common.LL.Locks := Self_ID.Common.LL.Locks.Next;
+  Self_ID.Common.LL.Locks := To_Lock_Ptr (Self_ID.Common.LL.Locks.Next);
   P.Next := null;
   return True;
end Check_Unlock;
diff --git a/gcc/ada/libgnarl/s-tasini.adb b/gcc/ada/libgnarl/s-tasini.adb
index 794183f5356..d42d2881df4 100644
--- a/gcc/ada/libgnarl/s-tasini.adb
+++ b/gcc/ada/libgnarl/s-tasini.adb
@@ -246,6 +246,7 @@ package body System.Tasking.Initialization is
procedure Initialize_RTS_Lock (Addr : Address) is
   Lock : aliased SOL.RTS_Lock;
   for Lock'Address use Addr;
+  pragma Import (Ada, Lock);
 
begin
   Initialize_Lock (Lock'Unchecked_Access, PO_Level);
@@ -258,6 +259,7 @@ package body System.Tasking.Initialization is
procedure Finalize_RTS_Lock (Addr : Address) is
   Lock : aliased SOL.RTS_Lock;
   for Lock'Address use Addr;
+  pragma Import (Ada, Lock);
 
begin
   Finalize_Lock (Lock'Unchecked_Access);
@@ -270,6 +272,7 @@ package body System.Tasking.Initialization is
procedure Acquire_RTS_Lock (Addr : Address) is
   Lock : aliased SOL.RTS_Lock;
   for Lock'Address use Addr;
+  pragma Import (Ada, Lock);
 
begin
   Write_Lock (Lock'Unchecked_Access);
@@ -282,6 +285,7 @@ package body System.Tasking.Initialization is
procedure Release_RTS_Lock (Addr : Address) is
   Lock : aliased SOL.RTS_Lock;
   for Lock'Address use Addr;
+  pragma Import (Ada, Lock);
 
begin
   Unlock (Lock'Unchecked_Access);
diff --git a/gcc/ada/libgnarl/s-taspri__solaris.ads b/gcc/ada/libgnarl/s-taspri__solaris.ads
index ca40229993b..16fc4196b00 100644
--- a/gcc/ada/libgnarl/s-taspri__solaris.ads
+++ b/gcc/ada/libgnarl/s-taspri__solaris.ads
@@ -47,6 +47,8 @@ package System.Task_Primitives is
 
function To_Lock_Ptr is
  new Ada.Unchecked_Conversion (OS_Locks.RTS_Lock_Ptr, Lock_Ptr);
+   function To_RTS_Lock_Ptr is
+ new Ada.Unchecked_Conversion (Lock_Ptr, OS_Locks.RTS_Lock_Ptr);
 
type Suspension_Object is limited private;
--  Should be used for the implementation of Ada.Synchronous_Task_Control
diff --git a/gcc/ada/libgnat/s-oslock__solaris.ads b/gcc/ada/libgnat/s

[gcc r15-641] Fix Ada runtime library breakage on Solaris

2024-05-17 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:5812e1bbb1c8a7a90d995a0165cddae4d450d6cf

commit r15-641-g5812e1bbb1c8a7a90d995a0165cddae4d450d6cf
Author: Eric Botcazou 
Date:   Sat May 18 00:21:56 2024 +0200

Fix Ada runtime library breakage on Solaris

The recent changes made to the runtime library broke its build on Solaris
because it uses Solaris threads instead of POSIX threads on this platform.

gcc/ada/
PR ada/115133
* libgnarl/s-osinte__solaris.ads (mutex_t): Fix typo.
* libgnarl/s-taprop__solaris.adb (Record_Lock): Add conversion.
(Check_Sleep): Likewise.
(Record_Wakeup): Likewise.
(Check_Unlock): Likewise.
* libgnarl/s-tasini.adb (Initialize_RTS_Lock): Add pragma Import
on the overlaid variable.
(Finalize_RTS_Lock): Likewise.
(Acquire_RTS_Lock): Likewise.
(Release_RTS_Lock): Likewise.
* libgnarl/s-taspri__solaris.ads (To_RTS_Lock_Ptr): New instance
of Ada.Unchecked_Conversion.
* libgnat/s-oslock__solaris.ads: Add with clause for
Ada.Unchecked_Conversion.
(array_type_9): Add missing name qualification.
(record_type_3): Likewise.
(mutex_t): Fix formatting.

Diff:
---
 gcc/ada/libgnarl/s-osinte__solaris.ads | 2 +-
 gcc/ada/libgnarl/s-taprop__solaris.adb | 8 
 gcc/ada/libgnarl/s-tasini.adb  | 4 
 gcc/ada/libgnarl/s-taspri__solaris.ads | 2 ++
 gcc/ada/libgnat/s-oslock__solaris.ads  | 7 ---
 5 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/gcc/ada/libgnarl/s-osinte__solaris.ads 
b/gcc/ada/libgnarl/s-osinte__solaris.ads
index 12ad52bb48ed..3703697ef44f 100644
--- a/gcc/ada/libgnarl/s-osinte__solaris.ads
+++ b/gcc/ada/libgnarl/s-osinte__solaris.ads
@@ -298,7 +298,7 @@ package System.OS_Interface is
 
function To_thread_t is new Ada.Unchecked_Conversion (Integer, thread_t);
 
-   subtype mutex_t is System.OS_Lock.mutex_t;
+   subtype mutex_t is System.OS_Locks.mutex_t;
 
type cond_t is limited private;
 
diff --git a/gcc/ada/libgnarl/s-taprop__solaris.adb 
b/gcc/ada/libgnarl/s-taprop__solaris.adb
index 88b77b09820d..82e51b8d25c5 100644
--- a/gcc/ada/libgnarl/s-taprop__solaris.adb
+++ b/gcc/ada/libgnarl/s-taprop__solaris.adb
@@ -1399,7 +1399,7 @@ package body System.Task_Primitives.Operations is
   P := Self_ID.Common.LL.Locks;
 
   if P /= null then
- L.Next := P;
+ L.Next := To_RTS_Lock_Ptr (P);
   end if;
 
   Self_ID.Common.LL.Locking := null;
@@ -1440,7 +1440,7 @@ package body System.Task_Primitives.Operations is
 
   Self_ID.Common.LL.L.Owner := null;
   P := Self_ID.Common.LL.Locks;
-  Self_ID.Common.LL.Locks := Self_ID.Common.LL.Locks.Next;
+  Self_ID.Common.LL.Locks := To_Lock_Ptr (Self_ID.Common.LL.Locks.Next);
   P.Next := null;
   return True;
end Check_Sleep;
@@ -1468,7 +1468,7 @@ package body System.Task_Primitives.Operations is
   P := Self_ID.Common.LL.Locks;
 
   if P /= null then
- L.Next := P;
+ L.Next := To_RTS_Lock_Ptr (P);
   end if;
 
   Self_ID.Common.LL.Locking := null;
@@ -1549,7 +1549,7 @@ package body System.Task_Primitives.Operations is
 
   L.Owner := null;
   P := Self_ID.Common.LL.Locks;
-  Self_ID.Common.LL.Locks := Self_ID.Common.LL.Locks.Next;
+  Self_ID.Common.LL.Locks := To_Lock_Ptr (Self_ID.Common.LL.Locks.Next);
   P.Next := null;
   return True;
end Check_Unlock;
diff --git a/gcc/ada/libgnarl/s-tasini.adb b/gcc/ada/libgnarl/s-tasini.adb
index 794183f5356a..d42d2881df45 100644
--- a/gcc/ada/libgnarl/s-tasini.adb
+++ b/gcc/ada/libgnarl/s-tasini.adb
@@ -246,6 +246,7 @@ package body System.Tasking.Initialization is
procedure Initialize_RTS_Lock (Addr : Address) is
   Lock : aliased SOL.RTS_Lock;
   for Lock'Address use Addr;
+  pragma Import (Ada, Lock);
 
begin
   Initialize_Lock (Lock'Unchecked_Access, PO_Level);
@@ -258,6 +259,7 @@ package body System.Tasking.Initialization is
procedure Finalize_RTS_Lock (Addr : Address) is
   Lock : aliased SOL.RTS_Lock;
   for Lock'Address use Addr;
+  pragma Import (Ada, Lock);
 
begin
   Finalize_Lock (Lock'Unchecked_Access);
@@ -270,6 +272,7 @@ package body System.Tasking.Initialization is
procedure Acquire_RTS_Lock (Addr : Address) is
   Lock : aliased SOL.RTS_Lock;
   for Lock'Address use Addr;
+  pragma Import (Ada, Lock);
 
begin
   Write_Lock (Lock'Unchecked_Access);
@@ -282,6 +285,7 @@ package body System.Tasking.Initialization is
procedure Release_RTS_Lock (Addr : Address) is
   Lock : aliased SOL.RTS_Lock;
   for Lock'Address use Addr;
+  pragma Import (Ada, Lock);
 
begin
   Unlock (Lock'Unchecked_Access);
diff --git a/gcc/ada/libgnarl/s-taspri__solaris.ads 
b/gcc/ada/libgnarl/s-taspri__solaris.ads
index ca40229993bd..16fc4196b005 100644
--- a/gcc/ada

[gcc r15-623] Add widening expansion of MULT_HIGHPART_EXPR for integral modes

2024-05-17 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:f53f8a859631bef97adba1522a8049a8fce57c1b

commit r15-623-gf53f8a859631bef97adba1522a8049a8fce57c1b
Author: Eric Botcazou 
Date:   Wed May 8 10:07:56 2024 +0200

Add widening expansion of MULT_HIGHPART_EXPR for integral modes

For integral modes the expansion of MULT_HIGHPART_EXPR requires the presence
of an {s,u}mul_highpart optab whereas, for vector modes, widening expansion
is supported.  This adds a widening expansion for integral modes too, which
is in fact already implemented in expmed_mult_highpart_optab.

gcc/
* expmed.h (expmed_mult_highpart_optab): Declare.
* expmed.cc (expmed_mult_highpart_optab): Remove static keyword.
Do not assume that OP1 is a constant integer.  Fix pasto.
(expmed_mult_highpart): Pass OP1 narrowed to MODE in all the calls
to expmed_mult_highpart_optab.
* optabs-query.cc (can_mult_highpart_p): Use 2 for integer widening
and shift subsequent values accordingly.
* optabs.cc (expand_mult_highpart): Call expmed_mult_highpart_optab
when can_mult_highpart_p returns 2 and adjust to above change.

Diff:
---
 gcc/expmed.cc   | 54 +
 gcc/expmed.h|  2 ++
 gcc/optabs-query.cc | 24 
 gcc/optabs.cc   |  7 +--
 4 files changed, 52 insertions(+), 35 deletions(-)

diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index 248940fe4147..50d22762cae0 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -2748,8 +2748,7 @@ static rtx expand_mult_const (machine_mode, rtx, 
HOST_WIDE_INT, rtx,
 static unsigned HOST_WIDE_INT invert_mod2n (unsigned HOST_WIDE_INT, int);
 static rtx extract_high_half (scalar_int_mode, rtx);
 static rtx expmed_mult_highpart (scalar_int_mode, rtx, rtx, rtx, int, int);
-static rtx expmed_mult_highpart_optab (scalar_int_mode, rtx, rtx, rtx,
-  int, int);
+
 /* Compute and return the best algorithm for multiplying by T.
The algorithm must cost less than cost_limit
If retval.cost >= COST_LIMIT, no algorithm was found and all
@@ -3856,30 +3855,25 @@ extract_high_half (scalar_int_mode mode, rtx op)
   return convert_modes (mode, wider_mode, op, 0);
 }
 
-/* Like expmed_mult_highpart, but only consider using a multiplication
-   optab.  OP1 is an rtx for the constant operand.  */
+/* Like expmed_mult_highpart, but only consider using multiplication optab.  */
 
-static rtx
+rtx
 expmed_mult_highpart_optab (scalar_int_mode mode, rtx op0, rtx op1,
rtx target, int unsignedp, int max_cost)
 {
-  rtx narrow_op1 = gen_int_mode (INTVAL (op1), mode);
+  const scalar_int_mode wider_mode = GET_MODE_WIDER_MODE (mode).require ();
+  const bool speed = optimize_insn_for_speed_p ();
+  const int size = GET_MODE_BITSIZE (mode);
   optab moptab;
   rtx tem;
-  int size;
-  bool speed = optimize_insn_for_speed_p ();
-
-  scalar_int_mode wider_mode = GET_MODE_WIDER_MODE (mode).require ();
-
-  size = GET_MODE_BITSIZE (mode);
 
   /* Firstly, try using a multiplication insn that only generates the needed
  high part of the product, and in the sign flavor of unsignedp.  */
   if (mul_highpart_cost (speed, mode) < max_cost)
 {
   moptab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
-  tem = expand_binop (mode, moptab, op0, narrow_op1, target,
- unsignedp, OPTAB_DIRECT);
+  tem = expand_binop (mode, moptab, op0, op1, target, unsignedp,
+ OPTAB_DIRECT);
   if (tem)
return tem;
 }
@@ -3892,12 +3886,12 @@ expmed_mult_highpart_optab (scalar_int_mode mode, rtx 
op0, rtx op1,
  + 4 * add_cost (speed, mode) < max_cost))
 {
   moptab = unsignedp ? smul_highpart_optab : umul_highpart_optab;
-  tem = expand_binop (mode, moptab, op0, narrow_op1, target,
- unsignedp, OPTAB_DIRECT);
+  tem = expand_binop (mode, moptab, op0, op1, target, !unsignedp,
+ OPTAB_DIRECT);
   if (tem)
/* We used the wrong signedness.  Adjust the result.  */
-   return expand_mult_highpart_adjust (mode, tem, op0, narrow_op1,
-   tem, unsignedp);
+   return expand_mult_highpart_adjust (mode, tem, op0, op1, tem,
+   unsignedp);
 }
 
   /* Try widening multiplication.  */
@@ -3905,8 +3899,8 @@ expmed_mult_highpart_optab (scalar_int_mode mode, rtx 
op0, rtx op1,
   if (convert_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing
   && mul_widen_cost (speed, wider_mode) < max_cost)
 {
-  tem = expand_binop (wider_mode, moptab, op0, narrow_op1, 0,
- unsignedp, OPTAB_WIDEN);
+  tem = expand_binop (wider_mode, moptab, op0, op1, NULL_RTX, unsignedp,
+ OPTAB_WIDEN);
   if 

[c-family] Small fix to implementation of -fdump-ada-spec

2024-05-17 Thread Eric Botcazou
This avoids declaring anonymous array types as having an aliased component 
when the layout is packed, as is already done for named array types.

Tested on x86-64/Linux, applied on the mainline.


2024-05-17  Eric Botcazou  

* c-ada-spec.cc (bitfield_used): Move around.
(packed_layout): Likewise.
(dump_ada_array_type): Do not put "aliased" for a packed layout.

-- 
Eric Botcazoudiff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc
index e56ef10f443..46fee30b6b9 100644
--- a/gcc/c-family/c-ada-spec.cc
+++ b/gcc/c-family/c-ada-spec.cc
@@ -699,6 +699,8 @@ compare_comment (const void *lp, const void *rp)
 
 static tree *to_dump = NULL;
 static int to_dump_count = 0;
+static bool bitfield_used = false;
+static bool packed_layout = false;
 
 /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
by a subsequent call to dump_ada_nodes.  */
@@ -1825,7 +1827,7 @@ dump_ada_array_type (pretty_printer *buffer, tree node, int spc)
 
   pp_string (buffer, " of ");
 
-  if (TREE_CODE (tmp) != POINTER_TYPE)
+  if (TREE_CODE (tmp) != POINTER_TYPE && !packed_layout)
 	pp_string (buffer, "aliased ");
 
   if (TYPE_NAME (tmp)
@@ -2083,9 +2085,6 @@ is_float128 (tree node)
 	 || id_equal (name, "_Float128x");
 }
 
-static bool bitfield_used = false;
-static bool packed_layout = false;
-
 /* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
TYPE.  SPC is the indentation level.  LIMITED_ACCESS indicates whether NODE
can be referenced via a "limited with" clause.  NAME_ONLY indicates whether


[gcc r15-625] Small fix to implementation of -fdump-ada-spec

2024-05-17 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:6a0a46c57999d1f805f6c604a8868ae588a104f2

commit r15-625-g6a0a46c57999d1f805f6c604a8868ae588a104f2
Author: Eric Botcazou 
Date:   Fri May 17 11:44:30 2024 +0200

Small fix to implementation of -fdump-ada-spec

gcc/c-family/
* c-ada-spec.cc (bitfield_used): Move around.
(packed_layout): Likewise.
(dump_ada_array_type): Do not put "aliased" for a packed layout.

Diff:
---
 gcc/c-family/c-ada-spec.cc | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc
index e56ef10f443a..46fee30b6b90 100644
--- a/gcc/c-family/c-ada-spec.cc
+++ b/gcc/c-family/c-ada-spec.cc
@@ -699,6 +699,8 @@ compare_comment (const void *lp, const void *rp)
 
 static tree *to_dump = NULL;
 static int to_dump_count = 0;
+static bool bitfield_used = false;
+static bool packed_layout = false;
 
 /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
by a subsequent call to dump_ada_nodes.  */
@@ -1825,7 +1827,7 @@ dump_ada_array_type (pretty_printer *buffer, tree node, 
int spc)
 
   pp_string (buffer, " of ");
 
-  if (TREE_CODE (tmp) != POINTER_TYPE)
+  if (TREE_CODE (tmp) != POINTER_TYPE && !packed_layout)
pp_string (buffer, "aliased ");
 
   if (TYPE_NAME (tmp)
@@ -2083,9 +2085,6 @@ is_float128 (tree node)
 || id_equal (name, "_Float128x");
 }
 
-static bool bitfield_used = false;
-static bool packed_layout = false;
-
 /* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
TYPE.  SPC is the indentation level.  LIMITED_ACCESS indicates whether NODE
can be referenced via a "limited with" clause.  NAME_ONLY indicates whether


[gcc r15-624] Remove spurious line

2024-05-17 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:4da8be4f46b5dad4f5f610fc142538054446f44b

commit r15-624-g4da8be4f46b5dad4f5f610fc142538054446f44b
Author: Eric Botcazou 
Date:   Wed May 8 11:20:40 2024 +0200

Remove spurious line

Diff:
---
 gcc/ada/ChangeLog | 1 -
 1 file changed, 1 deletion(-)

diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 2095166460ec..f0ec83e56d39 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1139,7 +1139,6 @@
 2024-05-06  Eric Botcazou  
 
* fe.h: Remove unused declarations and add 'extern' to others.
-   no-issue-check
 
 2024-05-06  Piotr Trojanek  


[wwwdocs] Document reimplementation of GNU threads library on Windows

2024-05-16 Thread Eric Botcazou
... which happened in GCC 13.

Validated with W3C's Validator and applied.

-- 
Eric Botcazoudiff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html
index e324b782..3ab4a101 100644
--- a/htdocs/gcc-13/changes.html
+++ b/htdocs/gcc-13/changes.html
@@ -770,8 +770,17 @@ You may also want to check out our
 
 
 
-
-
+Windows
+
+  The GNU threads library used by the win32 thread model has
+  been reimplemented using direct Win32 API calls, except for the Objective-C
+  specific subset.  It requires Windows XP/Server 2003 or later.  The new
+  implementation also adds the support needed for the C++11 threads, using
+  again direct Win32 API calls; this additional layer requires Windows
+  Vista/Server 2008 or later.  It is recommended to use a recent version of
+  MinGW-W64 in conjunction with the win32 thread model.
+  
+
 
 
 


gcc-wwwdocs branch master updated. ed9ceba9b8b038f0e0f333798da7abe046679d0c

2024-05-16 Thread Eric Botcazou via Gcc-cvs-wwwdocs
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gcc-wwwdocs".

The branch, master has been updated
   via  ed9ceba9b8b038f0e0f333798da7abe046679d0c (commit)
  from  8f193930f0beb38d06b143bcc1d5632f457e0cdf (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -
commit ed9ceba9b8b038f0e0f333798da7abe046679d0c
Author: Eric Botcazou 
Date:   Thu May 16 12:38:25 2024 +0200

Document reimplementation of GNU threads library on Windows (PR web/115105)

diff --git a/htdocs/gcc-13/changes.html b/htdocs/gcc-13/changes.html
index e324b782..3ab4a101 100644
--- a/htdocs/gcc-13/changes.html
+++ b/htdocs/gcc-13/changes.html
@@ -770,8 +770,17 @@ You may also want to check out our
 
 
 
-
-
+Windows
+
+  The GNU threads library used by the win32 thread model has
+  been reimplemented using direct Win32 API calls, except for the 
Objective-C
+  specific subset.  It requires Windows XP/Server 2003 or later.  The new
+  implementation also adds the support needed for the C++11 threads, using
+  again direct Win32 API calls; this additional layer requires Windows
+  Vista/Server 2008 or later.  It is recommended to use a recent version of
+  MinGW-W64 in conjunction with the win32 thread model.
+  
+
 
 
 

---

Summary of changes:
 htdocs/gcc-13/changes.html | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)


hooks/post-receive
-- 
gcc-wwwdocs


[gcc r15-314] Minor tweaks to code computing modular multiplicative inverse

2024-05-08 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:10e34aa5b1d23e1517f0ca5cfae3cac3b51a7a53

commit r15-314-g10e34aa5b1d23e1517f0ca5cfae3cac3b51a7a53
Author: Eric Botcazou 
Date:   Mon Apr 29 17:46:20 2024 +0200

Minor tweaks to code computing modular multiplicative inverse

This removes the last parameter of choose_multiplier, which is unused, adds
another assertion and more details to the description and various comments.
Likewise to the closely related invert_mod2n, except for the last parameter.

[changelog]
* expmed.h (choose_multiplier): Tweak description and remove last
parameter.
* expmed.cc (choose_multiplier): Likewise.  Add assertion for the
third parameter and adds details to various comments.
(invert_mod2n): Tweak description and add assertion for the first
parameter.
(expand_divmod): Adjust calls to choose_multiplier.
* tree-vect-generic.cc (expand_vector_divmod): Likewise.
* tree-vect-patterns.cc (vect_recog_divmod_pattern): Likewise.

Diff:
---
 gcc/expmed.cc | 95 ++-
 gcc/expmed.h  |  9 +++--
 gcc/tree-vect-generic.cc  | 13 +++
 gcc/tree-vect-patterns.cc | 14 +++
 4 files changed, 71 insertions(+), 60 deletions(-)

diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index 20f3a36f38cc..248940fe4147 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -3695,50 +3695,62 @@ expand_widening_mult (machine_mode mode, rtx op0, rtx 
op1, rtx target,
   unsignedp, OPTAB_LIB_WIDEN);
 }
 
-/* Choose a minimal N + 1 bit approximation to 1/D that can be used to
-   replace division by D, and put the least significant N bits of the result
-   in *MULTIPLIER_PTR and return the most significant bit.
+/* Choose a minimal N + 1 bit approximation to 2**K / D that can be used to
+   replace division by D, put the least significant N bits of the result in
+   *MULTIPLIER_PTR, the value K - N in *POST_SHIFT_PTR, and return the most
+   significant bit.
 
The width of operations is N (should be <= HOST_BITS_PER_WIDE_INT), the
-   needed precision is in PRECISION (should be <= N).
+   needed precision is PRECISION (should be <= N).
 
-   PRECISION should be as small as possible so this function can choose
-   multiplier more freely.
+   PRECISION should be as small as possible so this function can choose the
+   multiplier more freely.  If PRECISION is <= N - 1, the most significant
+   bit returned by the function will be zero.
 
-   The rounded-up logarithm of D is placed in *lgup_ptr.  A shift count that
-   is to be used for a final right shift is placed in *POST_SHIFT_PTR.
-
-   Using this function, x/D will be equal to (x * m) >> (*POST_SHIFT_PTR),
-   where m is the full HOST_BITS_PER_WIDE_INT + 1 bit multiplier.  */
+   Using this function, x / D is equal to (x*m) / 2**N >> (*POST_SHIFT_PTR),
+   where m is the full N + 1 bit multiplier.  */
 
 unsigned HOST_WIDE_INT
 choose_multiplier (unsigned HOST_WIDE_INT d, int n, int precision,
   unsigned HOST_WIDE_INT *multiplier_ptr,
-  int *post_shift_ptr, int *lgup_ptr)
+  int *post_shift_ptr)
 {
   int lgup, post_shift;
-  int pow, pow2;
+  int pow1, pow2;
 
-  /* lgup = ceil(log2(divisor)); */
+  /* lgup = ceil(log2(d)) */
+  /* Assuming d > 1, we have d >= 2^(lgup-1) + 1 */
   lgup = ceil_log2 (d);
 
   gcc_assert (lgup <= n);
+  gcc_assert (lgup <= precision);
 
-  pow = n + lgup;
+  pow1 = n + lgup;
   pow2 = n + lgup - precision;
 
-  /* mlow = 2^(N + lgup)/d */
-  wide_int val = wi::set_bit_in_zero (pow, HOST_BITS_PER_DOUBLE_INT);
+  /* mlow = 2^(n + lgup)/d */
+  /* Trivially from above we have mlow < 2^(n+1) */
+  wide_int val = wi::set_bit_in_zero (pow1, HOST_BITS_PER_DOUBLE_INT);
   wide_int mlow = wi::udiv_trunc (val, d);
 
-  /* mhigh = (2^(N + lgup) + 2^(N + lgup - precision))/d */
+  /* mhigh = (2^(n + lgup) + 2^(n + lgup - precision))/d */
+  /* From above we have mhigh < 2^(n+1) assuming lgup <= precision */
+  /* From precision <= n, the difference between the numerators of mhigh and
+ mlow is >= 2^lgup >= d.  Therefore the difference of the quotients in
+ the Euclidean division by d is at least 1, so we have mlow < mhigh and
+ the exact value of 2^(n + lgup)/d lies in the interval [mlow; mhigh).  */
   val |= wi::set_bit_in_zero (pow2, HOST_BITS_PER_DOUBLE_INT);
   wide_int mhigh = wi::udiv_trunc (val, d);
 
-  /* If precision == N, then mlow, mhigh exceed 2^N
- (but they do not exceed 2^(N+1)).  */
-
   /* Reduce to lowest terms.  */
+  /* If precision <= n - 1, then the difference between the numerators of
+ mhigh and mlow is >= 2^(lgup + 1) >= 2 * 2^lgup >= 2 * d.  Therefore
+ the difference of the quotients in the Euclidean division by d is at
+ least 2, which means that mhigh and mlow di

[PATCH] Add widening expansion of MULT_HIGHPART_EXPR for integral modes

2024-04-29 Thread Eric Botcazou
Hi,

for integral modes, the expansion of MULT_HIGHPART_EXPR requires the presence 
of an {s,u}mul_highpart optab whereas, for vector modes, widening expansion is
supported.  This adds a widening expansion for integral modes too, which is in 
fact already implemented in expmed_mult_highpart_optab.  We'll use that in a 
subsequent change to the Ada front-end to generate fast modulo reduction for 
modular types with nonbinary modulus (a little controversial Ada 95 feature).

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

2024-04-29  Eric Botcazou  

* expmed.h (expmed_mult_highpart_optab): Declare.
* expmed.cc (expmed_mult_highpart_optab): Remove static keyword.
Do not assume that OP1 is a constant integer.  Fix pasto.
(expmed_mult_highpart): Pass OP1 narrowed to MODE in all the calls
to expmed_mult_highpart_optab.
* optabs-query.cc (can_mult_highpart_p): Use 2 for integer widening
and shift subsequent values accordingly.
* optabs.cc (expand_mult_highpart): Call expmed_mult_highpart_optab
when can_mult_highpart_p returns 2 and adjust to above change.

-- 
Eric Botcazoudiff --git a/gcc/expmed.cc b/gcc/expmed.cc
index 60f65c7acc5..ccc671e922d 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -2742,8 +2742,7 @@ static rtx expand_mult_const (machine_mode, rtx, HOST_WIDE_INT, rtx,
 static unsigned HOST_WIDE_INT invert_mod2n (unsigned HOST_WIDE_INT, int);
 static rtx extract_high_half (scalar_int_mode, rtx);
 static rtx expmed_mult_highpart (scalar_int_mode, rtx, rtx, rtx, int, int);
-static rtx expmed_mult_highpart_optab (scalar_int_mode, rtx, rtx, rtx,
-   int, int);
+
 /* Compute and return the best algorithm for multiplying by T.
The algorithm must cost less than cost_limit
If retval.cost >= COST_LIMIT, no algorithm was found and all
@@ -3850,30 +3849,25 @@ extract_high_half (scalar_int_mode mode, rtx op)
   return convert_modes (mode, wider_mode, op, 0);
 }
 
-/* Like expmed_mult_highpart, but only consider using a multiplication
-   optab.  OP1 is an rtx for the constant operand.  */
+/* Like expmed_mult_highpart, but only consider using multiplication optab.  */
 
-static rtx
+rtx
 expmed_mult_highpart_optab (scalar_int_mode mode, rtx op0, rtx op1,
 			rtx target, int unsignedp, int max_cost)
 {
-  rtx narrow_op1 = gen_int_mode (INTVAL (op1), mode);
+  const scalar_int_mode wider_mode = GET_MODE_WIDER_MODE (mode).require ();
+  const bool speed = optimize_insn_for_speed_p ();
+  const int size = GET_MODE_BITSIZE (mode);
   optab moptab;
   rtx tem;
-  int size;
-  bool speed = optimize_insn_for_speed_p ();
-
-  scalar_int_mode wider_mode = GET_MODE_WIDER_MODE (mode).require ();
-
-  size = GET_MODE_BITSIZE (mode);
 
   /* Firstly, try using a multiplication insn that only generates the needed
  high part of the product, and in the sign flavor of unsignedp.  */
   if (mul_highpart_cost (speed, mode) < max_cost)
 {
   moptab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
-  tem = expand_binop (mode, moptab, op0, narrow_op1, target,
-			  unsignedp, OPTAB_DIRECT);
+  tem = expand_binop (mode, moptab, op0, op1, target, unsignedp,
+			  OPTAB_DIRECT);
   if (tem)
 	return tem;
 }
@@ -3886,12 +3880,12 @@ expmed_mult_highpart_optab (scalar_int_mode mode, rtx op0, rtx op1,
 	  + 4 * add_cost (speed, mode) < max_cost))
 {
   moptab = unsignedp ? smul_highpart_optab : umul_highpart_optab;
-  tem = expand_binop (mode, moptab, op0, narrow_op1, target,
-			  unsignedp, OPTAB_DIRECT);
+  tem = expand_binop (mode, moptab, op0, op1, target, !unsignedp,
+			  OPTAB_DIRECT);
   if (tem)
 	/* We used the wrong signedness.  Adjust the result.  */
-	return expand_mult_highpart_adjust (mode, tem, op0, narrow_op1,
-	tem, unsignedp);
+	return expand_mult_highpart_adjust (mode, tem, op0, op1, tem,
+	unsignedp);
 }
 
   /* Try widening multiplication.  */
@@ -3899,8 +3893,8 @@ expmed_mult_highpart_optab (scalar_int_mode mode, rtx op0, rtx op1,
   if (convert_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing
   && mul_widen_cost (speed, wider_mode) < max_cost)
 {
-  tem = expand_binop (wider_mode, moptab, op0, narrow_op1, 0,
-			  unsignedp, OPTAB_WIDEN);
+  tem = expand_binop (wider_mode, moptab, op0, op1, NULL_RTX, unsignedp,
+			  OPTAB_WIDEN);
   if (tem)
 	return extract_high_half (mode, tem);
 }
@@ -3941,14 +3935,14 @@ expmed_mult_highpart_optab (scalar_int_mode mode, rtx op0, rtx op1,
 	  + 2 * shift_cost (speed, mode, size-1)
 	  + 4 * add_cost (speed, mode) < max_cost))
 {
-  tem = expand_binop (wider_mode, moptab, op0, narrow_op1,
-			  NULL_RTX, ! unsignedp, OPTAB_WIDEN);
+  tem = expand_binop (wider_mode, moptab, op0, op1, NULL_RTX, !unsignedp,
+			  OPTAB_WIDEN);
   if (tem != 0)
 	{
 	  tem = extract_high_half (mode, tem);
 	  /* We used the wrong signedness.  Adjust the

Re: [PATCH] Minor tweaks to code computing modular multiplicative inverse

2024-04-29 Thread Eric Botcazou
> OK.  Consider waiting to commit though as we want to make it easy to
> cherry pick patches over to the release branch if needed.

Sure.  There are a couple more changes on top of it, but all can wait a bit.

-- 
Eric Botcazou




[PATCH] Minor tweaks to code computing modular multiplicative inverse

2024-04-29 Thread Eric Botcazou
Hi,

this removes the last parameter of choose_multiplier, which is unused, adds
another assertion and more details to the description and various comments.
Likewise to the closely related invert_mod2n, except for the last parameter.

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


2024-04-29  Eric Botcazou  

* expmed.h (choose_multiplier): Tweak description and remove last
parameter.
* expmed.cc (choose_multiplier): Likewise.  Add assertion for the
third parameter and adds details to various comments.
(invert_mod2n): Tweak description and add assertion for the first
parameter.
(expand_divmod): Adjust calls to choose_multiplier.
* tree-vect-generic.cc (expand_vector_divmod): Likewise.
* tree-vect-patterns.cc (vect_recog_divmod_pattern): Likewise.

-- 
Eric Botcazoudiff --git a/gcc/expmed.cc b/gcc/expmed.cc
index 4ec035e4843..60f65c7acc5 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -3689,50 +3689,62 @@ expand_widening_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
 		   unsignedp, OPTAB_LIB_WIDEN);
 }
 
-/* Choose a minimal N + 1 bit approximation to 1/D that can be used to
-   replace division by D, and put the least significant N bits of the result
-   in *MULTIPLIER_PTR and return the most significant bit.
+/* Choose a minimal N + 1 bit approximation to 2**K / D that can be used to
+   replace division by D, put the least significant N bits of the result in
+   *MULTIPLIER_PTR, the value K - N in *POST_SHIFT_PTR, and return the most
+   significant bit.
 
The width of operations is N (should be <= HOST_BITS_PER_WIDE_INT), the
-   needed precision is in PRECISION (should be <= N).
+   needed precision is PRECISION (should be <= N).
 
-   PRECISION should be as small as possible so this function can choose
-   multiplier more freely.
+   PRECISION should be as small as possible so this function can choose the
+   multiplier more freely.  If PRECISION is <= N - 1, the most significant
+   bit returned by the function will be zero.
 
-   The rounded-up logarithm of D is placed in *lgup_ptr.  A shift count that
-   is to be used for a final right shift is placed in *POST_SHIFT_PTR.
-
-   Using this function, x/D will be equal to (x * m) >> (*POST_SHIFT_PTR),
-   where m is the full HOST_BITS_PER_WIDE_INT + 1 bit multiplier.  */
+   Using this function, x / D is equal to (x*m) / 2**N >> (*POST_SHIFT_PTR),
+   where m is the full N + 1 bit multiplier.  */
 
 unsigned HOST_WIDE_INT
 choose_multiplier (unsigned HOST_WIDE_INT d, int n, int precision,
 		   unsigned HOST_WIDE_INT *multiplier_ptr,
-		   int *post_shift_ptr, int *lgup_ptr)
+		   int *post_shift_ptr)
 {
   int lgup, post_shift;
-  int pow, pow2;
+  int pow1, pow2;
 
-  /* lgup = ceil(log2(divisor)); */
+  /* lgup = ceil(log2(d)) */
+  /* Assuming d > 1, we have d >= 2^(lgup-1) + 1 */
   lgup = ceil_log2 (d);
 
   gcc_assert (lgup <= n);
+  gcc_assert (lgup <= precision);
 
-  pow = n + lgup;
+  pow1 = n + lgup;
   pow2 = n + lgup - precision;
 
-  /* mlow = 2^(N + lgup)/d */
-  wide_int val = wi::set_bit_in_zero (pow, HOST_BITS_PER_DOUBLE_INT);
+  /* mlow = 2^(n + lgup)/d */
+  /* Trivially from above we have mlow < 2^(n+1) */
+  wide_int val = wi::set_bit_in_zero (pow1, HOST_BITS_PER_DOUBLE_INT);
   wide_int mlow = wi::udiv_trunc (val, d);
 
-  /* mhigh = (2^(N + lgup) + 2^(N + lgup - precision))/d */
+  /* mhigh = (2^(n + lgup) + 2^(n + lgup - precision))/d */
+  /* From above we have mhigh < 2^(n+1) assuming lgup <= precision */
+  /* From precision <= n, the difference between the numerators of mhigh and
+ mlow is >= 2^lgup >= d.  Therefore the difference of the quotients in
+ the Euclidean division by d is at least 1, so we have mlow < mhigh and
+ the exact value of 2^(n + lgup)/d lies in the interval [mlow; mhigh(.  */
   val |= wi::set_bit_in_zero (pow2, HOST_BITS_PER_DOUBLE_INT);
   wide_int mhigh = wi::udiv_trunc (val, d);
 
-  /* If precision == N, then mlow, mhigh exceed 2^N
- (but they do not exceed 2^(N+1)).  */
-
   /* Reduce to lowest terms.  */
+  /* If precision <= n - 1, then the difference between the numerators of
+ mhigh and mlow is >= 2^(lgup + 1) >= 2 * 2^lgup >= 2 * d.  Therefore
+ the difference of the quotients in the Euclidean division by d is at
+ least 2, which means that mhigh and mlow differ by at least one bit
+ not in the last place.  The conclusion is that the first iteration of
+ the loop below completes and shifts mhigh and mlow by 1 bit, which in
+ particular means that mhigh < 2^n, that is to say, the most significant
+ bit in the n + 1 bit value is zero.  */
   for (post_shift = lgup; post_shift > 0; post_shift--)
 {
   unsigned HOST_WIDE_INT ml_lo = wi::extract_uhwi (mlow, 1,
@@ -3747,7 +3759,7 @@ choose_multiplier (unsigned HOST_WIDE_INT d, int n, int precision,
 }
 
   *post_shift

Re: [SPARC] Fix PR target/114416

2024-04-25 Thread Eric Botcazou
> For the 20th anniversary of https://gcc.gnu.org/gcc-3.4/sparc-abi.html, a
> new calling convention incompatibility with the vendor compiler (and the
> ABI) has been discovered in 64-bit mode, affecting small structures
> containing arrays of floating-point components.  The decision has been made
> to fix it on Solaris only at this point.

Documented by the attached patch, validated with W3C's Validator and applied.

-- 
Eric Botcazoudiff --git a/htdocs/gcc-14/changes.html b/htdocs/gcc-14/changes.html
index f0f0efe0..83b1016c 100644
--- a/htdocs/gcc-14/changes.html
+++ b/htdocs/gcc-14/changes.html
@@ -136,7 +136,7 @@ a work-in-progress.
 	int foo (int n)
 	{
 	  int res = 0;
-	  for (int i = 0; i < n; i++)
+	  for (int i = 0; i  n; i++)
 		{
 		   y[i] = x[i] * 2;
 		   res += x[i] + y[i];
@@ -1212,7 +1212,17 @@ __asm (".global __flmap_lock"  "\n\t"
 
 
 
-
+SPARC
+
+
+  
+The implementation of calling conventions for small structures containing
+arrays of floating-point components has been changed in 64-bit mode for
+the Solaris port to match the implementation of the vendor compiler (and
+the ABI). As a result, the code generated will not be binary compatible
+with earlier releases in these cases.
+  
+
 
 
 


gcc-wwwdocs branch master updated. 688a21c3093f0d3dbf7248066b5c9c00802bdf89

2024-04-25 Thread Eric Botcazou via Gcc-cvs-wwwdocs
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "gcc-wwwdocs".

The branch, master has been updated
   via  688a21c3093f0d3dbf7248066b5c9c00802bdf89 (commit)
  from  215f3f4f7d8ad162a9a3f5e48b475d82ee4cfb3d (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -
commit 688a21c3093f0d3dbf7248066b5c9c00802bdf89
Author: Eric Botcazou 
Date:   Thu Apr 25 19:37:27 2024 +0200

gcc-14/changes.html: Add SPARC section and fix syntax error

diff --git a/htdocs/gcc-14/changes.html b/htdocs/gcc-14/changes.html
index f0f0efe0..83b1016c 100644
--- a/htdocs/gcc-14/changes.html
+++ b/htdocs/gcc-14/changes.html
@@ -136,7 +136,7 @@ a work-in-progress.
int foo (int n)
{
  int res = 0;
- for (int i = 0; i < n; i++)
+ for (int i = 0; i  n; i++)
{
   y[i] = x[i] * 2;
   res += x[i] + y[i];
@@ -1212,7 +1212,17 @@ __asm (".global __flmap_lock"  "\n\t"
 
 
 
-
+SPARC
+
+
+  
+The implementation of calling conventions for small structures containing
+arrays of floating-point components has been changed in 64-bit mode for
+the Solaris port to match the implementation of the vendor compiler (and
+the ABI). As a result, the code generated will not be binary compatible
+with earlier releases in these cases.
+  
+
 
 
 

---

Summary of changes:
 htdocs/gcc-14/changes.html | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)


hooks/post-receive
-- 
gcc-wwwdocs


[SPARC] Fix PR target/114416

2024-04-25 Thread Eric Botcazou
For the 20th anniversary of https://gcc.gnu.org/gcc-3.4/sparc-abi.html, a new 
calling convention incompatibility with the vendor compiler (and the ABI) has 
been discovered in 64-bit mode, affecting small structures containing arrays 
of floating-point components.  The decision has been made to fix it on Solaris 
only at this point.

Bootstrapped/regtested on SPARC/Solaris 11.4 and SPARC64/Linux by Rainer (many 
thanks again) and applied on the mainline.


2024-04-25  Eric Botcazou  

PR target/114416
* config/sparc/sparc.h (SUN_V9_ABI_COMPATIBILITY): New macro.
* config/sparc/sol2.h (SUN_V9_ABI_COMPATIBILITY): Redefine it.
* config/sparc/sparc.cc (fp_type_for_abi): New predicate.
(traverse_record_type): Use it to spot floating-point types.
(compute_fp_layout): Also deal with array types.


2024-04-25  Eric Botcazou  

* gcc.target/sparc/small-struct-1.c: New test.

-- 
Eric Botcazoudiff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
index e849af9038b..552f58b2cc8 100644
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -456,3 +456,6 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 
 #undef SPARC_LOW_FE_EXCEPT_VALUES
 #define SPARC_LOW_FE_EXCEPT_VALUES 1
+
+#undef SUN_V9_ABI_COMPATIBILITY
+#define SUN_V9_ABI_COMPATIBILITY 1
diff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc
index 30fa4474bbd..8a5f76c8885 100644
--- a/gcc/config/sparc/sparc.cc
+++ b/gcc/config/sparc/sparc.cc
@@ -6782,6 +6782,22 @@ sparc_pass_by_reference (cumulative_args_t, const function_arg_info )
 	|| GET_MODE_SIZE (mode) > 16);
 }
 
+/* Return true if TYPE is considered as a floating-point type by the ABI.  */
+
+static bool
+fp_type_for_abi (const_tree type)
+{
+  /* This is the original GCC implementation.  */
+  if (FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type))
+return true;
+
+  /* This has been introduced in GCC 14 to match the vendor compiler.  */
+  if (SUN_V9_ABI_COMPATIBILITY && TREE_CODE (type) == ARRAY_TYPE)
+return fp_type_for_abi (TREE_TYPE (type));
+
+  return false;
+}
+
 /* Traverse the record TYPE recursively and call FUNC on its fields.
NAMED is true if this is for a named parameter.  DATA is passed
to FUNC for each field.  OFFSET is the starting position and
@@ -6820,8 +6836,7 @@ traverse_record_type (const_tree type, bool named, T *data,
 	 packed);
 	else
 	  {
-	const bool fp_type
-	  = FLOAT_TYPE_P (field_type) || VECTOR_TYPE_P (field_type);
+	const bool fp_type = fp_type_for_abi (field_type);
 	Func (field, bitpos, fp_type && named && !packed && TARGET_FPU,
 		  data);
 	  }
@@ -7072,6 +7087,13 @@ compute_fp_layout (const_tree field, int bitpos, assign_data_t *data,
   mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (field)));
   nregs = 2;
 }
+  else if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
+{
+  tree elt_type = strip_array_types (TREE_TYPE (field));
+  mode = TYPE_MODE (elt_type);
+  nregs
+	= int_size_in_bytes (TREE_TYPE (field)) / int_size_in_bytes (elt_type);
+}
   else
 nregs = 1;
 
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index fb074808d30..232ecb30ddc 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1700,3 +1700,6 @@ extern int sparc_indent_opcode;
 #define SPARC_LOW_FE_EXCEPT_VALUES 0
 
 #define TARGET_SUPPORTS_WIDE_INT 1
+
+/* Define this to 1 to accept ABI changes to match the vendor compiler.  */
+#define SUN_V9_ABI_COMPATIBILITY 0
/* PR target/114416 */
/* Reported by Rainer Orth  */

/* { dg-do compile } */
/* { dg-options "-O" } */
/* { dg-require-effective-target lp64 } */

struct vec2
{
  double x[2];
};

struct vec2x
{
  double x;
  double y;
};

struct vec2 sum2 (double val)
{
  struct vec2 v;
  v.x[0] = val;
  v.x[1] = val;
  return v;
}

struct vec2x sum2x (double val)
{
  struct vec2x v;
  v.x = val;
  v.y = val;
  return v;
}

double get2 (struct vec2 v)
{
  return v.x[0] + v.x[1];
}

double get2x (struct vec2x v)
{
  return v.x + v.y;
}

/* { dg-final { scan-assembler-not "ldx" } } */
/* { dg-final { scan-assembler-not "stx" } } */


[gcc r14-10119] Fix calling convention incompatibility with vendor compiler

2024-04-25 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:1d238c84025aaef1641e4000bd2a8f4328b474dd

commit r14-10119-g1d238c84025aaef1641e4000bd2a8f4328b474dd
Author: Eric Botcazou 
Date:   Thu Apr 25 12:44:14 2024 +0200

Fix calling convention incompatibility with vendor compiler

For the 20th anniversary of https://gcc.gnu.org/gcc-3.4/sparc-abi.html,
a new calling convention incompatibility with the vendor compiler (and
the ABI) has been discovered in 64-bit mode, affecting small structures
containing arrays of floating-point components.  The decision has been
made to fix it on Solaris only at this point.

gcc/
PR target/114416
* config/sparc/sparc.h (SUN_V9_ABI_COMPATIBILITY): New macro.
* config/sparc/sol2.h (SUN_V9_ABI_COMPATIBILITY): Redefine it.
* config/sparc/sparc.cc (fp_type_for_abi): New predicate.
(traverse_record_type): Use it to spot floating-point types.
(compute_fp_layout): Also deal with array types.

gcc/testsuite/
* gcc.target/sparc/small-struct-1.c: New test.
* gcc.target/sparc/pr105573.c: Rename to...
* gcc.target/sparc/20230425-1.c: ...this.
* gcc.target/sparc/pr109541.c: Rename to...
* gcc.target/sparc/20230607-1.c: ...this

Diff:
---
 gcc/config/sparc/sol2.h|  3 ++
 gcc/config/sparc/sparc.cc  | 26 +++-
 gcc/config/sparc/sparc.h   |  3 ++
 .../gcc.target/sparc/{pr105573.c => 20230425-1.c}  |  3 ++
 .../gcc.target/sparc/{pr109541.c => 20230607-1.c}  |  3 ++
 gcc/testsuite/gcc.target/sparc/small-struct-1.c| 46 ++
 6 files changed, 82 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
index e849af9038b..552f58b2cc8 100644
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -456,3 +456,6 @@ extern const char *host_detect_local_cpu (int argc, const 
char **argv);
 
 #undef SPARC_LOW_FE_EXCEPT_VALUES
 #define SPARC_LOW_FE_EXCEPT_VALUES 1
+
+#undef SUN_V9_ABI_COMPATIBILITY
+#define SUN_V9_ABI_COMPATIBILITY 1
diff --git a/gcc/config/sparc/sparc.cc b/gcc/config/sparc/sparc.cc
index 30fa4474bbd..8a5f76c8885 100644
--- a/gcc/config/sparc/sparc.cc
+++ b/gcc/config/sparc/sparc.cc
@@ -6782,6 +6782,22 @@ sparc_pass_by_reference (cumulative_args_t, const 
function_arg_info )
|| GET_MODE_SIZE (mode) > 16);
 }
 
+/* Return true if TYPE is considered as a floating-point type by the ABI.  */
+
+static bool
+fp_type_for_abi (const_tree type)
+{
+  /* This is the original GCC implementation.  */
+  if (FLOAT_TYPE_P (type) || VECTOR_TYPE_P (type))
+return true;
+
+  /* This has been introduced in GCC 14 to match the vendor compiler.  */
+  if (SUN_V9_ABI_COMPATIBILITY && TREE_CODE (type) == ARRAY_TYPE)
+return fp_type_for_abi (TREE_TYPE (type));
+
+  return false;
+}
+
 /* Traverse the record TYPE recursively and call FUNC on its fields.
NAMED is true if this is for a named parameter.  DATA is passed
to FUNC for each field.  OFFSET is the starting position and
@@ -6820,8 +6836,7 @@ traverse_record_type (const_tree type, bool named, T 
*data,
 packed);
else
  {
-   const bool fp_type
- = FLOAT_TYPE_P (field_type) || VECTOR_TYPE_P (field_type);
+   const bool fp_type = fp_type_for_abi (field_type);
Func (field, bitpos, fp_type && named && !packed && TARGET_FPU,
  data);
  }
@@ -7072,6 +7087,13 @@ compute_fp_layout (const_tree field, int bitpos, 
assign_data_t *data,
   mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (field)));
   nregs = 2;
 }
+  else if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
+{
+  tree elt_type = strip_array_types (TREE_TYPE (field));
+  mode = TYPE_MODE (elt_type);
+  nregs
+   = int_size_in_bytes (TREE_TYPE (field)) / int_size_in_bytes (elt_type);
+}
   else
 nregs = 1;
 
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index fb074808d30..232ecb30ddc 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1700,3 +1700,6 @@ extern int sparc_indent_opcode;
 #define SPARC_LOW_FE_EXCEPT_VALUES 0
 
 #define TARGET_SUPPORTS_WIDE_INT 1
+
+/* Define this to 1 to accept ABI changes to match the vendor compiler.  */
+#define SUN_V9_ABI_COMPATIBILITY 0
diff --git a/gcc/testsuite/gcc.target/sparc/pr105573.c 
b/gcc/testsuite/gcc.target/sparc/20230425-1.c
similarity index 82%
rename from gcc/testsuite/gcc.target/sparc/pr105573.c
rename to gcc/testsuite/gcc.target/sparc/20230425-1.c
index 14043a5fdad..c07dd3261fc 100644
--- a/gcc/testsuite/gcc.target/sparc/pr105573.c
+++ b/gcc/testsuite/gcc.target/sparc/20230425-1.c
@@ -1,3 +1,6 @@
+/* PR target/105573 */
+/* Reported by Sam James  */
+
 /* { dg-do compile } */
 /* { dg-options "-O3 -mvis3"

[gcc r13-8436] ada: Fix error message for Aggregate aspect

2024-03-13 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:618db8d5ecd6d113d3089fda6fbf8bf472ddfc25

commit r13-8436-g618db8d5ecd6d113d3089fda6fbf8bf472ddfc25
Author: Marc Poulhiès 
Date:   Wed Mar 8 20:39:45 2023 +0100

ada: Fix error message for Aggregate aspect

The error message was wrongly using % instead of & in the format string,
causing the displayed message to refer to incorrect names in some cases.

gcc/ada/

* sem_ch13.adb (Check_Aspect_At_Freeze_Point): fix format string,
use existing local Ident.

Diff:
---
 gcc/ada/sem_ch13.adb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 073e8f9b0d8..550f10366f2 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -11147,8 +11147,8 @@ package body Sem_Ch13 is
  when Aspect_Aggregate =>
 if Is_Array_Type (Entity (ASN)) then
Error_Msg_N
- ("aspect% can only be applied to non-array type",
-  Identifier (ASN));
+ ("aspect& can only be applied to non-array type",
+  Ident);
 end if;
 Resolve_Aspect_Aggregate (Entity (ASN), Expression (ASN));
 return;


[gcc r13-8435] ada: Fix (again) incorrect handling of Aggregate aspect

2024-03-13 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:6c8e7aa2ce1d51050c59c1492be2a29890d2c172

commit r13-8435-g6c8e7aa2ce1d51050c59c1492be2a29890d2c172
Author: Marc Poulhiès 
Date:   Mon Mar 6 12:15:13 2023 +0100

ada: Fix (again) incorrect handling of Aggregate aspect

Previous fix stopped the processing of the Aggregate aspect early,
skipping the call to Record_Rep_Item, making later call to
Resolve_Container_Aggregate fail.

Also, the previous fix would not handle correctly the case where the
type is private and the check for non-array type can only be done at the
freeze point with the full type.

Adapt the resolving of the aspect when the input is not correct and the
parameters can't be resolved.

gcc/ada/

* sem_ch13.adb (Analyze_One_Aspect): Call Record_Rep_Item.
(Check_Aspect_At_Freeze_Point): Check the aspect is specified on
non-array type only...
(Analyze_One_Aspect): ... instead of doing it too early here.
* sem_aggr.adb (Resolve_Container_Aggregate): Do nothing in case
the parameters failed to resolve.

Diff:
---
 gcc/ada/sem_aggr.adb |  9 +++--
 gcc/ada/sem_ch13.adb | 12 +++-
 2 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index 3ebb30d64ed..8d8a26329b5 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -3157,6 +3157,7 @@ package body Sem_Aggr is
 
   if Present (Add_Unnamed_Subp)
 and then No (New_Indexed_Subp)
+and then Etype (Add_Unnamed_Subp) /= Any_Type
   then
  declare
 Elmt_Type : constant Entity_Id :=
@@ -3200,7 +3201,9 @@ package body Sem_Aggr is
 end if;
  end;
 
-  elsif Present (Add_Named_Subp) then
+  elsif Present (Add_Named_Subp)
+and then Etype (Add_Named_Subp) /= Any_Type
+  then
  declare
 --  Retrieves types of container, key, and element from the
 --  specified insertion procedure.
@@ -3242,7 +3245,9 @@ package body Sem_Aggr is
 end loop;
  end;
 
-  elsif Present (Assign_Indexed_Subp) then
+  elsif Present (Assign_Indexed_Subp)
+and then Etype (Assign_Indexed_Subp) /= Any_Type
+  then
  --  Indexed Aggregate. Positional or indexed component
  --  can be present, but not both. Choices must be static
  --  values or ranges with static bounds.
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index 317c4841d87..073e8f9b0d8 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -4211,11 +4211,8 @@ package body Sem_Ch13 is
   Aitem := Empty;
 
when Aspect_Aggregate =>
-  if Is_Array_Type (E) then
- Error_Msg_N
-   ("aspect% can only be applied to non-array type", Id);
- goto Continue;
-  end if;
+  --  We will be checking that the aspect is not specified on a
+  --  non-array type in Check_Aspect_At_Freeze_Point
 
   Validate_Aspect_Aggregate (Expr);
   Record_Rep_Item (E, Aspect);
@@ -11148,6 +11145,11 @@ package body Sem_Ch13 is
 return;
 
  when Aspect_Aggregate =>
+if Is_Array_Type (Entity (ASN)) then
+   Error_Msg_N
+ ("aspect% can only be applied to non-array type",
+  Identifier (ASN));
+end if;
 Resolve_Aspect_Aggregate (Entity (ASN), Expression (ASN));
 return;


[gcc r13-8434] ada: Fix incorrect handling of Aggregate aspect

2024-03-13 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:bc97504e021fd8719fa6d9e31c311b38e87a3900

commit r13-8434-gbc97504e021fd8719fa6d9e31c311b38e87a3900
Author: Marc Poulhiès 
Date:   Tue Feb 28 17:10:29 2023 +0100

ada: Fix incorrect handling of Aggregate aspect

This change fixes 2 incorrect handlings of the aspect.
The arguments are now correctly resolved and the aspect is rejected on
non array types.

gcc/ada/

* sem_ch13.adb (Analyze_One_Aspect): Mark Aggregate aspect as
needing delayed resolution and reject the aspect on non-array
type.

Diff:
---
 gcc/ada/sem_ch13.adb | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index b81b6b02e1d..317c4841d87 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -2921,10 +2921,10 @@ package body Sem_Ch13 is
 end case;
 
 if Delay_Required
-
and then (A_Id = Aspect_Stable_Properties
   or else A_Id = Aspect_Designated_Storage_Model
-  or else A_Id = Aspect_Storage_Model_Type)
+  or else A_Id = Aspect_Storage_Model_Type
+  or else A_Id = Aspect_Aggregate)
--  ??? It seems like we should do this for all aspects, not
--  just these, but that causes as-yet-undiagnosed regressions.
 
@@ -4211,6 +4211,12 @@ package body Sem_Ch13 is
   Aitem := Empty;
 
when Aspect_Aggregate =>
+  if Is_Array_Type (E) then
+ Error_Msg_N
+   ("aspect% can only be applied to non-array type", Id);
+ goto Continue;
+  end if;
+
   Validate_Aspect_Aggregate (Expr);
   Record_Rep_Item (E, Aspect);
   goto Continue;


Re: [PATCH] Fix PR ipa/113996

2024-03-12 Thread Eric Botcazou
> Patch is still OK, but ipa-ICF will only identify the functions if
> static chain is unused. Perhaps just picking the winning candidate to be
> version without static chain and making ipa-inline to not ICE when calls
> with static chain lands to function with no static chain would help us
> to optimize better.

I see, thanks for the explanation.  The attached patch appears to work.


PR ipa/113996
* ipa-icf.h (sem_function): Add static_chain_p member.
* ipa-icf.cc (sem_function::init): Initialize it.
(sem_item_optimizer::merge_classes): If the class is made of
functions, pick one without static chain as the target.

-- 
Eric Botcazoudiff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
index 5d5a42f9c6c..4fc02831798 100644
--- a/gcc/ipa-icf.cc
+++ b/gcc/ipa-icf.cc
@@ -1368,6 +1368,8 @@ sem_function::init (ipa_icf_gimple::func_checker *checker)
   /* iterating all function arguments.  */
   arg_count = count_formal_params (fndecl);
 
+  static_chain_p = func->static_chain_decl != NULL_TREE;
+
   edge_count = n_edges_for_fn (func);
   cgraph_node *cnode = dyn_cast  (node);
   if (!cnode->thunk)
@@ -3399,11 +3401,22 @@ sem_item_optimizer::merge_classes (unsigned int prev_class_count,
 
 	sem_item *source = c->members[0];
 
-	if (DECL_NAME (source->decl)
-	&& MAIN_NAME_P (DECL_NAME (source->decl)))
-	  /* If merge via wrappers, picking main as the target can be
-	 problematic.  */
-	  source = c->members[1];
+	if (source->type == FUNC)
+	  {
+	/* Pick a member without static chain, if any.  */
+	for (unsigned int j = 0; j < c->members.length (); j++)
+	  if (!static_cast (c->members[j])->static_chain_p)
+		{
+		  source = c->members[j];
+		  break;
+		}
+
+	/* If merge via wrappers, picking main as the target can be
+	   problematic.  */
+	if (DECL_NAME (source->decl)
+		&& MAIN_NAME_P (DECL_NAME (source->decl)))
+	  source = c->members[source == c->members[0] ? 1 : 0];
+	  }
 
 	for (unsigned int j = 0; j < c->members.length (); j++)
 	  {
diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h
index ef7e41bfa88..da20862c306 100644
--- a/gcc/ipa-icf.h
+++ b/gcc/ipa-icf.h
@@ -355,6 +355,9 @@ public:
  parameters.  */
   bool compatible_parm_types_p (tree, tree);
 
+  /* Return true if parameter I may be used.  */
+  bool param_used_p (unsigned int i);
+
   /* Exception handling region tree.  */
   eh_region region_tree;
 
@@ -379,6 +382,9 @@ public:
   /* Total number of SSA names used in the function.  */
   unsigned ssa_names_size;
 
+  /* Whether the special PARM_DECL for the static chain is present.  */
+  bool static_chain_p;
+
   /* Array of structures for all basic blocks.  */
   vec  bb_sorted;
 
@@ -386,9 +392,6 @@ public:
  function.  */
   hashval_t m_alias_sets_hash;
 
-  /* Return true if parameter I may be used.  */
-  bool param_used_p (unsigned int i);
-
 private:
   /* Calculates hash value based on a BASIC_BLOCK.  */
   hashval_t get_bb_hash (const ipa_icf_gimple::sem_bb *basic_block);


[PATCH] Fix PR ipa/113996

2024-03-11 Thread Eric Botcazou
Hi,

this is a regression present on all active branches: the attached Ada testcase 
triggers an assertion failure when compiled with -O2 -gnatp -flto:

  /* Initialize the static chain.  */
  p = DECL_STRUCT_FUNCTION (fn)->static_chain_decl;
  gcc_assert (fn != current_function_decl);
  if (p)
{
  /* No static chain?  Seems like a bug in tree-nested.cc.  */
  gcc_assert (static_chain);  <--- here

  setup_one_parameter (id, p, static_chain, fn, bb, );
}

The problem is that the ICF pass identifies two functions, one of which has a 
static chain but the other does not.  The proposed fix is just to prevent this 
identification from occurring.

Tested on x86-64/Linux, OK for all active branches?


2024-03-11  Eric Botcazou  

PR ipa/113996
* ipa-icf.h (sem_function): Add static_chain_present member.
* ipa-icf.cc (sem_function::get_hash): Hash it.
(sem_function::equals_wpa): Compare it.
(sem_function::equals_private): Likewise.
(sem_function::init): Initialize it.


2024-03-11  Eric Botcazou  

* gnat.dg/lto27.adb: New test.

-- 
Eric Botcazou-- { dg-do link }
-- { dg-options "-O2 -gnatp -flto" { target lto } }

with Ada.Containers.Hashed_Maps;
with Ada.Strings.Hash;

procedure Lto27 is
   subtype Node_Name is String (1 .. 4);

   package Node_Maps is new Ada.Containers.Hashed_Maps
 (Key_Type=> Node_Name,
  Element_Type=> Integer,
  Hash=> Ada.Strings.Hash,
  Equivalent_Keys => "=");

begin
   null;
end;
diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
index 5d5a42f9c6c..dff7ad6efda 100644
--- a/gcc/ipa-icf.cc
+++ b/gcc/ipa-icf.cc
@@ -284,6 +284,7 @@ sem_function::get_hash (void)
   hstate.add_int (177454); /* Random number for function type.  */
 
   hstate.add_int (arg_count);
+  hstate.add_int (static_chain_present);
   hstate.add_int (cfg_checksum);
   hstate.add_int (gcode_hash);
 
@@ -655,7 +656,10 @@ sem_function::equals_wpa (sem_item *item,
 }
 
   if (list1 || list2)
-return return_false_with_msg ("Mismatched number of parameters");
+return return_false_with_msg ("mismatched number of parameters");
+
+  if (static_chain_present != m_compared_func->static_chain_present)
+return return_false_with_msg ("static chain mismatch");
 
   if (node->num_references () != item->node->num_references ())
 return return_false_with_msg ("different number of references");
@@ -876,7 +880,10 @@ sem_function::equals_private (sem_item *item)
 return return_false ();
 }
   if (arg1 || arg2)
-return return_false_with_msg ("Mismatched number of arguments");
+return return_false_with_msg ("mismatched number of arguments");
+
+  if (static_chain_present != m_compared_func->static_chain_present)
+return return_false_with_msg ("static chain mismatch");
 
   if (!dyn_cast  (node)->has_gimple_body_p ())
 return true;
@@ -1368,6 +1375,8 @@ sem_function::init (ipa_icf_gimple::func_checker *checker)
   /* iterating all function arguments.  */
   arg_count = count_formal_params (fndecl);
 
+  static_chain_present = func->static_chain_decl != NULL_TREE;
+
   edge_count = n_edges_for_fn (func);
   cgraph_node *cnode = dyn_cast  (node);
   if (!cnode->thunk)
diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h
index ef7e41bfa88..bd9fd9fb294 100644
--- a/gcc/ipa-icf.h
+++ b/gcc/ipa-icf.h
@@ -355,6 +355,9 @@ public:
  parameters.  */
   bool compatible_parm_types_p (tree, tree);
 
+  /* Return true if parameter I may be used.  */
+  bool param_used_p (unsigned int i);
+
   /* Exception handling region tree.  */
   eh_region region_tree;
 
@@ -379,6 +382,9 @@ public:
   /* Total number of SSA names used in the function.  */
   unsigned ssa_names_size;
 
+  /* Whether the special PARM_DECL for the static chain is present.  */
+  bool static_chain_present;
+
   /* Array of structures for all basic blocks.  */
   vec  bb_sorted;
 
@@ -386,9 +392,6 @@ public:
  function.  */
   hashval_t m_alias_sets_hash;
 
-  /* Return true if parameter I may be used.  */
-  bool param_used_p (unsigned int i);
-
 private:
   /* Calculates hash value based on a BASIC_BLOCK.  */
   hashval_t get_bb_hash (const ipa_icf_gimple::sem_bb *basic_block);


Fix PR debug/113519 and debug/113777

2024-03-11 Thread Eric Botcazou
They both come from an oversight of mine in the placement of the DIE created 
for an enumeration type with reverse scalar storage order.

Tested on x86-64/Linux, both GCC and GDB, applied on mainline as obvious.


2024-03-11  Eric Botcazou  

PR debug/113519
PR debug/113777
* dwarf2out.cc (gen_enumeration_type_die): In the reverse case,
generate the DIE with the same parent as in the regular case.


2024-03-11  Eric Botcazou  

* gcc.dg/sso-20.c: New test.
* gcc.dg/sso-21.c: Likewise.

-- 
Eric Botcazoudiff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 03d73f9eecd..9b1548e4ae3 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -22868,18 +22868,19 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die, bool reverse)
 
   if (type_die == NULL || reverse)
 {
+  dw_die_ref scope_die = scope_die_for (type, context_die);
+
   /* The DIE with DW_AT_endianity is placed right after the naked DIE.  */
   if (reverse)
 	{
 	  gcc_assert (type_die);
 	  dw_die_ref after_die = type_die;
 	  type_die = new_die_raw (DW_TAG_enumeration_type);
-	  add_child_die_after (context_die, type_die, after_die);
+	  add_child_die_after (scope_die, type_die, after_die);
 	}
   else
 	{
-	  type_die = new_die (DW_TAG_enumeration_type,
-			  scope_die_for (type, context_die), type);
+	  type_die = new_die (DW_TAG_enumeration_type, scope_die, type);
 	  equate_type_number_to_die (type, type_die);
 	}
   add_name_attribute (type_die, type_tag (type));
/* PR debug/113519 */
/* Reported by Zdenek Sojka  */

/* { dg-do compile } */
/* { dg-options "-g -fdebug-types-section" } */

enum E { X };

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
struct __attribute__((scalar_storage_order("big-endian")))
{
  enum E e;
} S;
#else
struct __attribute__((scalar_storage_order("little-endian")))
{
  enum E e;
} S;
#endif
/* PR debug/113777 */
/* Reported by Zdenek Sojka  */

/* { dg-do compile } */
/* { dg-options "-g" } */

typedef short __attribute__((__hardbool__)) hbool;

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
struct __attribute__((scalar_storage_order("big-endian")))
{
  hbool a[2];
} S;
#else
struct __attribute__((scalar_storage_order("little-endian")))
{
  hbool a[2];
} S;
#endif


[gcc r14-9423] Fix placement of recently implemented DIE

2024-03-11 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:0c4df2c3c38ca15c123e9a801b617e63256c83a3

commit r14-9423-g0c4df2c3c38ca15c123e9a801b617e63256c83a3
Author: Eric Botcazou 
Date:   Mon Mar 11 09:24:50 2024 +0100

Fix placement of recently implemented DIE

It's the DIE added for enumeration types with reverse scalar storage order.

gcc/
PR debug/113519
PR debug/113777
* dwarf2out.cc (gen_enumeration_type_die): In the reverse case,
generate the DIE with the same parent as in the regular case.

gcc/testsuite/
* gcc.dg/sso-20.c: New test.
* gcc.dg/sso-21.c: Likewise.

Diff:
---
 gcc/dwarf2out.cc  |  7 ---
 gcc/testsuite/gcc.dg/sso-20.c | 19 +++
 gcc/testsuite/gcc.dg/sso-21.c | 19 +++
 3 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 87e4240b871..8f18bc4fe64 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -22868,18 +22868,19 @@ gen_enumeration_type_die (tree type, dw_die_ref 
context_die, bool reverse)
 
   if (type_die == NULL || reverse)
 {
+  dw_die_ref scope_die = scope_die_for (type, context_die);
+
   /* The DIE with DW_AT_endianity is placed right after the naked DIE.  */
   if (reverse)
{
  gcc_assert (type_die);
  dw_die_ref after_die = type_die;
  type_die = new_die_raw (DW_TAG_enumeration_type);
- add_child_die_after (context_die, type_die, after_die);
+ add_child_die_after (scope_die, type_die, after_die);
}
   else
{
- type_die = new_die (DW_TAG_enumeration_type,
- scope_die_for (type, context_die), type);
+ type_die = new_die (DW_TAG_enumeration_type, scope_die, type);
  equate_type_number_to_die (type, type_die);
}
   add_name_attribute (type_die, type_tag (type));
diff --git a/gcc/testsuite/gcc.dg/sso-20.c b/gcc/testsuite/gcc.dg/sso-20.c
new file mode 100644
index 000..3bea38423a8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sso-20.c
@@ -0,0 +1,19 @@
+/* PR debug/113519 */
+/* Reported by Zdenek Sojka  */
+
+/* { dg-do compile } */
+/* { dg-options "-g -fdebug-types-section" } */
+
+enum E { X };
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+struct __attribute__((scalar_storage_order("big-endian")))
+{
+  enum E e;
+} S;
+#else
+struct __attribute__((scalar_storage_order("little-endian")))
+{
+  enum E e;
+} S;
+#endif
diff --git a/gcc/testsuite/gcc.dg/sso-21.c b/gcc/testsuite/gcc.dg/sso-21.c
new file mode 100644
index 000..4b5d76d479b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/sso-21.c
@@ -0,0 +1,19 @@
+/* PR debug/113777 */
+/* Reported by Zdenek Sojka  */
+
+/* { dg-do compile } */
+/* { dg-options "-g" } */
+
+typedef short __attribute__((__hardbool__)) hbool;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+struct __attribute__((scalar_storage_order("big-endian")))
+{
+  hbool a[2];
+} S;
+#else
+struct __attribute__((scalar_storage_order("little-endian")))
+{
+  hbool a[2];
+} S;
+#endif


[Ada] Fix PR ada/113979

2024-03-07 Thread Eric Botcazou
This is a regression present on all active branches: the compiler gives a 
bogus error on an allocator for an unconstrained array type declared with a 
Dynamic_Predicate because Apply_Predicate_Check is invoked directly on a 
subtype reference, which it cannot handle.

This moves the check to the resulting access value (after dereference) like in 
Expand_Allocator_Expression.

Tested on x86-64/Linux, applied on all active branches.


2024-03-07  Eric Botcazou  

PR ada/113979
* exp_ch4.adb (Expand_N_Allocator): In the subtype indication case,
call Apply_Predicate_Check on the resulting access value if needed.


2024-03-07  Eric Botcazou  

* testsuite/gnat.dg/predicate15.adb: New test.

-- 
Eric Botcazoudiff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 4f83cd4737a..e4a40414872 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -4657,8 +4657,6 @@ package body Exp_Ch4 is
  if Is_Array_Type (Dtyp) and then not No_Initialization (N) then
 Apply_Constraint_Check (Expression (N), Dtyp, No_Sliding => True);
 
-Apply_Predicate_Check (Expression (N), Dtyp);
-
 if Nkind (Expression (N)) = N_Raise_Constraint_Error then
Rewrite (N, New_Copy (Expression (N)));
Set_Etype (N, PtrT);
@@ -4752,6 +4750,8 @@ package body Exp_Ch4 is
 Rewrite (N, New_Occurrence_Of (Temp, Loc));
 Analyze_And_Resolve (N, PtrT);
 
+Apply_Predicate_Check (N, Dtyp, Deref => True);
+
  --  Case of no initialization procedure present
 
  elsif not Has_Non_Null_Base_Init_Proc (T) then
@@ -5119,6 +5119,8 @@ package body Exp_Ch4 is
Rewrite (N, New_Occurrence_Of (Temp, Loc));
Analyze_And_Resolve (N, PtrT);
 
+   Apply_Predicate_Check (N, Dtyp, Deref => True);
+
--  When designated type has Default_Initial_Condition aspects,
--  make a call to the type's DIC procedure to perform the
--  checks. Theoretically this might also be needed for cases
-- { dg-do compile }
-- { dg-options "-gnata" }

procedure Predicate15 is

   type Grid is array (Positive range <>) of Integer with
  Dynamic_Predicate => Grid'First = 1;

   type Grid_Ptr is access Grid;

   Data : Grid_Ptr := new Grid (1 .. 10);

begin
   null;
end;


[gcc r11-11272] Fix bogus error on allocator for array type with Dynamic_Predicate

2024-03-07 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:b26501b6e310345ad9f6423b3f8b9df178c5e7d9

commit r11-11272-gb26501b6e310345ad9f6423b3f8b9df178c5e7d9
Author: Eric Botcazou 
Date:   Thu Mar 7 15:05:54 2024 +0100

Fix bogus error on allocator for array type with Dynamic_Predicate

This is a regression present on all active branches: the compiler gives
a bogus error on an allocator for an unconstrained array type declared
with a Dynamic_Predicate because Apply_Predicate_Check is invoked directly
on a subtype reference, which it cannot handle.

This moves the check to the resulting access value (after dereference) like
in Expand_Allocator_Expression.

gcc/ada/
PR ada/113979
* exp_ch4.adb (Expand_N_Allocator): In the subtype indication case,
remove call to Apply_Predicate_Check.

gcc/testsuite/
* gnat.dg/predicate15.adb: New test.

Diff:
---
 gcc/ada/exp_ch4.adb   |  2 --
 gcc/testsuite/gnat.dg/predicate15.adb | 15 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 44370786a3d..48dae8396d0 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -4970,8 +4970,6 @@ package body Exp_Ch4 is
  if Is_Array_Type (Dtyp) and then not No_Initialization (N) then
 Apply_Constraint_Check (Expression (N), Dtyp, No_Sliding => True);
 
-Apply_Predicate_Check (Expression (N), Dtyp);
-
 if Nkind (Expression (N)) = N_Raise_Constraint_Error then
Rewrite (N, New_Copy (Expression (N)));
Set_Etype (N, PtrT);
diff --git a/gcc/testsuite/gnat.dg/predicate15.adb 
b/gcc/testsuite/gnat.dg/predicate15.adb
new file mode 100644
index 000..cf9e1d9e17f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate15.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+procedure Predicate15 is
+
+   type Grid is array (Positive range <>) of Integer with
+  Dynamic_Predicate => Grid'First = 1;
+
+   type Grid_Ptr is access Grid;
+
+   Data : Grid_Ptr := new Grid (1 .. 10);
+
+begin
+   null;
+end;


[gcc r12-10197] Fix bogus error on allocator for array type with Dynamic_Predicate

2024-03-07 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:f9e1d7aa8b4f0b8afff1de59fcadf1db0244b4e1

commit r12-10197-gf9e1d7aa8b4f0b8afff1de59fcadf1db0244b4e1
Author: Eric Botcazou 
Date:   Thu Mar 7 15:05:54 2024 +0100

Fix bogus error on allocator for array type with Dynamic_Predicate

This is a regression present on all active branches: the compiler gives
a bogus error on an allocator for an unconstrained array type declared
with a Dynamic_Predicate because Apply_Predicate_Check is invoked directly
on a subtype reference, which it cannot handle.

This moves the check to the resulting access value (after dereference) like
in Expand_Allocator_Expression.

gcc/ada/
PR ada/113979
* exp_ch4.adb (Expand_N_Allocator): In the subtype indication case,
remove call to Apply_Predicate_Check.

gcc/testsuite/
* gnat.dg/predicate15.adb: New test.

Diff:
---
 gcc/ada/exp_ch4.adb   |  2 --
 gcc/testsuite/gnat.dg/predicate15.adb | 15 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 2506c67e936..6429c6e9d69 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -4823,8 +4823,6 @@ package body Exp_Ch4 is
  if Is_Array_Type (Dtyp) and then not No_Initialization (N) then
 Apply_Constraint_Check (Expression (N), Dtyp, No_Sliding => True);
 
-Apply_Predicate_Check (Expression (N), Dtyp);
-
 if Nkind (Expression (N)) = N_Raise_Constraint_Error then
Rewrite (N, New_Copy (Expression (N)));
Set_Etype (N, PtrT);
diff --git a/gcc/testsuite/gnat.dg/predicate15.adb 
b/gcc/testsuite/gnat.dg/predicate15.adb
new file mode 100644
index 000..cf9e1d9e17f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate15.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+procedure Predicate15 is
+
+   type Grid is array (Positive range <>) of Integer with
+  Dynamic_Predicate => Grid'First = 1;
+
+   type Grid_Ptr is access Grid;
+
+   Data : Grid_Ptr := new Grid (1 .. 10);
+
+begin
+   null;
+end;


[gcc r13-8409] Fix bogus error on allocator for array type with Dynamic_Predicate

2024-03-07 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:0e591e6f27a20c26672ea8c0550a6ef673c1fccf

commit r13-8409-g0e591e6f27a20c26672ea8c0550a6ef673c1fccf
Author: Eric Botcazou 
Date:   Thu Mar 7 15:05:54 2024 +0100

Fix bogus error on allocator for array type with Dynamic_Predicate

This is a regression present on all active branches: the compiler gives
a bogus error on an allocator for an unconstrained array type declared
with a Dynamic_Predicate because Apply_Predicate_Check is invoked directly
on a subtype reference, which it cannot handle.

This moves the check to the resulting access value (after dereference) like
in Expand_Allocator_Expression.

gcc/ada/
PR ada/113979
* exp_ch4.adb (Expand_N_Allocator): In the subtype indication case,
remove call to Apply_Predicate_Check.

gcc/testsuite/
* gnat.dg/predicate15.adb: New test.

Diff:
---
 gcc/ada/exp_ch4.adb   |  2 --
 gcc/testsuite/gnat.dg/predicate15.adb | 15 +++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 8442de6f90c..5cb6ee25702 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -4785,8 +4785,6 @@ package body Exp_Ch4 is
  if Is_Array_Type (Dtyp) and then not No_Initialization (N) then
 Apply_Constraint_Check (Expression (N), Dtyp, No_Sliding => True);
 
-Apply_Predicate_Check (Expression (N), Dtyp);
-
 if Nkind (Expression (N)) = N_Raise_Constraint_Error then
Rewrite (N, New_Copy (Expression (N)));
Set_Etype (N, PtrT);
diff --git a/gcc/testsuite/gnat.dg/predicate15.adb 
b/gcc/testsuite/gnat.dg/predicate15.adb
new file mode 100644
index 000..cf9e1d9e17f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate15.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+procedure Predicate15 is
+
+   type Grid is array (Positive range <>) of Integer with
+  Dynamic_Predicate => Grid'First = 1;
+
+   type Grid_Ptr is access Grid;
+
+   Data : Grid_Ptr := new Grid (1 .. 10);
+
+begin
+   null;
+end;


[gcc r14-9361] Fix bogus error on allocator for array type with Dynamic_Predicate

2024-03-07 Thread Eric Botcazou via Gcc-cvs
https://gcc.gnu.org/g:e71a4e81729516eed8782a255ff37617e6fd4b69

commit r14-9361-ge71a4e81729516eed8782a255ff37617e6fd4b69
Author: Eric Botcazou 
Date:   Thu Mar 7 15:05:54 2024 +0100

Fix bogus error on allocator for array type with Dynamic_Predicate

This is a regression present on all active branches: the compiler gives
a bogus error on an allocator for an unconstrained array type declared
with a Dynamic_Predicate because Apply_Predicate_Check is invoked directly
on a subtype reference, which it cannot handle.

This moves the check to the resulting access value (after dereference) like
in Expand_Allocator_Expression.

gcc/ada/
PR ada/113979
* exp_ch4.adb (Expand_N_Allocator): In the subtype indication case,
call Apply_Predicate_Check on the resulting access value if needed.

gcc/testsuite/
* gnat.dg/predicate15.adb: New test.

Diff:
---
 gcc/ada/exp_ch4.adb   |  6 --
 gcc/testsuite/gnat.dg/predicate15.adb | 15 +++
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 4f83cd4737a..e4a40414872 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -4657,8 +4657,6 @@ package body Exp_Ch4 is
  if Is_Array_Type (Dtyp) and then not No_Initialization (N) then
 Apply_Constraint_Check (Expression (N), Dtyp, No_Sliding => True);
 
-Apply_Predicate_Check (Expression (N), Dtyp);
-
 if Nkind (Expression (N)) = N_Raise_Constraint_Error then
Rewrite (N, New_Copy (Expression (N)));
Set_Etype (N, PtrT);
@@ -4752,6 +4750,8 @@ package body Exp_Ch4 is
 Rewrite (N, New_Occurrence_Of (Temp, Loc));
 Analyze_And_Resolve (N, PtrT);
 
+Apply_Predicate_Check (N, Dtyp, Deref => True);
+
  --  Case of no initialization procedure present
 
  elsif not Has_Non_Null_Base_Init_Proc (T) then
@@ -5119,6 +5119,8 @@ package body Exp_Ch4 is
Rewrite (N, New_Occurrence_Of (Temp, Loc));
Analyze_And_Resolve (N, PtrT);
 
+   Apply_Predicate_Check (N, Dtyp, Deref => True);
+
--  When designated type has Default_Initial_Condition aspects,
--  make a call to the type's DIC procedure to perform the
--  checks. Theoretically this might also be needed for cases
diff --git a/gcc/testsuite/gnat.dg/predicate15.adb 
b/gcc/testsuite/gnat.dg/predicate15.adb
new file mode 100644
index 000..cf9e1d9e17f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate15.adb
@@ -0,0 +1,15 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+procedure Predicate15 is
+
+   type Grid is array (Positive range <>) of Integer with
+  Dynamic_Predicate => Grid'First = 1;
+
+   type Grid_Ptr is access Grid;
+
+   Data : Grid_Ptr := new Grid (1 .. 10);
+
+begin
+   null;
+end;


[PATCH] Fix internal error in GIMPLE DSE

2024-02-27 Thread Eric Botcazou
Hi,

this is a regression present on the mainline, 13 and 12 branches.  For the 
attached Ada case, it's a tree checking failure on the mainline at -O:

+===GNAT BUG DETECTED==+
| 14.0.1 20240226 (experimental) [master r14-9171-g4972f97a265]  GCC error:|
| tree check: expected tree that contains 'decl common' structure, |
| have 'component_ref' in tree_could_trap_p, at tree-eh.cc:2733|
| Error detected around /home/eric/cvs/gcc/gcc/testsuite/gnat.dg/opt104.adb:

Time is a 10-byte record and Packed_Rec.T is placed at bit-offset 65 because 
of the packing. so tree-ssa-dse.cc:setup_live_bytes_from_ref has computed a 
const_size of 88 from ref->offset of 65 and ref->max_size of 80.

Then in tree-ssa-dse.cc:compute_trims:

411   int last_live = bitmap_last_set_bit (live);
(gdb) next
412   if (ref->size.is_constant (_size))
(gdb) 
414   int last_orig = (const_size / BITS_PER_UNIT) - 1;
(gdb) 
418   *trim_tail = last_orig - last_live;

(gdb) call debug_bitmap (live)
n_bits = 256, set = {0 1 2 3 4 5 6 7 8 9 10 }
(gdb) p last_live
$33 = 10
(gdb) p const_size
$34 = 80
(gdb) p last_orig
$35 = 9
(gdb) p *trim_tail
$36 = -1

In other words, compute_trims is overlooking the alignment adjustments applied 
earlier by setup_live_bytes_from_ref.  Moveover it reads:

  /* We use sbitmaps biased such that ref->offset is bit zero and the bitmap
 extends through ref->size.  So we know that in the original bitmap
 bits 0..ref->size were true.  We don't actually need the bitmap, just
 the REF to compute the trims.  */

But setup_live_bytes_from_ref used ref->max_size instead of ref->size.

It appears that all the callers of compute_trims assume that ref->offset is 
byte aligned and that the trimmed bytes are relative to ref->size, so the 
patch simply adds an early return if either condition is not fulfilled

Tested on x86-64/Linux, OK for all the affected branches?


2024-02-27  Eric Botcazou  

* tree-ssa-dse.cc (compute_trims): Fix description.  Return early
if ref->offset is not byte aligned or ref->size is not known to be
equal to ref->max_size.
(maybe_trim_complex_store): Fix description.
(maybe_trim_constructor_store): Likewise.
(maybe_trim_partially_dead_store): Likewise.


2024-02-27  Eric Botcazou  

* gnat.dg/opt104.ads, gnat.dg/opt104.adb! New test.

-- 
Eric Botcazoudiff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc
index 81b65125409..5869010287c 100644
--- a/gcc/tree-ssa-dse.cc
+++ b/gcc/tree-ssa-dse.cc
@@ -403,11 +403,11 @@ setup_live_bytes_from_ref (ao_ref *ref, sbitmap live_bytes)
   return false;
 }
 
-/* Compute the number of elements that we can trim from the head and
-   tail of ORIG resulting in a bitmap that is a superset of LIVE.
+/* Compute the number of stored bytes that we can trim from the head and
+   tail of REF.  LIVE is the bitmap of stores to REF that are still live.
 
-   Store the number of elements trimmed from the head and tail in
-   TRIM_HEAD and TRIM_TAIL.
+   Store the number of bytes trimmed from the head and tail in TRIM_HEAD
+   and TRIM_TAIL respectively.
 
STMT is the statement being trimmed and is used for debugging dump
output only.  */
@@ -416,10 +416,16 @@ static void
 compute_trims (ao_ref *ref, sbitmap live, int *trim_head, int *trim_tail,
 	   gimple *stmt)
 {
-  /* We use sbitmaps biased such that ref->offset is bit zero and the bitmap
- extends through ref->size.  So we know that in the original bitmap
- bits 0..ref->size were true.  We don't actually need the bitmap, just
- the REF to compute the trims.  */
+  *trim_head = 0;
+  *trim_tail = 0;
+
+  /* We use bitmaps biased such that ref->offset is contained in bit zero and
+ the bitmap extends through ref->max_size and we know that in the original
+ bitmap bits 0 .. ref->max_size were true.  But we need to check that this
+ covers exactly the bytes of REF.  */
+  const unsigned int align = known_alignment (ref->offset);
+  if ((align && align < BITS_PER_UNIT) || !known_eq (ref->size, ref->max_size))
+return;
 
   /* Now identify how much, if any of the tail we can chop off.  */
   HOST_WIDE_INT const_size;
@@ -444,8 +450,6 @@ compute_trims (ao_ref *ref, sbitmap live, int *trim_head, int *trim_tail,
 			   last_orig) <= 0)
 	*trim_tail = 0;
 }
-  else
-*trim_tail = 0;
 
   /* Identify how much, if any of the head we can chop off.  */
   int first_orig = 0;
@@ -503,8 +507,7 @@ compute_trims (ao_ref *ref, sbitmap live, int *trim_head, int *trim_tail,
 	}
 }
 
-  if ((*trim_head || *trim_tail)
-  && dump_file && (dump_flags & TDF_DETAILS))
+  if ((*trim_head || *trim_tail) && dump_file && (dump_flags & TDF_DETAILS))
 {
   fprintf (dump_file, "  Trimming statement (

[Ada] Fix PR ada/113893

2024-02-26 Thread Eric Botcazou
The finalization of objects dynamically allocated through an anonymous access 
type is deferred to the enclosing library unit in the current implementation 
and a warning is given on each of them.

However this cannot be done if the designated type is local, because this 
would generate dangling references to the local finalization routine, so
the finalization needs to be dropped in this case and the warning adjusted.

Tested on x86-64/Linux, applied on all active branches.


2024-02-26  Eric Botcazou  

PR ada/113893
* exp_ch7.adb (Build_Anonymous_Master): Do not build the master
for a local designated type.
* exp_util.adb (Build_Allocate_Deallocate_Proc): Force Needs_Fin
to false if no finalization master is attached to an access type
and assert that it is anonymous in this case.
* sem_res.adb (Resolve_Allocator): Mention that the object might
not be finalized at all in the warning given when the type is an
anonymous access-to-controlled type.


2024-02-26  Eric Botcazou  

* gnat.dg/access10.adb: New test.

-- 
Eric Botcazoudiff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 2ac73101351..e594a534244 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -749,6 +749,7 @@ package body Exp_Ch7 is
   Desig_Typ : Entity_Id;
   FM_Id : Entity_Id;
   Priv_View : Entity_Id;
+  Scop  : Entity_Id;
   Unit_Decl : Node_Id;
   Unit_Id   : Entity_Id;
 
@@ -787,6 +788,18 @@ package body Exp_Ch7 is
  Desig_Typ := Priv_View;
   end if;
 
+  --  For a designated type not declared at library level, we cannot create
+  --  a finalization collection attached to an outer unit since this would
+  --  generate dangling references to the dynamic scope through access-to-
+  --  procedure values designating the local Finalize_Address primitive.
+
+  Scop := Enclosing_Dynamic_Scope (Desig_Typ);
+  if Scop /= Standard_Standard
+and then Scope_Depth (Scop) > Scope_Depth (Unit_Id)
+  then
+ return;
+  end if;
+
   --  Determine whether the current semantic unit already has an anonymous
   --  master which services the designated type.
 
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 31cd47de7d2..04d114694ab 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -936,6 +936,16 @@ package body Exp_Util is
 Needs_Finalization (Desig_Typ)
   and then not No_Heap_Finalization (Ptr_Typ);
 
+  --  The allocation/deallocation of a controlled object must be associated
+  --  with an attachment to/detachment from a finalization master, but the
+  --  implementation cannot guarantee this property for every anonymous
+  --  access tyoe, see Build_Anonymous_Collection.
+
+  if Needs_Fin and then No (Finalization_Master (Ptr_Typ)) then
+ pragma Assert (Ekind (Ptr_Typ) = E_Anonymous_Access_Type);
+ Needs_Fin := False;
+  end if;
+
   if Needs_Fin then
 
  --  Do nothing if the access type may never allocate / deallocate
@@ -945,11 +955,6 @@ package body Exp_Util is
 return;
  end if;
 
- --  The allocation / deallocation of a controlled object must be
- --  chained on / detached from a finalization master.
-
- pragma Assert (Present (Finalization_Master (Ptr_Typ)));
-
   --  The only other kind of allocation / deallocation supported by this
   --  routine is on / from a subpool.
 
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 8e9714c1c86..075c0d85ccd 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -5679,19 +5679,19 @@ package body Sem_Res is
Set_Is_Dynamic_Coextension (N, False);
Set_Is_Static_Coextension  (N, False);
 
-   --  Anonymous access-to-controlled objects are not finalized on
-   --  time because this involves run-time ownership and currently
-   --  this property is not available. In rare cases the object may
-   --  not be finalized at all. Warn on potential issues involving
-   --  anonymous access-to-controlled objects.
+   --  Objects allocated through anonymous access types are not
+   --  finalized on time because this involves run-time ownership
+   --  and currently this property is not available. In rare cases
+   --  the object might not be finalized at all. Warn on potential
+   --  issues involving anonymous access-to-controlled types.
 
if Ekind (Typ) = E_Anonymous_Access_Type
  and then Is_Controlled_Active (Desig_T)
then
   Error_Msg_N
-("??object designated by anonymous access object might "
+("??object designated by anonymous access value might "
  & 

[c-family] Fix PR ada/113397

2024-01-16 Thread Eric Botcazou
It is a regression on the mainline for -fdump-ada-spec in a pathological case.

Tested on x86-64/Linux, applied on the mainline.


2024-01-16  Eric Botcazou  

PR ada/113397
* c-ada-spec.cc (check_type_name_conflict): Add guard for the
presence of DECL_NAME on a TYPE_DECL.
 
-- 
Eric Botcazoudiff --git a/gcc/c-family/c-ada-spec.cc b/gcc/c-family/c-ada-spec.cc
index 7d886c0f92e..4b245ed6975 100644
--- a/gcc/c-family/c-ada-spec.cc
+++ b/gcc/c-family/c-ada-spec.cc
@@ -1566,6 +1566,8 @@ check_type_name_conflict (pretty_printer *buffer, tree t)
 	s = "";
   else if (TREE_CODE (TYPE_NAME (tmp)) == IDENTIFIER_NODE)
 	s = IDENTIFIER_POINTER (TYPE_NAME (tmp));
+  else if (!DECL_NAME (TYPE_NAME (tmp)))
+	s = "";
   else
 	s = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp)));
 


Re: HELP: Questions on unshare_expr

2024-01-15 Thread Eric Botcazou
> Okay, so, the "unsharing everything” is done automatically by the compiler
> before gimplification? 

See the blurb at gimplify.cc:835 and below about this.

-- 
Eric Botcazou




Re: [PATCH] Fix debug info for enumeration types with reverse Scalar_Storage_Order

2024-01-10 Thread Eric Botcazou
> Can you elaborate on the DIE order constraint and why it was chosen?  That
> is,
> 
> +  /* The DIE with DW_AT_endianity is placed right after the naked DIE. 
> */ +  if (reverse)
> +   {
> + gcc_assert (type_die);
> ...
> 
> and
> 
> +  /* The DIE with DW_AT_endianity is placed right after the naked DIE. 
> */ +  if (reverse_type)
> +   {
> + dw_die_ref after_die
> +   = modified_type_die (type, cv_quals, false, context_die);
> + gen_type_die (type, context_die, true);
> + gcc_assert (after_die->die_sib
> + && get_AT_unsigned (after_die->die_sib,
> DW_AT_endianity)); + return after_die->die_sib;
> 
> ?

That's preexisting though, see line 13730 where there is a small blurb.

The crux of the matter is that there is no scalar *_TYPE node with a reverse 
SSO, so there is nothing to equate with for the DIE carrying DW_AT_endianity, 
unlike for type variants (the reverse SSO is on the enclosing aggregate type 
instead but this does not match the way DWARF describes it).

Therefore, in order to avoid building a new DIE with DW_AT_endianity each 
time, the DIE with DW_AT_endianity is placed right after the naked DIE, so 
that the lookup done at line 13730 for reverse SSO is immediate.

> Likewise the extra argument to the functions is odd - is that not available
> on the tree type?

No, for the reason described above, so the extra parameter is preexisting for 
base_type_die, modified_type_die and add_type_attribute.

-- 
Eric Botcazou




[PATCH] Fix debug info for enumeration types with reverse Scalar_Storage_Order

2024-01-09 Thread Eric Botcazou
Hi,

this is not really a regression but the patch was written last week and is 
quite straightforward, so hopefully can nevertheless be OK.  It implements the 
support of DW_AT_endianity for enumeration types because they are scalar and, 
therefore, reverse Scalar_Storage_Order is supported for them, but only when 
the -gstrict-dwarf switch is not passed because this is an extension.

There is an associated GDB patch to be submitted by Tom to grok the new DWARF.

Tested on x86-64/Linux, OK for the mainline?  It may also help the GDB side to 
backport it for the upcoming 13.3 release.


2024-01-09  Eric Botcazou  

* dwarf2out.cc (modified_type_die): Extend the support of reverse
storage order to enumeration types if -gstrict-dwarf is not passed.
(gen_enumeration_type_die): Add REVERSE parameter and generate the
DIE immediately after the existing one if it is true.
(gen_tagged_type_die): Add REVERSE parameter and pass it in the
call to gen_enumeration_type_die.
(gen_type_die_with_usage): Add REVERSE parameter and pass it in the
first recursive call as well as the call to gen_tagged_type_die.
(gen_type_die): Add REVERSE parameter and pass it in the call to
gen_type_die_with_usage.

-- 
Eric Botcazoudiff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc
index 2f9010bc3cb..1c994bb8b9b 100644
--- a/gcc/dwarf2out.cc
+++ b/gcc/dwarf2out.cc
@@ -3940,7 +3940,7 @@ static void gen_descr_array_type_die (tree, struct array_descr_info *, dw_die_re
 #if 0
 static void gen_entry_point_die (tree, dw_die_ref);
 #endif
-static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
+static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref, bool);
 static dw_die_ref gen_formal_parameter_die (tree, tree, bool, dw_die_ref);
 static dw_die_ref gen_formal_parameter_pack_die  (tree, tree, dw_die_ref, tree*);
 static void gen_unspecified_parameters_die (tree, dw_die_ref);
@@ -3960,7 +3960,7 @@ static void gen_struct_or_union_type_die (tree, dw_die_ref,
 		enum debug_info_usage);
 static void gen_subroutine_type_die (tree, dw_die_ref);
 static void gen_typedef_die (tree, dw_die_ref);
-static void gen_type_die (tree, dw_die_ref);
+static void gen_type_die (tree, dw_die_ref, bool = false);
 static void gen_block_die (tree, dw_die_ref);
 static void decls_for_scope (tree, dw_die_ref, bool = true);
 static bool is_naming_typedef_decl (const_tree);
@@ -3976,8 +3976,10 @@ static struct dwarf_file_data * lookup_filename (const char *);
 static void retry_incomplete_types (void);
 static void gen_type_die_for_member (tree, tree, dw_die_ref);
 static void gen_generic_params_dies (tree);
-static void gen_tagged_type_die (tree, dw_die_ref, enum debug_info_usage);
-static void gen_type_die_with_usage (tree, dw_die_ref, enum debug_info_usage);
+static void gen_tagged_type_die (tree, dw_die_ref, enum debug_info_usage,
+ bool = false);
+static void gen_type_die_with_usage (tree, dw_die_ref, enum debug_info_usage,
+ bool = false);
 static void splice_child_die (dw_die_ref, dw_die_ref);
 static int file_info_cmp (const void *, const void *);
 static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *, var_loc_view,
@@ -13665,8 +13667,11 @@ modified_type_die (tree type, int cv_quals, bool reverse,
   const int cv_qual_mask = (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE
 			| TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC | 
 			ENCODE_QUAL_ADDR_SPACE(~0U));
-  const bool reverse_base_type
-= need_endianity_attribute_p (reverse) && is_base_type (type);
+  /* DW_AT_endianity is specified only for base types in the standard.  */
+  const bool reverse_type
+= need_endianity_attribute_p (reverse)
+  && (is_base_type (type)
+	  || (TREE_CODE (type) == ENUMERAL_TYPE && !dwarf_strict));
 
   if (code == ERROR_MARK)
 return NULL;
@@ -13726,9 +13731,9 @@ modified_type_die (tree type, int cv_quals, bool reverse,
 
   /* DW_AT_endianity doesn't come from a qualifier on the type, so it is
 	 dealt with specially: the DIE with the attribute, if it exists, is
-	 placed immediately after the regular DIE for the same base type.  */
+	 placed immediately after the regular DIE for the same type.  */
   if (mod_type_die
-	  && (!reverse_base_type
+	  && (!reverse_type
 	  || ((mod_type_die = mod_type_die->die_sib) != NULL
 		  && get_AT_unsigned (mod_type_die, DW_AT_endianity
 	return mod_type_die;
@@ -13745,7 +13750,7 @@ modified_type_die (tree type, int cv_quals, bool reverse,
   tree dtype = TREE_TYPE (name);
 
   /* Skip the typedef for base types with DW_AT_endianity, no big deal.  */
-  if (qualified_type == dtype && !reverse_base_type)
+  if (qualified_type == dtype && !reverse_type)
 	{
 	  tree origin = decl_ultimate_origin (name);
 
@@ -13952,7 +13957,7 @@ modified_type_die (tree type, int cv_quals, bool reverse,
 	mod_type_die = base_type_die (type,

[Ada] Fix PR ada/112781 (2/2)

2024-01-09 Thread Eric Botcazou
The problem occurs when this function call is the expression of a return in a 
function returning the limited interface; in this peculiar case, there is a 
mismatch between the callee, which has BIP formals but is not a BIP call, and 
the caller, which is a BIP function, that is spotted by an assertion.

This is fixed by restoring the semantics of Is_Build_In_Place_Function_Call, 
which returns again true only for calls to BIP functions, introducing the 
Is_Function_Call_With_BIP_Formals predicate, which also returns true for calls 
to functions with BIP formals that are not BIP functions, and moving down the 
assertion in Expand_Simple_Function_Return.

Tested on SPARC64/Linux, applied on the mainline and 13 branch.

2024-01-09  Eric Botcazou  

PR ada/112781
* exp_ch6.ads (Is_Build_In_Place_Function): Adjust description.
* exp_ch6.adb (Is_True_Build_In_Place_Function_Call): Delete.
(Is_Function_Call_With_BIP_Formals): New predicate.
(Is_Build_In_Place_Function_Call): Restore original semantics.
(Expand_Call_Helper): Adjust conditions guarding the calls to
Add_Dummy_Build_In_Place_Actuals to above renaming.
(Expand_N_Extended_Return_Statement): Adjust to above renaming.
(Expand_Simple_Function_Return): Likewise.  Move the assertion
to after the transformation into an extended return statement.
(Make_Build_In_Place_Call_In_Allocator): Remove unreachable code.
(Make_Build_In_Place_Call_In_Assignment): Likewise.


2024-01-09  Eric Botcazou  

* gnat.dg/bip_prim_func2.adb: New test.
* gnat.dg/bip_prim_func2_pkg.ads, gnat.dg/bip_prim_func2_pkg.adb:
New helper package.

-- 
Eric Botcazoudiff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 8e4c9035b22..939d3be57c3 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -316,11 +316,10 @@ package body Exp_Ch6 is
--  Insert the Post_Call list previously produced by routine Expand_Actuals
--  or Expand_Call_Helper into the tree.
 
-   function Is_True_Build_In_Place_Function_Call (N : Node_Id) return Boolean;
+   function Is_Function_Call_With_BIP_Formals (N : Node_Id) return Boolean;
--  Ada 2005 (AI-318-02): Returns True if N denotes a call to a function
-   --  that requires handling as a build-in-place call; returns False for
-   --  non-BIP function calls and also for calls to functions with inherited
-   --  BIP formals that do not require BIP formals. For example:
+   --  that requires handling as a build-in-place call, that is, BIP function
+   --  calls and calls to functions with inherited BIP formals. For example:
--
--type Iface is limited interface;
--function Get_Object return Iface;
@@ -330,15 +329,14 @@ package body Exp_Ch6 is
--type T1 is new Root1 and Iface with ...
--function Get_Object return T1;
----  This primitive requires the BIP formals, and the evaluation of
-   ----  Is_True_Build_In_Place_Function_Call returns True.
+   ----  Is_Build_In_Place_Function_Call returns True.
--
--type Root2 is tagged record ...
--type T2 is new Root2 and Iface with ...
--function Get_Object return T2;
----  This primitive inherits the BIP formals of the interface primitive
----  but, given that T2 is not a limited type, it does not require such
-   ----  formals; therefore Is_True_Build_In_Place_Function_Call returns
-   ----  False.
+   ----  formals; therefore Is_Build_In_Place_Function_Call returns False.
 
procedure Replace_Renaming_Declaration_Id
   (New_Decl  : Node_Id;
@@ -4906,8 +4904,8 @@ package body Exp_Ch6 is
 --  inherited the BIP extra actuals but does not require them.
 
 if Nkind (Call_Node) = N_Function_Call
-  and then Is_Build_In_Place_Function_Call (Call_Node)
-  and then not Is_True_Build_In_Place_Function_Call (Call_Node)
+  and then Is_Function_Call_With_BIP_Formals (Call_Node)
+  and then not Is_Build_In_Place_Function_Call (Call_Node)
 then
Add_Dummy_Build_In_Place_Actuals (Subp,
  Num_Added_Extra_Actuals => Num_Extra_Actuals);
@@ -4918,8 +4916,8 @@ package body Exp_Ch6 is
   --  inherited the BIP extra actuals but does not require them.
 
   elsif Nkind (Call_Node) = N_Function_Call
-and then Is_Build_In_Place_Function_Call (Call_Node)
-and then not Is_True_Build_In_Place_Function_Call (Call_Node)
+and then Is_Function_Call_With_BIP_Formals (Call_Node)
+and then not Is_Build_In_Place_Function_Call (Call_Node)
   then
  Add_Dummy_Build_In_Place_Actuals (Subp);
   end if;
@@ -5614,7 +5612,7 @@ package body Exp_Ch6 is
 pragma Assert (Ekind (Current_Subprogram) = E_Function);
 pragma Assert
   (Is_Build_In_Place_Function (Current_Subprog

[Ada] Fix PR ada/112781 (1/2)

2024-01-09 Thread Eric Botcazou
This is a regression present on the mainline and 13 branch, in the form of a 
series of internal errors (3) on a function call returning the extension of a
limited interface.

This is only a partial fix for the first two assertion failures triggered by 
this case; the third one is the most problematic and will be dealt with 
separately.

The first issue is in Instantiate_Type, where we use Base_Type in a specific 
case to compute the ancestor of a derived type, which will later trigger the 
assertion on line 16960 of sem_ch3.adb since Parent_Base and Generic_Actual 
are the same node.  This is changed to use Etype like in other cases around.

The second issue is an unprotected use of Designated_Type on type T in 
Analyze_Explicit_Dereference, while another use in an equivalent context
is guarded by Is_Access_Type a few lines above.

Tested on SPARC64/Linux, applied on the mainline and 13 branch.

2024-01-09  Eric Botcazou  

PR ada/112781
* sem_ch12.adb (Instantiate_Type): Use Etype instead of Base_Type
consistently to retrieve the ancestor for a derived type.
* sem_ch4.adb (Analyze_Explicit_Dereference): Test Is_Access_Type
consistently before accessing Designated_Type.

-- 
Eric Botcazoudiff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index bfb400f5642..d2285082f97 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -13522,8 +13522,7 @@ package body Sem_Ch12 is
Ancestor := Get_Instance_Of (Ancestor);
 
 else
-   Ancestor :=
- Get_Instance_Of (Base_Type (Get_Instance_Of (A_Gen_T)));
+   Ancestor := Get_Instance_Of (Etype (Get_Instance_Of (A_Gen_T)));
 end if;
 
  --  Check whether parent is a previous formal of the current generic
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index 64aa9a84e60..85ae282dc37 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -2304,7 +2304,9 @@ package body Sem_Ch4 is
 while Present (It.Nam) loop
T := It.Typ;
 
-   if No (First_Formal (Base_Type (Designated_Type (T then
+   if Is_Access_Type (T)
+ and then No (First_Formal (Base_Type (Designated_Type (T
+   then
   Set_Etype (P, T);
else
   Remove_Interp (I);


[Ada] Fix PR ada/113195

2024-01-09 Thread Eric Botcazou
This is a small regression present on the mainline and 13 branch, in the form 
of an internal error in gigi on anonymous access type equality.  We now need 
to also accept them too for anonymous access types that point to compatible 
object subtypes in the language sense.

Tested on SPARC64/Linux, applied on the mainline and 13 branch.


2024-01-09  Eric Botcazou  

PR ada/113195
* gcc-interface/utils2.cc (build_binary_op) : Relax
assertion for regular pointer types.


2024-01-09  Eric Botcazou  

* gnat.dg/specs/anon4.ads: New test.

-- 
Eric Botcazou-- { dg-do compile }

package Anon4 is
   subtype I is Integer;
   A : access I;

   Acc : access Integer;

   function F return Boolean is (A = Acc);
end Anon4;
diff --git a/gcc/ada/gcc-interface/utils2.cc b/gcc/ada/gcc-interface/utils2.cc
index 6a951093ff8..df11eef2101 100644
--- a/gcc/ada/gcc-interface/utils2.cc
+++ b/gcc/ada/gcc-interface/utils2.cc
@@ -1142,14 +1142,10 @@ build_binary_op (enum tree_code op_code, tree result_type,
 	  tree left_ref_type = TREE_TYPE (left_base_type);
 	  tree right_ref_type = TREE_TYPE (right_base_type);
 
-	  /* Anonymous access types in Ada 2005 can point to different
-		 members of a tagged hierarchy or different function types.  */
-	  gcc_assert (TYPE_MAIN_VARIANT (left_ref_type)
-			  == TYPE_MAIN_VARIANT (right_ref_type)
-			  || (TYPE_ALIGN_OK (left_ref_type)
-			  && TYPE_ALIGN_OK (right_ref_type))
-			  || (TREE_CODE (left_ref_type) == FUNCTION_TYPE
-			  && TREE_CODE (right_ref_type) == FUNCTION_TYPE));
+	  /* Anonymous access types in Ada 2005 may point to compatible
+		 object subtypes or function types in the language sense.  */
+	  gcc_assert (FUNCTION_POINTER_TYPE_P (left_ref_type)
+			  == FUNCTION_POINTER_TYPE_P (right_ref_type));
 	  best_type = left_base_type;
 	}
 


Fix PR rtl-optimization/113140

2024-01-09 Thread Eric Botcazou
This is a small regression present on the mainline and 13 branch, although the 
underlying problem has probably been there for ages, in the form of a segfault 
during the delay slot scheduling pass, for a function that falls through to 
exit without any RTL instruction generated for the end of function.

Tested on SPARC64/Linux, applied on the mainline and 13 branch.


2024-01-09  Eric Botcazou  

PR rtl-optimization/113140
* reorg.cc (fill_slots_from_thread): If we are to branch after the
last instruction of the function, create an end label.


2024-01-09  Eric Botcazou  

* g++.dg/opt/delay-slot-2.C: New test.

-- 
Eric Botcazoudiff --git a/gcc/reorg.cc b/gcc/reorg.cc
index e85af7134f4..99228a22c69 100644
--- a/gcc/reorg.cc
+++ b/gcc/reorg.cc
@@ -2641,7 +2641,8 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition,
  arithmetic insn after the jump insn and put the arithmetic insn in the
  delay slot.  If we can't do this, return.  */
   if (delay_list->is_empty () && likely
-  && new_thread && !ANY_RETURN_P (new_thread)
+  && new_thread
+  && !ANY_RETURN_P (new_thread)
   && NONJUMP_INSN_P (new_thread)
   && !RTX_FRAME_RELATED_P (new_thread)
   && GET_CODE (PATTERN (new_thread)) != ASM_INPUT
@@ -2729,14 +2730,16 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition,
 
   gcc_assert (thread_if_true);
 
-  if (new_thread && simplejump_or_return_p (new_thread)
+  if (new_thread
+	  && simplejump_or_return_p (new_thread)
 	  && redirect_with_delay_list_safe_p (insn,
 	  JUMP_LABEL (new_thread),
 	  *delay_list))
-	new_thread = follow_jumps (JUMP_LABEL (new_thread), insn,
-   );
+	new_thread = follow_jumps (JUMP_LABEL (new_thread), insn, );
 
-  if (ANY_RETURN_P (new_thread))
+  if (!new_thread)
+	label = find_end_label (simple_return_rtx);
+  else if (ANY_RETURN_P (new_thread))
 	label = find_end_label (new_thread);
   else if (LABEL_P (new_thread))
 	label = new_thread;
// PR rtl-optimization/113140
// Reduced testcase by Rainer Orth 

// { dg-options "-O -w" }

int *m();
struct StaticValue {
  long _val;
  void setM(int *) { _val = 0; }
};
struct Value : StaticValue {
  template  T *as();
};
Value *alloc();
struct Scoped {
  Scoped() {
Value v;
ptr = alloc();
Value *__trans_tmp_1 = v.as();
ptr->setM(__trans_tmp_1 ? m() : 0);
  }
  Value *ptr;
};
struct QObjectMethod {
  unsigned long long callInternal() const;
};
unsigned long long QObjectMethod::callInternal() const {
  [] {
if (Scoped(); 0)
  ;
  }();
}


Fix PR rtl-optimization/113140

2024-01-09 Thread Eric Botcazou
This is a small regression present on the mainline and 13 branch, although the 
underlying problem has probably been there for ages, in the form of a segfault 
during the delay slot scheduling pass, for a function that falls through to 
exit without any RTL instruction generated for the end of function.

Tested on SPARC64/Linux, applied on the mainline and 13 branch.


2024-01-09  Eric Botcazou  

PR rtl-optimization/113140
* reorg.cc (fill_slots_from_thread): If we are to branch after the
last instruction of the function, create an end label.


2024-01-09  Eric Botcazou  

* g++.dg/opt/delay-slot-2.C: New test.

-- 
Eric Botcazoudiff --git a/gcc/reorg.cc b/gcc/reorg.cc
index e85af7134f4..99228a22c69 100644
--- a/gcc/reorg.cc
+++ b/gcc/reorg.cc
@@ -2641,7 +2641,8 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition,
  arithmetic insn after the jump insn and put the arithmetic insn in the
  delay slot.  If we can't do this, return.  */
   if (delay_list->is_empty () && likely
-  && new_thread && !ANY_RETURN_P (new_thread)
+  && new_thread
+  && !ANY_RETURN_P (new_thread)
   && NONJUMP_INSN_P (new_thread)
   && !RTX_FRAME_RELATED_P (new_thread)
   && GET_CODE (PATTERN (new_thread)) != ASM_INPUT
@@ -2729,14 +2730,16 @@ fill_slots_from_thread (rtx_jump_insn *insn, rtx condition,
 
   gcc_assert (thread_if_true);
 
-  if (new_thread && simplejump_or_return_p (new_thread)
+  if (new_thread
+	  && simplejump_or_return_p (new_thread)
 	  && redirect_with_delay_list_safe_p (insn,
 	  JUMP_LABEL (new_thread),
 	  *delay_list))
-	new_thread = follow_jumps (JUMP_LABEL (new_thread), insn,
-   );
+	new_thread = follow_jumps (JUMP_LABEL (new_thread), insn, );
 
-  if (ANY_RETURN_P (new_thread))
+  if (!new_thread)
+	label = find_end_label (simple_return_rtx);
+  else if (ANY_RETURN_P (new_thread))
 	label = find_end_label (new_thread);
   else if (LABEL_P (new_thread))
 	label = new_thread;
// PR rtl-optimization/113140
// Reduced testcase by Rainer Orth 

// { dg-options "-O -w" }

int *m();
struct StaticValue {
  long _val;
  void setM(int *) { _val = 0; }
};
struct Value : StaticValue {
  template  T *as();
};
Value *alloc();
struct Scoped {
  Scoped() {
Value v;
ptr = alloc();
Value *__trans_tmp_1 = v.as();
ptr->setM(__trans_tmp_1 ? m() : 0);
  }
  Value *ptr;
};
struct QObjectMethod {
  unsigned long long callInternal() const;
};
unsigned long long QObjectMethod::callInternal() const {
  [] {
if (Scoped(); 0)
  ;
  }();
}


Re: [PATCH] testsuite: Skip ifcvt-4.c for SPARC V8

2024-01-09 Thread Eric Botcazou
> Conditional moves are not available in SPARC V8.
> 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/ifcvt-4.c: Skip for SPARC V8

OK.

-- 
Eric Botcazou




Re: [PATCH] sparc: Char arrays are 64-bit aligned on SPARC

2024-01-09 Thread Eric Botcazou
> Hello Eric! Thank you for reviewing the patches!

You're welcome.

> No, this warning is not from GCC, it is from binutils ld. I forgot to
> mention that in the message. I get a similar warning from older versions
> of ld, so I do not think it is a new warning. It is also there with GCC 10.

I see, thanks for the explanation, the patch is OK then.

> For the OK:ed patches (with your changes), can I push them to
> release/gcc-13 in addition to master?

Sure.

-- 
Eric Botcazou




Re: [PATCH 2/2] sparc: Add errata workaround to membar patterns

2024-01-08 Thread Eric Botcazou
> LEON now uses the standard V8 membar patterns that contains an ldstub
> instruction. This instruction needs to be aligned properly when the
> GR712RC errata workaround is enabled.
> 
> gcc/ChangeLog:
> 
>   * config/sparc/sparc.cc (atomic_insn_for_leon3_p): Treat 
membar_storeload as atomic
>   * config/sparc/sync.md: Add GR712RC errata workaround

The second ChangeLog entry should be more detailed:

* config/sparc/sync.md (membar_storeload): Turn into named insn
and add GR712RC errata workaround.
(membar_v8): Add GR712RC errata workaround.

OK with this change.

-- 
Eric Botcazou




Re: [PATCH] sparc: Treat instructions with length 0 as empty

2024-01-08 Thread Eric Botcazou
> This is to handle the membar_empty instruction that can be generated
> when compiling for UT699.
> 
> gcc/ChangeLog:
> 
>   * config/sparc/sparc.cc (next_active_non_empty_insn): Length 0 treated 
> as empty

OK without the superfluous parentheses.


-- 
Eric Botcazou




Re: [PATCH 1/2] sparc: Revert membar optimization that is not suitable for LEON5

2024-01-08 Thread Eric Botcazou
> LEON5 has a deeper write-buffer and hence stb is not enough to flush a
> write out. For compatibility, use the default V8 approach for both
> LEON3 and LEON5.
> 
> This reverts commit 49cc765db35a5a21cab2aece27a44983fa70b94b,
> "sync.md (*membar_storeload_leon3): New insn."
> 
> gcc/ChangeLog:
> 
>   * config/sparc/sync.md (*membar_storeload_leon3): Remove
>   (*membar_storeload): Enable for LEON

OK.

-- 
Eric Botcazou




Re: [PATCH] sparc: Char arrays are 64-bit aligned on SPARC

2024-01-08 Thread Eric Botcazou
> pr88077 fails on SPARC since char HeaderStr[1] in pr88077_1.c and
> long HeaderStr in pr88077_0.c differs in alignment.
> 
> warning: alignment 4 of normal symbol `HeaderStr' in c_lto_pr88077_0.o is
> smaller than 8 used by the common definition in c_lto_pr88077_1.o

I have never seen it though.  Is that really a warning issued by GCC?

-- 
Eric Botcazou




Re: [PATCH] combine: Don't optimize paradoxical SUBREG AND CONST_INT on WORD_REGISTER_OPERATIONS targets [PR112758]

2023-12-22 Thread Eric Botcazou
> Bootstrapped/regtested on x86_64-linux and i686-linux (neither of which
> is WORD_REGISTER_OPERATIONS target), tested on the testcase using
> cross to riscv64-linux but don't have an easy access to a
> WORD_REGISTER_OPERATIONS target to bootstrap/regtest it there.
> 
> Ok for trunk?

Yes, thanks for fixing this.

-- 
Eric Botcazou




Re: [gcc15] nested functions in C

2023-12-07 Thread Eric Botcazou
> I think from a language standpoint, the general idea that nested
> functions are just any functions inside functions (which is how the C
> nested functions essentially behave) is too broad and they should be
> restricted to minimal implementations that, e.g. don't have side-effects
> or if they do, there's explicit syntactic sugar to make it clearer.

That sounds totally arbitrary though.  Algol-derived languages have had nested 
subprograms for ages, e.g. Pascal or Ada, and they can be very useful.

-- 
Eric Botcazou




Re: [PATCH] gcc: Disallow trampolines when -fhardened

2023-12-07 Thread Eric Botcazou
> I don't know either of these languages to write a test, and I don't see
> anything that mentions the word trampoline in gfortran.dg/.  Ada has
> gnat.dg/trampoline3.adb but:
> 
> $ gcc -c -Wtrampolines trampoline3.adb
> trampoline3.adb:6:03: warning: variable "A" is read but never assigned
> [-gnatwv]
> 
> so there is no warning.

Look at the last line of the test (Ada has not used trampolines for ages!).

-- 
Eric Botcazou




Re: [PATCH] pro_and_epilogue: Call df_note_add_problem () if SHRINK_WRAPPING_ENABLED [PR112760]

2023-12-02 Thread Eric Botcazou
> So sorry to be awkward, but I don't think this is the way to go.  I think
> we'll just end up playing whack-a-mole and adding df_note_add_problem to
> lots of passes.

We have doing that for the past 15 years though, so what has changed?

> (FTR, I'm not saying passes have to avoid false negatives, just false
> positives.  If a pass updates an instruction with a REG_UNUSED note,
> and the pass is no longer sure whether the register is unused or not,
> the pass can just delete the note.)

Reintroducing the manual management of such notes would be a step backward.

-- 
Eric Botcazou




[Ada] Fix internal error on function returning dynamically-sized type

2023-11-16 Thread Eric Botcazou
This is PR ada/109881, a tree sharing issue for the internal return type 
synthesized for a function returning a dynamically-sized type and taking an 
Out or In/Out parameter passed by copy.

Tested on x86-64/Linux, applied on mainline, 13 and 12 branches.


2023-11-16  Eric Botcazou  

PR ada/109881
* gcc-interface/decl.cc (gnat_to_gnu_subprog_type): Also create a
TYPE_DECL for the return type built for the CI/CO mechanism.


2023-11-16  Eric Botcazou  

* gnat.dg/varsize4.ads, gnat.dg/varsize4.adb: New test.
* gnat.dg/varsize4_pkg.ads: New helper.

-- 
Eric Botcazoudiff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index 95fa508c559..9c7f6840e21 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -6329,6 +6329,12 @@ gnat_to_gnu_subprog_type (Entity_Id gnat_subprog, bool definition,
 
 	  if (debug_info_p)
 	rest_of_record_type_compilation (gnu_cico_return_type);
+
+	  /* Declare it now since it will never be declared otherwise.  This
+	 is necessary to ensure that its subtrees are properly marked.  */
+	  create_type_decl (TYPE_NAME (gnu_cico_return_type),
+			gnu_cico_return_type,
+			true, debug_info_p, gnat_subprog);
 	}
 
   gnu_return_type = gnu_cico_return_type;
-- { dg-do compile }

package body Varsize4 is

   function Func (bytes_read : out Natural) return Arr is
  Ret : Arr := (others => False);
   begin
  return Ret;
   end;

   function Get return Natural is
  Data  : Arr;
  Bytes : Natural;
   begin
  Data := Func (Bytes);
  return Bytes;
   end;

end Varsize4;
with Varsize4_Pkg;

package Varsize4 is

   type Arr is array (1 .. Varsize4_Pkg.F) of Boolean;

   function Get return Natural;

end Varsize4;
package Varsize4_Pkg is

   function F return Natural;

end Varsize4_Pkg;


[PATCH] Handle addresses of more constants in IPA-CP

2023-11-11 Thread Eric Botcazou
Hi,

IPA-CP can currently handle addresses of scalar constants (CONST_DECL) so this 
extends that to addresses of constants in the pool (DECL_IN_CONSTANT_POOL).
Again this is helpful for so-called fat pointers in Ada, i.e. objects that are 
semantically pointers but represented by structures made up of two pointers. 

This also moves the unused function print_ipcp_constant_value from ipa-cp.cc 
to ipa-prop.cc and renames it.

I have an LTO testcase for which this makes a difference, but it's large so 
not really suitable for the testsuite.

Bootstrapped/regtested on x86-64/Linux, OK for the mainline?


2023-11-11  Eric Botcazou  

* ipa-cp.cc (print_ipcp_constant_value): Move to...
(values_equal_for_ipcp_p): Deal with VAR_DECLs from the
constant pool.
* ipa-prop.cc (ipa_print_constant_value): ...here.  Likewise.
(ipa_print_node_jump_functions_for_edge): Call the function
ipa_print_constant_value to print IPA_JF_CONST elements.

-- 
Eric Botcazoudiff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 788157ebd55..34fae065454 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -478,31 +478,21 @@ values_equal_for_ipcp_p (tree x, tree y)
 
   if (TREE_CODE (x) == ADDR_EXPR
   && TREE_CODE (y) == ADDR_EXPR
-  && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
-  && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
-return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
-			DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
+  && (TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
+	  || (TREE_CODE (TREE_OPERAND (x, 0)) == VAR_DECL
+	  && DECL_IN_CONSTANT_POOL (TREE_OPERAND (x, 0
+  && (TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL
+	  || (TREE_CODE (TREE_OPERAND (y, 0)) == VAR_DECL
+	  && DECL_IN_CONSTANT_POOL (TREE_OPERAND (y, 0)
+return TREE_OPERAND (x, 0) == TREE_OPERAND (y, 0)
+	   || operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
+			   DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
   else
 return operand_equal_p (x, y, 0);
 }
 
 /* Print V which is extracted from a value in a lattice to F.  */
 
-static void
-print_ipcp_constant_value (FILE * f, tree v)
-{
-  if (TREE_CODE (v) == ADDR_EXPR
-  && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL)
-{
-  fprintf (f, "& ");
-  print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (v, 0)));
-}
-  else
-print_generic_expr (f, v);
-}
-
-/* Print V which is extracted from a value in a lattice to F.  */
-
 static void
 print_ipcp_constant_value (FILE * f, ipa_polymorphic_call_context v)
 {
diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index 827bdb691ba..7de2b788185 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -365,6 +365,24 @@ ipa_initialize_node_params (struct cgraph_node *node)
 ipa_populate_param_decls (node, *info->descriptors);
 }
 
+/* Print VAL which is extracted from a jump function to F.  */
+
+static void
+ipa_print_constant_value (FILE *f, tree val)
+{
+  print_generic_expr (f, val);
+
+  /* This is in keeping with values_equal_for_ipcp_p.  */
+  if (TREE_CODE (val) == ADDR_EXPR
+  && (TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL
+	  || (TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL
+	  && DECL_IN_CONSTANT_POOL (TREE_OPERAND (val, 0)
+{
+  fputs (" -> ", f);
+  print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)));
+}
+}
+
 /* Print the jump functions associated with call graph edge CS to file F.  */
 
 static void
@@ -386,15 +404,8 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
 	fprintf (f, "UNKNOWN\n");
   else if (type == IPA_JF_CONST)
 	{
-	  tree val = jump_func->value.constant.value;
 	  fprintf (f, "CONST: ");
-	  print_generic_expr (f, val);
-	  if (TREE_CODE (val) == ADDR_EXPR
-	  && TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL)
-	{
-	  fprintf (f, " -> ");
-	  print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)));
-	}
+	  ipa_print_constant_value (f, jump_func->value.constant.value);
 	  fprintf (f, "\n");
 	}
   else if (type == IPA_JF_PASS_THROUGH)
@@ -468,7 +479,7 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
 	  else if (item->jftype == IPA_JF_CONST)
 		{
 		  fprintf (f, "CONST: ");
-		  print_generic_expr (f, item->value.constant);
+		  ipa_print_constant_value (f, item->value.constant);
 		}
 	  else if (item->jftype == IPA_JF_UNKNOWN)
 		fprintf (f, "UNKNOWN: " HOST_WIDE_INT_PRINT_DEC " bits",


[PATCH] Handle constant CONSTRUCTORs in operand_compare

2023-11-10 Thread Eric Botcazou
Hi,

this teaches operand_compare to compare constant CONSTRUCTORs, which is quite
helpful for so-called fat pointers in Ada, i.e. objects that are semantically
pointers but are represented by structures made up of two pointers.  This is
modeled on the implementation present in the ICF pass.

Bootstrapped/regtested on x86-64/Linux, OK for the mainline?


2023-11-10  Eric Botcazou  

* fold-const.cc (operand_compare::operand_equal_p) :
Deal with nonempty constant CONSTRUCTORs.
(operand_compare::hash_operand) : Hash DECL_FIELD_OFFSET
and DECL_FIELD_BIT_OFFSET for FIELD_DECLs.


2023-11-10  Eric Botcazou  

* gnat.dg/opt103.ads, gnat.dg/opt103.adb: New test.

-- 
Eric Botcazoudiff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 40767736389..332bc8aead2 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -3315,9 +3315,65 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1,
 flags | OEP_ADDRESS_OF
 | OEP_MATCH_SIDE_EFFECTS);
   case CONSTRUCTOR:
-	/* In GIMPLE empty constructors are allowed in initializers of
-	   aggregates.  */
-	return !CONSTRUCTOR_NELTS (arg0) && !CONSTRUCTOR_NELTS (arg1);
+	{
+	  /* In GIMPLE empty constructors are allowed in initializers of
+	 aggregates.  */
+	  if (!CONSTRUCTOR_NELTS (arg0) && !CONSTRUCTOR_NELTS (arg1))
+	return true;
+
+	  /* See sem_variable::equals in ipa-icf for a similar approach.  */
+	  tree typ0 = TREE_TYPE (arg0);
+	  tree typ1 = TREE_TYPE (arg1);
+
+	  if (TREE_CODE (typ0) != TREE_CODE (typ1))
+	return false;
+	  else if (TREE_CODE (typ0) == ARRAY_TYPE)
+	{
+	  /* For arrays, check that the sizes all match.  */
+	  const HOST_WIDE_INT siz0 = int_size_in_bytes (typ0);
+	  if (TYPE_MODE (typ0) != TYPE_MODE (typ1)
+		  || siz0 < 0
+		  || siz0 != int_size_in_bytes (typ1))
+		return false;
+	}
+	  else if (!types_compatible_p (typ0, typ1))
+	return false;
+
+	  vec *v0 = CONSTRUCTOR_ELTS (arg0);
+	  vec *v1 = CONSTRUCTOR_ELTS (arg1);
+	  if (vec_safe_length (v0) != vec_safe_length (v1))
+	return false;
+
+	  /* Address of CONSTRUCTOR is defined in GENERIC to mean the value
+	 of the CONSTRUCTOR referenced indirectly.  */
+	  flags &= ~OEP_ADDRESS_OF;
+
+	  for (unsigned idx = 0; idx < vec_safe_length (v0); ++idx)
+	{
+	  constructor_elt *c0 = &(*v0)[idx];
+	  constructor_elt *c1 = &(*v1)[idx];
+
+	  /* Check that the values are the same...  */
+	  if (c0->value != c1->value
+		  && !operand_equal_p (c0->value, c1->value, flags))
+		return false;
+
+	  /* ... and that they apply to the same field!  */
+	  if (c0->index != c1->index
+		  && (TREE_CODE (typ0) == ARRAY_TYPE
+		  ? !operand_equal_p (c0->index, c1->index, flags)
+		  : !operand_equal_p (DECL_FIELD_OFFSET (c0->index),
+	  DECL_FIELD_OFFSET (c1->index),
+	  flags)
+			|| !operand_equal_p (DECL_FIELD_BIT_OFFSET (c0->index),
+	 DECL_FIELD_BIT_OFFSET (c1->index),
+	 flags)))
+		return false;
+	}
+
+	  return true;
+	}
+
   default:
 	break;
   }
@@ -3703,9 +3759,7 @@ operand_compare::operand_equal_p (const_tree arg0, const_tree arg1,
 	 elements.  Individual elements in the constructor must be
 	 indexed in increasing order and form an initial sequence.
 
-	 We make no effort to compare constructors in generic.
-	 (see sem_variable::equals in ipa-icf which can do so for
-	  constants).  */
+	 We make no effort to compare nonconstant ones in GENERIC.  */
 	  if (!VECTOR_TYPE_P (TREE_TYPE (arg0))
 	  || !VECTOR_TYPE_P (TREE_TYPE (arg1)))
 	return false;
@@ -3887,7 +3941,13 @@ operand_compare::hash_operand (const_tree t, inchash::hash ,
 	/* In GIMPLE the indexes can be either NULL or matching i.  */
 	if (field == NULL_TREE)
 	  field = bitsize_int (idx);
-	hash_operand (field, hstate, flags);
+	if (TREE_CODE (field) == FIELD_DECL)
+	  {
+		hash_operand (DECL_FIELD_OFFSET (field), hstate, flags);
+		hash_operand (DECL_FIELD_BIT_OFFSET (field), hstate, flags);
+	  }
+	else
+	  hash_operand (field, hstate, flags);
 	hash_operand (value, hstate, flags);
 	  }
 	return;
-- { dg-do compile }
-- { dg-options "-O -gnatn -fdump-tree-optimized" }

package body Opt103 is

  function Read return Mode is
S : String := Get;
M : Mode;

  begin
--  There should be a single call to Value_Enumeration_Pos after inlining

if Mode'Valid_Value (S) then
  M := Mode'Value (S);
else
  raise Program_Error;
end if;

return M;
  end;

  function Translate (S : String) return Mode is
M : Mode;

  begin
--  There should be a single call to Value_Enumeration_Pos after inlining

if Mode'Valid_Value (S) then
  M := Mode'Value (S);
else
  raise Program_Error;
end if;

return M;
  end;

end Opt103;

-- { dg-final {

[PATCH] Add missing return in gori_compute::logical_combine

2023-09-25 Thread Eric Botcazou
Hi,

the varying case currently falls through to the 1/true case.

Tested on x86_64-suse-linux, OK for mainline, 13 and 12 branches?


2023-09-25  Eric Botcazou  

* gimple-range-gori.cc (gori_compute::logical_combine): Add missing
return statement in the varying case.


2023-09-25  Eric Botcazou  

* gnat.dg/opt102.adb:New test.
* gnat.dg/opt102_pkg.adb, gnat.dg/opt102_pkg.ads: New helper.

-- 
Eric Botcazoudiff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 51fb542a19c..2694e551d73 100644
--- a/gcc/gimple-range-gori.cc
+++ b/gcc/gimple-range-gori.cc
@@ -876,6 +876,7 @@ gori_compute::logical_combine (vrange , enum tree_code code,
 	  r.dump (dump_file);
 	  fputc ('\n', dump_file);
 	}
+  return res;
 }
 
   switch (code)
package body Opt102_Pkg is

  function Get (E : Enum; F, M : access Integer) return Integer is
  begin
case E is
  when One   => return 0;
  when Two   => return F.all;
  when Three => return M.all;
end case;
  end;

end Opt102_Pkg;
-- { dg-do run }
-- { dg-options "-O2 -gnata" }

with Opt102_Pkg; use Opt102_Pkg;

procedure Opt102 is
  I, F : aliased Integer;
begin
  I := Get (Two, F'Access, null);
end;
package Opt102_Pkg is

  type Enum is (One, Two, Three);

  function Get (E : Enum; F, M : access Integer) return Integer
with Pre => (E = One) = (F = null and M = null) and
(E = Two) = (F /= null) and
(E = Three) = (M /= null);

end Opt102_Pkg;


Re: PING^5: [PATCH] rtl-optimization/110939 Really fix narrow comparison of memory and constant

2023-09-25 Thread Eric Botcazou
> This is why I got a bit uncertain and hoped to get some feedback whether
> my intuition is correct or not.  Meanwhile I also found a comment in
> the internals book at "14.7 Constant Expression Types" where we have:
> 
>"Constants generated for modes with fewer bits than in HOST_WIDE_INT
> must be sign extended to full width (e.g., with gen_int_mode).
> [...]
> Note however that values are neither inherently signed nor
> inherently unsigned; where necessary, signedness is determined by
> the rtl operation instead."
> 
> At least this and the assert statement document that the normal form of
> a CONST_INT is kind of special w.r.t. unsigned integers.  Is there
> anyone who can shed some light on _why_ such a normal form was chosen?

In RTL integral values have no sign, they just represent a given pattern of 
bits so, in order to have a 1-to-1 mapping, you need to choose a canonical 
form.  The signed form is probably more natural and, since CONST_INTs have no 
mode, the same objects are used for e.g. QImode and HImode, which means that 
you need to sign-extend the bit pattern.

-- 
Eric Botcazou




Re: [PATCH] ssa_name_has_boolean_range vs signed-boolean:31 types

2023-09-12 Thread Eric Botcazou via Gcc-patches
> Does Ada have signed booleans that are BOOLEAN_TYPE but do _not_
> have [-1, 0] as range?  I think documenting [0, 1] for (single-bit
> precision?) unsigned BOOLEAN_TYPE and [-1, 1] for signed BOOLEAN_TYPE would
> be conservative.

All BOOLEAN_TYPEs are unsigned in Ada but may have precision > 1, typically 8.

-- 
Eric Botcazou




Re: [committed] libstdc++: Fix compare_exchange_padding.cc test for std::atomic_ref

2023-09-02 Thread Eric Botcazou via Gcc-patches
> This should be fixed now. I rewrote the test to check the padding byte
> directly, instead of inspecting a copy of it which might not preserve
> the padding bits.

Great, thanks!

-- 
Eric Botcazou




Re: [PATCH v2] Store_bit_field_1: Use SUBREG instead of REG if possible

2023-07-19 Thread Eric Botcazou via Gcc-patches
> I don't see that.  That's definitely not what GCC expects here,
> the left-most word of the doubleword should be unchanged.
> 
> Your testcase should be a dg-do-run and probably more like
> 
> NOMIPS16 int __attribute__((noipa)) test (const unsigned char *buf)
> {
>   int val;
>   ((unsigned char*))[0] = *buf++;
>   ((unsigned char*))[1] = *buf++;
>   ((unsigned char*))[2] = *buf++;
>   ((unsigned char*))[3] = *buf++;
>   return val;
> }
> int main()
> {
>   int val = 0x01020304;
>   val = test ();
>   if (val != 0x01020304)
> abort ();
> }
> 
> not sure if I got endianess correct.  Now, the question is what
> WORD_REGISTER_OPERATIONS implies for a bitfield insert and what
> the MIPS ABI says for returning SImode.

WORD_REGISTER_OPERATIONS must *not* be taken account for bit-fields, see e;g. 
word_register_operation_p:

/* Return true if X is an operation that always operates on the full
   registers for WORD_REGISTER_OPERATIONS architectures.  */

inline bool
word_register_operation_p (const_rtx x)
{
  switch (GET_CODE (x))
{
case CONST_INT:
case ROTATE:
case ROTATERT:
case SIGN_EXTRACT:
case ZERO_EXTRACT:
  return false;

default:
  return true;
}
}

-- 
Eric Botcazou




Re: [COMMITTED] ada: Follow-up fix for compilation issue with recent MinGW-w64 versions

2023-07-11 Thread Eric Botcazou via Gcc-patches
> It turns out that adaint.c includes other Windows header files than just
> windows.h, so defining WIN32_LEAN_AND_MEAN is not sufficient for it.
> 
> gcc/ada/
> 
>   * adaint.c [_WIN32]: Undefine 'abort' macro.

I backported it onto the 13 branch.

-- 
Eric Botcazou




Re: [COMMITTED] ada: Fix expanding container aggregates

2023-07-07 Thread Eric Botcazou via Gcc-patches
> Ensure that that container aggregate expressions are expanded as
> such and not as records even if the type of the expression is a
> record.
> 
> gcc/ada/
> 
>   * exp_aggr.adb (Expand_N_Aggregate): Ensure that container
>   aggregate expressions do not get expanded as records but instead
>   as container aggregates.

This is not a regression but the problem is quite visible in Ada 2022 so I 
backported the fix onto the 13 branch.

-- 
Eric Botcazou





Re: [COMMITTED] ada: Fix internal error on aggregate within container aggregate

2023-07-07 Thread Eric Botcazou via Gcc-patches
> This just applies the same fix to Expand_Array_Aggregate as the one that was
> recently applied to Convert_To_Assignments.
> 
> gcc/ada/
> 
>   * exp_aggr.adb (Convert_To_Assignments): Tweak comment.
>   (Expand_Array_Aggregate): Do not delay the expansion if the parent
>   node is a container aggregate.

This is not a regression but the problem is quite visible in Ada 2022 so I 
backported the fix onto the 13 branch.

-- 
Eric Botcazou




Re: [COMMITTED] ada: Fix crash on vector initialization

2023-07-07 Thread Eric Botcazou via Gcc-patches
> Such assignments to container aggregates are later transformed into
> procedure calls to the procedures named in the Aggregate aspect
> definition, for which the delayed expansion is not required/expected.
> 
> gcc/ada/
> 
>   * exp_aggr.adb (Convert_To_Assignments): Do not mark node for
>   delayed expansion if parent type has the Aggregate aspect.
>   * sem_util.adb (Is_Container_Aggregate): Move...
>   * sem_util.ads (Is_Container_Aggregate): ... here and make it
>   public.

This is not a regression but the problem is quite visible in Ada 2022 so I 
backported the fix onto the 13 branch.

-- 
Eric Botcazou




[PATCH] Fix couple of endianness issues in fold_ctor_reference

2023-06-30 Thread Eric Botcazou via Gcc-patches
Hi,

fold_ctor_reference attempts to use a recursive local processing in order to 
call native_encode_expr on the leaf nodes of the constructor, before falling 
back to calling native_encode_initializer if this fails.  There are a couple 
of issues related to endianness present in it:
  1) it does not specifically handle integral bit-fields; now these are left 
justified on big-endian platforms so cannot be treated like ordinary fields.
  2) it does not check that the constructor uses the native storage order.

Proposed fix attached, tested on x86-64/Linux and SPARC/Solaris, OK for the 
mainline and some branches?


2023-06-30  Eric Botcazou  

* gimple-fold.cc (fold_array_ctor_reference): Fix head comment.
(fold_nonarray_ctor_reference): Likewise.  Specifically deal
with integral bit-fields.
(fold_ctor_reference): Check that the constructor uses the
native storage order.


2023-06-30  Eric Botcazou  

* gcc.c-torture/execute/20230630-1.c: New test.
* gcc.c-torture/execute/20230630-2.c: Likewise.

-- 
Eric Botcazoudiff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 3d46b76edeb..e80a72dfa22 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -7849,12 +7849,11 @@ get_base_constructor (tree base, poly_int64_pod *bit_offset,
 }
 }
 
-/* CTOR is CONSTRUCTOR of an array type.  Fold a reference of SIZE bits
-   to the memory at bit OFFSET. When non-null, TYPE is the expected
-   type of the reference; otherwise the type of the referenced element
-   is used instead. When SIZE is zero, attempt to fold a reference to
-   the entire element which OFFSET refers to.  Increment *SUBOFF by
-   the bit offset of the accessed element.  */
+/* CTOR is a CONSTRUCTOR of an array or vector type.  Fold a reference of SIZE
+   bits to the memory at bit OFFSET.  If non-null, TYPE is the expected type of
+   the reference; otherwise the type of the referenced element is used instead.
+   When SIZE is zero, attempt to fold a reference to the entire element OFFSET
+   refers to.  Increment *SUBOFF by the bit offset of the accessed element.  */
 
 static tree
 fold_array_ctor_reference (tree type, tree ctor,
@@ -8019,13 +8018,11 @@ fold_array_ctor_reference (tree type, tree ctor,
   return type ? build_zero_cst (type) : NULL_TREE;
 }
 
-/* CTOR is CONSTRUCTOR of an aggregate or vector.  Fold a reference
-   of SIZE bits to the memory at bit OFFSET.   When non-null, TYPE
-   is the expected type of the reference; otherwise the type of
-   the referenced member is used instead.  When SIZE is zero,
-   attempt to fold a reference to the entire member which OFFSET
-   refers to; in this case.  Increment *SUBOFF by the bit offset
-   of the accessed member.  */
+/* CTOR is a CONSTRUCTOR of a record or union type.  Fold a reference of SIZE
+   bits to the memory at bit OFFSET.  If non-null, TYPE is the expected type of
+   the reference; otherwise the type of the referenced member is used instead.
+   When SIZE is zero, attempt to fold a reference to the entire member OFFSET
+   refers to.  Increment *SUBOFF by the bit offset of the accessed member.  */
 
 static tree
 fold_nonarray_ctor_reference (tree type, tree ctor,
@@ -8037,8 +8034,7 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
   unsigned HOST_WIDE_INT cnt;
   tree cfield, cval;
 
-  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield,
-			cval)
+  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
 {
   tree byte_offset = DECL_FIELD_OFFSET (cfield);
   tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
@@ -8110,6 +8106,19 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
 	return NULL_TREE;
 
 	  offset_int inner_offset = offset_int (offset) - bitoffset;
+
+	  /* Integral bit-fields are left-justified on big-endian targets, so
+	 we must arrange for native_encode_int to look at the MSB.  */
+  if (DECL_BIT_FIELD (cfield) && INTEGRAL_TYPE_P (TREE_TYPE (cfield)))
+	{
+	  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+		return NULL_TREE;
+	  const unsigned int encoding_size
+		= GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (cfield)));
+	  if (BYTES_BIG_ENDIAN)
+		inner_offset += encoding_size - wi::to_offset (field_size);
+	}
+
 	  return fold_ctor_reference (type, cval,
   inner_offset.to_uhwi (), size,
   from_decl, suboff);
@@ -8122,7 +8131,7 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
   return build_zero_cst (type);
 }
 
-/* CTOR is value initializing memory.  Fold a reference of TYPE and
+/* CTOR is a value initializing memory.  Fold a reference of TYPE and
bit size POLY_SIZE to the memory at bit POLY_OFFSET.  When POLY_SIZE
is zero, attempt to fold a reference to the entire subobject
which OFFSET refers to.  This is used when folding accesses to
@@ -8163,7 +8172,8 @@ fold_ctor_reference (tree type, tree ctor, const poly_uint64 _offset,
 	}
   re

Re: [PATCH] configure: Implement --enable-host-bind-now

2023-06-27 Thread Eric Botcazou via Gcc-patches
> Arg, once again, I'm sorry.  I don't know how this happened.  It would
> be trivial to fix it but since
> 
> commit 4a48a38fa99f067b8f3a3d1a5dc7a1e602db351f
> Author: Eric Botcazou 
> Date:   Wed Jun 21 18:19:36 2023 +0200
> 
> ada: Fix build of GNAT tools
> 
> the build with Ada included fails with --enable-host-pie.  So that needs
> to be fixed first.
> 
> Eric, I'm not asking you to fix that, but I'm curious, what did the
> commit above fix?  The patch looks correct; I'm just puzzled why I
> hadn't seen any build failures.

The GNAT tools were failing to build for a compiler configured with --disable-
host-pie --enable-default-pie.

-- 
Eric Botcazou




Re: When do I need -fnon-call-exceptions?

2023-06-07 Thread Eric Botcazou via Gcc
> On x864 Linux -fasynchronous-unwind-tables is the default.  That is
> probably sufficient to make your test case work.

The testcase g++.dg/torture/except-1.C you recently added to the testsuite 
does not pass at all if -fnon-call-exceptions is not specified (and does not 
pass with optimization if -fno-delete-dead-exceptions is not specified).

-- 
Eric Botcazou




Re: [PATCH] tree: Fix up save_expr [PR52339]

2023-05-30 Thread Eric Botcazou via Gcc-patches
> We want to be able to treat such things as invariant somehow even if we
> can't do that for references to user data that might be changed by
> intervening code.
> 
> That is, indicate that we know that the _REF actually refers to a const
> variable or is otherwise known to be unchanging.
> 
> Perhaps that should be a new flag that tree_invariant_p can check
> instead of TREE_READONLY.

Richard earlier suggested a langhook; given that Ada will be the main (sole?) 
user of it, this would probably be better.

-- 
Eric Botcazou





Re: [COMMITTED] ada: Remove the body of System.Storage_Elements

2023-05-29 Thread Eric Botcazou via Gcc-patches
> Is this an issue with the patch? Or does it need a newer Ada compiler
> to for building it?

Neither, it's very likely an issue with your build procedure: you need to use 
a matching host Ada compiler to build a cross Ada compiler, that's documented 
in https://gcc.gnu.org/install/prerequisites.html#GNAT-prerequisite

"In order to build a cross compiler, it is strongly recommended to install the 
new compiler as native first, and then use it to build the cross compiler. 
Other native compiler versions may work but this is not guaranteed and will 
typically fail with hard to understand compilation errors during the build."

-- 
Eric Botcazou




Re: [PATCH] Fix artificial overflow during GENERIC folding

2023-05-24 Thread Eric Botcazou via Gcc-patches
> But nobody is going to understand why the INTEGER_CST case goes the
> other way.

I can add a fat comment to that effect of course. :-)

> As you say we don't have a good way to say we're doing
> this to avoid undefined behavior, but then a view-convert back would
> be a good way to indicate that?  I can't come up with a better name
> for a custom operator we could also use,
> 
>   (convert_without_overflow (negate (convert:utype @1
> 
> maybe?  As said, if view_convert works I prefer that.  Does it?

Well, VIEW_CONVERT_EXPR adds its own set of problems in GENERIC and it will 
precisely survive when it is not needed, so I'm not sure that's any better.

-- 
Eric Botcazou




Re: [PATCH] Fix artificial overflow during GENERIC folding

2023-05-24 Thread Eric Botcazou via Gcc-patches
> I don't like littering the patterns with this and it's likely far from the
> only cases we have?

Maybe, but that's the only problematic case we have in Ada.  It occurs only on 
mainline because we have streamlined address calculations there, from out-of-
line to inline expansion, i.e. from run time to compile time.

> Since we did move some of the patterns from fold-const.cc to match.pd and
> the frontends might be interested in TREE_OVERFLOW (otherwise we'd just
> scrap that!) I'm not sure removing the flag is good (and I never was really
> convinced the setting for the implementation defined behavior on conversion
> to unsigned is good).

Yes, the Ada front-end relies on the TREE_OVERFLOW flag to detect overflows at 
compile time, so it cannot be removed, but it must be set correctly, which is 
not the case here: (T)p - (T) (p + 4) where T is signed should just yield -4.

> Am I correct that the user writing such a conversion in Ada _should_
> get a constraint violation?  So it's just the middle-end introducing it
> to avoid undefined signed overflow that's on error?

Yes, it's a Constraint_Error in Ada to convert a value of an unsigned type to 
a signed type if it does not fit in the signed type.

> I'll also note that fold_convert_const_int_from_int shouldn't set
> TREE_OVERFLOW on unsigned destination types?  So it's the
> outer conversion back to signed that generates the TREE_OVERFLOW?

Yes, 4 is converted to unsigned, then negated, yielding a huge number, and the 
final conversion back to signed yields -4 with TREE_OVERFLOW set.

> Would it help to use a (view_convert ...) here?  For non-constants that
> should be folded back to a sign changing (convert ...) but the constant
> folding should hopefully happen earlier?  But it's again implementation
> defined behavior we have here, so not sure we need TREE_OVERFLOW at all.

I'm not sure we need to jump through too many hoops here: the intermediate 
conversion trick is a kludge because we lack a proper method to selectively 
disable undefined overflow at run time, but that's not the case at compile 
time where we have a finer-grained control (and even different rules) so I 
don't really see a problem with handling the two cases differently.

-- 
Eric Botcazou




[PATCH] Fix artificial overflow during GENERIC folding

2023-05-24 Thread Eric Botcazou via Gcc-patches
Hi,

on the attached testcase, the Ada compiler gives a bogus warning:
storage_offset1.ads:16:52: warning: Constraint_Error will be raised at run 
time [enabled by default]

This directly comes from the GENERIC folding setting a bogus TREE_OVERFLOW on 
an INTEGER_CST during the (T)P - (T)(P + A) -> -(T) A transformation:

  /* (T)P - (T)(P + A) -> -(T) A */
  (simplify
   (minus (convert? @0)
(convert (plus:c @@0 @1)))
   (if (INTEGRAL_TYPE_P (type)
&& TYPE_OVERFLOW_UNDEFINED (type)
&& element_precision (type) <= element_precision (TREE_TYPE (@1)))
(with { tree utype = unsigned_type_for (type); }
 (convert (negate (convert:utype @1
(if (element_precision (type) <= element_precision (TREE_TYPE (@1))
 /* For integer types, if A has a smaller type
than T the result depends on the possible
overflow in P + A.
E.g. T=size_t, A=(unsigned)429497295, P>0.
However, if an overflow in P + A would cause
undefined behavior, we can assume that there
is no overflow.  */
 || (INTEGRAL_TYPE_P (TREE_TYPE (@1))
 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@1
 (negate (convert @1)
  (simplify
   (minus (convert @0)
(convert (pointer_plus @@0 @1)))
   (if (INTEGRAL_TYPE_P (type)
&& TYPE_OVERFLOW_UNDEFINED (type)
&& element_precision (type) <= element_precision (TREE_TYPE (@1)))
(with { tree utype = unsigned_type_for (type); }
 (convert (negate (convert:utype @1
(if (element_precision (type) <= element_precision (TREE_TYPE (@1))
 /* For pointer types, if the conversion of A to the
final type requires a sign- or zero-extension,
then we have to punt - it is not defined which
one is correct.  */
 || (POINTER_TYPE_P (TREE_TYPE (@0))
 && TREE_CODE (@1) == INTEGER_CST
 && tree_int_cst_sign_bit (@1) == 0))
 (negate (convert @1)

Ironically enough, this occurs because of the intermediate conversion to an 
unsigned type which is supposed to hide overflows, but is counter-productive 
for constants because TREE_OVERFLOW is always set for them, so it ends up 
setting a bogus TREE_OVERFLOW when converting back to the original type.

The fix simply redirects INTEGER_CSTs to the other, direct path without the 
intermediate conversion to the unsigned type.

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


2023-05-24  Eric Botcazou 

* match.pd ((T)P - (T)(P + A) -> -(T) A): Avoid artificial overflow
on constants.


2023-05-24  Eric Botcazou 

* gnat.dg/specs/storage_offset1.ads: New test.

-- 
Eric Botcazoudiff --git a/gcc/match.pd b/gcc/match.pd
index 1fe0559acfb..b9d04dd423b 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3194,6 +3194,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (convert (plus:c @@0 @1)))
(if (INTEGRAL_TYPE_P (type)
 	&& TYPE_OVERFLOW_UNDEFINED (type)
+	&& TREE_CODE (@1) != INTEGER_CST
 	&& element_precision (type) <= element_precision (TREE_TYPE (@1)))
 (with { tree utype = unsigned_type_for (type); }
  (convert (negate (convert:utype @1
@@ -3213,6 +3214,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (convert (pointer_plus @@0 @1)))
(if (INTEGRAL_TYPE_P (type)
 	&& TYPE_OVERFLOW_UNDEFINED (type)
+	&& TREE_CODE (@1) != INTEGER_CST
 	&& element_precision (type) <= element_precision (TREE_TYPE (@1)))
 (with { tree utype = unsigned_type_for (type); }
  (convert (negate (convert:utype @1
-- { dg-do compile }

with System.Storage_Elements; use System.Storage_Elements;
with System;

package Storage_Offset1 is

  type Rec is record
I1, I2 : Integer;
  end record;

  type Ptr is access all Rec;

  R : Ptr := new Rec;

  Offset : constant Storage_Offset := R.I1'Address - R.I2'Address;

end Storage_Offset1;


Re: [PATCH] Fix handling of non-integral bit-fields in native_encode_initializer

2023-05-23 Thread Eric Botcazou via Gcc-patches
> OK.

Thanks!

> Can we handle non-integer bitfields by recursing with a temporary buffer to
> encode it byte-aligned and then apply shifting and masking to get it in
> place? Or is that not worth it?

Certainly doable, something along these lines is implemented in varasm.c to 
output these non-integral bit-fields (output_constructor et al) so we could 
even try to share some code.  However, in practice, these cases turn out to be 
rare because the tree_output_constant_def path in gimplify_init_constructor is 
well guarded.

-- 
Eric Botcazou




[PATCH] Fix handling of non-integral bit-fields in native_encode_initializer

2023-05-22 Thread Eric Botcazou via Gcc-patches
Hi,

the encoder for CONSTRUCTORs assumes that all bit-fields (DECL_BIT_FIELD) have
integral types, but that's not the case in Ada where they may have pretty much
any type, resulting in a wrong encoding for them.

The attached fix filters out non-integral bit-fields, except if they start and
end on a byte boundary because they are correctly handled in this case.

Bootstrapped/regtested on x86-64/Linux, OK for mainline and 13 branch?


2023-05-22  Eric Botcazou  

* fold-const.cc (native_encode_initializer) : Apply the
specific treatment for bit-fields only if they have an integral type
and filter out non-integral bit-fields that do not start and end on
a byte boundary.


2023-05-22  Eric Botcazou  

* gnat.dg/opt101.adb: New test.
* gnat.dg/opt101_pkg.ads: New helper.

-- 
Eric Botcazoudiff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 25466e97220..57521501fff 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -8360,20 +8360,26 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
 	  if (fieldsize == 0)
 		continue;
 
+	  /* Prepare to deal with integral bit-fields and filter out other
+		 bit-fields that do not start and end on a byte boundary.  */
 	  if (DECL_BIT_FIELD (field))
 		{
 		  if (!tree_fits_uhwi_p (DECL_FIELD_BIT_OFFSET (field)))
 		return 0;
-		  fieldsize = TYPE_PRECISION (TREE_TYPE (field));
 		  bpos = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field));
-		  if (bpos % BITS_PER_UNIT)
-		bpos %= BITS_PER_UNIT;
-		  else
-		bpos = 0;
-		  fieldsize += bpos;
-		  epos = fieldsize % BITS_PER_UNIT;
-		  fieldsize += BITS_PER_UNIT - 1;
-		  fieldsize /= BITS_PER_UNIT;
+		  if (INTEGRAL_TYPE_P (TREE_TYPE (field)))
+		{
+		  bpos %= BITS_PER_UNIT;
+		  fieldsize = TYPE_PRECISION (TREE_TYPE (field)) + bpos;
+		  epos = fieldsize % BITS_PER_UNIT;
+		  fieldsize += BITS_PER_UNIT - 1;
+		  fieldsize /= BITS_PER_UNIT;
+		}
+		  else if (bpos % BITS_PER_UNIT
+			   || DECL_SIZE (field) == NULL_TREE
+			   || !tree_fits_shwi_p (DECL_SIZE (field))
+			   || tree_to_shwi (DECL_SIZE (field)) % BITS_PER_UNIT)
+		return 0;
 		}
 
 	  if (off != -1 && pos + fieldsize <= off)
@@ -8382,7 +8388,8 @@ native_encode_initializer (tree init, unsigned char *ptr, int len,
 	  if (val == NULL_TREE)
 		continue;
 
-	  if (DECL_BIT_FIELD (field))
+	  if (DECL_BIT_FIELD (field)
+		  && INTEGRAL_TYPE_P (TREE_TYPE (field)))
 		{
 		  /* FIXME: Handle PDP endian.  */
 		  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
-- { dg-do run }
-- { dg-options "-O" }

pragma Optimize_Alignment (Space);

with Opt101_Pkg; use Opt101_Pkg;

procedure Opt101 is

  C1 : Cont1;
  C2 : Cont2;

begin
  C1 := ((1234, 1, 2), 1, 2);
  if C1.R.I1 /= 1 or C1.I2 /= 2 then
raise Program_Error;
  end if;

  C2 := (1, (1234, 1, 2), 2);
  if C2.R.I1 /= 1 or C2.I2 /= 2 then
raise Program_Error;
  end if;
end;
package Opt101_Pkg is

  type Int is mod 16;

  type Rec is record
S : Short_Integer;
I1, I2 : Int;
  end record;
  pragma Pack (Rec);
  for Rec'Alignment use 4;

  type Cont1 is record
R : Rec;
I1, I2 : Int;
  end record;
  pragma Pack (Cont1);

  type Cont2 is record
I1 : Int;
R  : Rec;
I2 : Int;
  end record;
  pragma Pack (Cont2);
  pragma No_Component_Reordering (Cont2);

end Opt101_Pkg;


Re: [PATCH] Fix internal error on small array with negative lower bound

2023-05-18 Thread Eric Botcazou via Gcc-patches
> Would it be better to use
> 
>   wi::to_uhwi (wi::to_wide (local->index) - wi::to_wide (local->min_index))
> 
> to honor the actual sign of the indices?  I think nothing forbids frontends
> to use a signed TYPE_DOMAIN here?  But the difference should be always
> representable in an unsigned value of course.

We use tree_to_uhwi everywhere else though, see categorize_ctor_elements_1:

  if (tree_fits_uhwi_p (lo_index) && tree_fits_uhwi_p (hi_index))
mult = (tree_to_uhwi (hi_index)
- tree_to_uhwi (lo_index) + 1);

or store_constructor

this_node_count = (tree_to_uhwi (hi_index)
   - tree_to_uhwi (lo_index) + 1);

so the proposed form looks better for the sake of consistency.

-- 
Eric Botcazou




[PATCH] Fix internal error on small array with negative lower bound

2023-05-18 Thread Eric Botcazou via Gcc-patches
Hi,

Ada supports arrays with negative indices, although the internal index type is
sizetype like in other languages, which is unsigned.  This means that negative
values are represented by very large numbers, which works with a bit of care.
The attached test exposes a small loophole in output_constructor_bitfield.

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


2023-05-18  Eric Botcazou 

* varasm.cc (output_constructor_bitfield): Call tree_to_uhwi instead
of tree_to_shwi on array indices.  Minor tweaks.


2023-05-18  Eric Botcazou 

* gnat.dg/specs/array6.ads: New test.

-- 
Eric Botcazoudiff --git a/gcc/varasm.cc b/gcc/varasm.cc
index 2256194d934..478cbfe6736 100644
--- a/gcc/varasm.cc
+++ b/gcc/varasm.cc
@@ -5585,19 +5585,18 @@ output_constructor_bitfield (oc_local_state *local, unsigned int bit_offset)
 
   /* Relative index of this element if this is an array component.  */
   HOST_WIDE_INT relative_index
-= (!local->field
-   ? (local->index
-	  ? (tree_to_shwi (local->index)
-	 - tree_to_shwi (local->min_index))
-	  : local->last_relative_index + 1)
-   : 0);
+= (local->field
+   ? 0
+   : (local->index
+	  ? tree_to_uhwi (local->index) - tree_to_uhwi (local->min_index)
+	  : local->last_relative_index + 1));
 
   /* Bit position of this element from the start of the containing
  constructor.  */
   HOST_WIDE_INT constructor_relative_ebitpos
-  = (local->field
-	 ? int_bit_position (local->field)
-	 : ebitsize * relative_index);
+= (local->field
+   ? int_bit_position (local->field)
+   : ebitsize * relative_index);
 
   /* Bit position of this element from the start of a possibly ongoing
  outer byte buffer.  */
-- { dg-do compile }

package Array6 is 

  type Range_Type is range -10 ..  10;
  type Array_Type is array (Range_Type range <> ) of Short_Short_Integer;

  type Record_Type is record 
A : Array_Type(-2..4);
  end record ;

  Rec : Record_Type := (A => (others => -1));

end Array6;


Re: [PATCH 01/14] ada: use _P() defines from tree.h

2023-05-15 Thread Eric Botcazou via Gcc-patches
>   && DECL_RETURN_VALUE_P (inner))
> diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc
> index 0c4f8b90c8e..460ef6f1f01 100644
> --- a/gcc/ada/gcc-interface/utils.cc
> +++ b/gcc/ada/gcc-interface/utils.cc
> @@ -1966,7 +1966,7 @@ finish_record_type (tree record_type, tree field_list,
> int rep_level, bool debug_info_p)
>  {
>const enum tree_code orig_code = TREE_CODE (record_type);
> -  const bool had_size = TYPE_SIZE (record_type) != NULL_TREE;
> +  const bool had_size = COMPLETE_TYPE_P (record_type);
>const bool had_align = TYPE_ALIGN (record_type) > 0;
>/* For all-repped records with a size specified, lay the QUAL_UNION_TYPE
>   out just like a UNION_TYPE, since the size will be fixed.  */

This one is not an improvement but more of a coincidence; the rest is OK.

-- 
Eric Botcazou




Re: [PATCH] tree: Fix up save_expr [PR52339]

2023-05-13 Thread Eric Botcazou via Gcc-patches
> I think we really need Eric (as one who e.g. introduced the
> DECL_INVARIANT_P apparently for this kind of stuff) to have a look at that
> on the Ada side.

I have been investigating this for a few days and it's no small change for Ada 
and probably for other languages with dynamic types.  SAVE_EXPRs are delicate 
to handle because 1) they are TREE_SIDE_EFFECTS (it's explained in save_expr) 
so out of TREE_READONLY && !TREE_SIDE_EFFECTS trees, you now get side effects 
which then propagate to all parent nodes 2) their placement is problematic in 
conditional expressions, for example if you replace

  cond > 0 ? A : A + 1

with

  cond > 0 ? SAVE_EXPR (A) : SAVE_EXPR (A) + 1

then gimplification will, say, create the temporary and initialize it in the 
first arm so, if at runtime you take the second arm, you'll read the temporary 
uninitialized.  That's caught for scalar values by the SSA form (if your patch 
is applied to a GCC 12 tree, you'll get ICEs in the ACATS testsuite because of 
this through finalize_type_size -> variable_size -> save_expr, it is probably 
mitigated/addressed in GCC 14 by 68e0063397ba820e71adc220b2da0581dce29ffa).
That's also why making gnat_invariant_expr return (some of) them does not look 
really safe.

In addition to this, in Ada we have bounds of unconstrained arrays which are 
both read-only and stored indirectly, i.e. you have an INDIRECT_REF in the 
tree (it is marked TREE_THIS_NOTRAP because the bounds are always present), 
and which obviously play a crucial role in loops running over the arrays.
This issue is responsible for the regressions in the gnat.dg testsuite.

I think that we can reasonably deal with the second issue in the Ada front-end 
because we know the semantics of the bounds of unconstrained arrays, and I'm 
testing a patch to that effect, but the first issue might be annoying too.

-- 
Eric Botcazou




Re: [PATCH] tree: Fix up save_expr [PR52339]

2023-05-09 Thread Eric Botcazou via Gcc-patches
> I think we really need Eric (as one who e.g. introduced the
> DECL_INVARIANT_P apparently for this kind of stuff) to have a look at that
> on the Ada side.

DECL_INVARIANT_P is only set on discriminants with no default value and those 
are really invariant in Ada, i.e. do not change once set.

> The question is if the posted tree.cc (smallest) patch + 3 new testcases
> + the 7 ada testsuite workarounds are ok for trunk if it passes
> bootstrap/regtest, then I'd file a PR about the Ada regression and only once
> it is dealt with would consider backporting, or if we need to wait for Eric
> before making progress.

Let me have a quick look first, as pessimizing loop optimizations in Ada in 
order to fix a 11-year old PR seems to be a little bit hasty.

-- 
Eric Botcazou




Re: Probe emission in fstack-clash-protection

2023-05-03 Thread Eric Botcazou via Gcc
> That may ultimately be better for -fstack-check to make it more robust,
> but it still wouldn't be a viable alternative for stack clash protection
> for the reasons laid out in that blog post.

Well, -fstack-check does that when it's possible, e.g. on Windows, but it's 
not on x86[_64]/Linux where you *cannot* probe below the stack pointer.

-- 
Eric Botcazou




Re: [PATCH] Avoid creating useless debug temporaries

2023-04-26 Thread Eric Botcazou via Gcc-patches
> probably also helps PR109612 and the other similar PR referenced therein.

Here's a more aggressive patch in this area, but it regresses guality tests, 
for example:

+FAIL: gcc.dg/guality/ipa-sra-1.c   -O2  -DPREVENT_OPTIMIZATION  line 27 k == 
3
+FAIL: gcc.dg/guality/ipa-sra-1.c   -O3 -g  -DPREVENT_OPTIMIZATION  line 27 k 
== 3
+FAIL: gcc.dg/guality/ipa-sra-1.c   -Os  -DPREVENT_OPTIMIZATION  line 27 k == 
3

eric@fomalhaut:~/build/gcc/native> diff -u ipa-sra-1.c.254t.optimized.0 ipa-
sra-1.c.254t.optimized
--- ipa-sra-1.c.254t.optimized.02023-04-26 11:12:07.806357325 +0200
+++ ipa-sra-1.c.254t.optimized  2023-04-26 11:24:08.632874257 +0200
@@ -101,7 +101,6 @@
   # DEBUG k => k_5
   # DEBUG BEGIN_STMT
   _1 = get_val1 ();
-  # DEBUG D#6 => k_5
   r_8 = foo.isra (_1);
   # DEBUG r => r_8
   # DEBUG BEGIN_STMT

and I don't understand why yet.


* tree-ssa-dce.cc (find_debug_expr_decl): New callback.
(mark_stmt_if_obviously_necessary): Add DECLS parameters.
: Call find_debug_expr_decl on the value of
DEBUG_BIND statements and record the results in DECLS.
(find_obviously_necessary_stmts): If DEBUG_BIND statements may be
present, get rid of those setting an unnecessary DEBUG_EXPR_DECL.

-- 
Eric Botcazoudiff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index 08876bfc1c7..09bbfaca22e 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -191,14 +191,35 @@ mark_operand_necessary (tree op)
 }
 
 
+/* Called via walk_tree, look for DEBUG_EXPR_DECLs and mark them in DATA.  */
+
+static tree
+find_debug_expr_decl (tree *tp, int *walk_subtrees, void *data)
+{
+  auto_bitmap *decls = (auto_bitmap *) data;
+
+  if (TREE_CODE (*tp) == SSA_NAME || IS_TYPE_OR_DECL_P (*tp))
+{
+  if (TREE_CODE (*tp) == DEBUG_EXPR_DECL)
+	bitmap_set_bit (*decls, DECL_UID (*tp));
+
+  *walk_subtrees = 0;
+}
+
+  return NULL_TREE;
+}
+
 /* Mark STMT as necessary if it obviously is.  Add it to the worklist if
it can make other statements necessary.
 
+   If STMT is a DEBUG_BIND, mark the necessary DEBUG_EXPR_DECLs in DECLS.
+
If AGGRESSIVE is false, control statements are conservatively marked as
necessary.  */
 
 static void
-mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
+mark_stmt_if_obviously_necessary (gimple *stmt, auto_bitmap *decls,
+  bool aggressive)
 {
   /* Statements that are implicitly live.  Most function calls, asm
  and return statements are required.  Labels and GIMPLE_BIND nodes
@@ -258,14 +279,28 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
   }
 
 case GIMPLE_DEBUG:
-  /* Debug temps without a value are not useful.  ??? If we could
-	 easily locate the debug temp bind stmt for a use thereof,
-	 would could refrain from marking all debug temps here, and
-	 mark them only if they're used.  */
-  if (gimple_debug_nonbind_marker_p (stmt)
-	  || !gimple_debug_bind_p (stmt)
-	  || gimple_debug_bind_has_value_p (stmt)
-	  || TREE_CODE (gimple_debug_bind_get_var (stmt)) != DEBUG_EXPR_DECL)
+  if (gimple_debug_bind_p (stmt))
+	{
+	  tree var = gimple_debug_bind_get_var (stmt);
+	  tree val = gimple_debug_bind_get_value (stmt);
+	  bool necessary = false;
+
+	  /* A bind statement for a real variable is always necessary.  */
+	  if (TREE_CODE (var) != DEBUG_EXPR_DECL)
+	necessary = true;
+
+	  /* A bind statement with a value is necessary for now and we look
+	 into the value to find out necessary DEBUG_EXPR_DECLs.  */
+	  if (val)
+	{
+	  walk_tree (, find_debug_expr_decl, decls, NULL);
+	  necessary = true;
+	}
+
+	  if (necessary )
+	mark_stmt_necessary (stmt, false);
+	}
+  else
 	mark_stmt_necessary (stmt, false);
   return;
 
@@ -398,6 +433,7 @@ find_obviously_necessary_stmts (bool aggressive)
   gimple_stmt_iterator gsi;
   edge e;
   gimple *phi, *stmt;
+  auto_bitmap necessary_decls;
   int flags;
 
   FOR_EACH_BB_FN (bb, cfun)
@@ -414,10 +450,35 @@ find_obviously_necessary_stmts (bool aggressive)
 	{
 	  stmt = gsi_stmt (gsi);
 	  gimple_set_plf (stmt, STMT_NECESSARY, false);
-	  mark_stmt_if_obviously_necessary (stmt, aggressive);
+	  mark_stmt_if_obviously_necessary (stmt, _decls, aggressive);
 	}
 }
 
+  /* Check all debug bind statements again in the basic blocks and find out
+ those which set an unnecessary DEBUG_EXPR_DECL to a value.  */
+  if (MAY_HAVE_DEBUG_BIND_STMTS)
+FOR_EACH_BB_FN (bb, cfun)
+  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next ())
+	{
+	  stmt = gsi_stmt (gsi);
+	  if (gimple_debug_bind_p (stmt)
+	  && gimple_debug_bind_has_value_p (stmt))
+	{
+	  tree var = gimple_debug_bind_get_var (stmt);
+	  if (TREE_CODE (var) == DEBUG_EXPR_DECL
+		  && !bitmap_bit_p (necessary_decls, DECL_UID (var)))
+		{
+		  gimple_set_plf (stmt, STMT_NECESSARY, false);
+		  if (dump_file && (dump_flags & TDF_DETAILS))
+		{
+		  fprintf (dump_file, "Unmarking useful stmt: 

Re: [PATCH] Avoid creating useless debug temporaries

2023-04-25 Thread Eric Botcazou via Gcc-patches
> Haven't looked into detail, but just saving compilation time shouldn't be
> the only factor when deciding about debug info stuff, another and perhaps
> even more important would be whether it affects the emitted debug info.

At least it doesn't change the guality results.

-- 
Eric Botcazou




[PATCH] Avoid creating useless debug temporaries

2023-04-25 Thread Eric Botcazou via Gcc-patches
Hi,

insert_debug_temp_for_var_def has some strange code whereby it creates debug 
temporaries for SINGLE_RHS (RHS for gimple_assign_single_p) but not for other 
RHS in the same situation.  Removing it saves 25% of compilation time at -g -O 
for a pathological testcase I have.

Bootstrapped/regtested on x86-64/Linux, OK for the mainline?


2023-04-25  Eric Botcazou  

* tree-ssa.cc (insert_debug_temp_for_var_def): Do not create
superfluous debug temporaries for single GIMPLE assignments.

-- 
Eric Botcazoudiff --git a/gcc/tree-ssa.cc b/gcc/tree-ssa.cc
index a5cad2d344e..4ca1f5f3104 100644
--- a/gcc/tree-ssa.cc
+++ b/gcc/tree-ssa.cc
@@ -412,8 +412,7 @@ insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
 {
   /* If there's a single use of VAR, and VAR is the entire debug
 	 expression (usecount would have been incremented again
-	 otherwise), and the definition involves only constants and
-	 SSA names, then we can propagate VALUE into this single use,
+	 otherwise), then we can propagate VALUE into this single use,
 	 avoiding the temp.
 
 	 We can also avoid using a temp if VALUE can be shared and
@@ -424,11 +423,9 @@ insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
 	 are deferred to a debug temp, although we could avoid temps
 	 at the expense of duplication of expressions.  */
 
-  if (CONSTANT_CLASS_P (value)
+  if (usecount == 1
 	  || gimple_code (def_stmt) == GIMPLE_PHI
-	  || (usecount == 1
-	  && (!gimple_assign_single_p (def_stmt)
-		  || is_gimple_min_invariant (value)))
+	  || CONSTANT_CLASS_P (value)
 	  || is_gimple_reg (value))
 	;
   else
@@ -466,11 +463,6 @@ insert_debug_temp_for_var_def (gimple_stmt_iterator *gsi, tree var)
   if (value)
 	{
 	  FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
-	/* unshare_expr is not needed here.  vexpr is either a
-	   SINGLE_RHS, that can be safely shared, some other RHS
-	   that was unshared when we found it had a single debug
-	   use, or a DEBUG_EXPR_DECL, that can be safely
-	   shared.  */
 	SET_USE (use_p, unshare_expr (value));
 	  /* If we didn't replace uses with a debug decl fold the
 	 resulting expression.  Otherwise we end up with invalid IL.  */


[Ada] Remove obsolete configure code in gnattools

2023-04-25 Thread Eric Botcazou via Gcc-patches
It was recently pointed out that we generate symbolic links to ghost files 
when building the GNAT tools, as the mlib-tgt-specific-*.adb files are gone.

Tested on x86-64/Linux, applied on the mainline.  I'll backport this onto 
branches after the GCC 13.1 release is out.


2023-04-25  Eric Botcazou  

* configure.ac (TOOLS_TARGET_PAIRS): Remove obsolete settings.
(EXTRA_GNATTOOLS): Likewise.
* configure: Regenerate.

-- 
Eric Botcazou
diff --git a/gnattools/configure.ac b/gnattools/configure.ac
index 5b6f34ed9f4..38a28b6ee62 100644
--- a/gnattools/configure.ac
+++ b/gnattools/configure.ac
@@ -53,74 +53,38 @@ AC_PROG_LN_S
 
 # Target-specific stuff (defaults)
 TOOLS_TARGET_PAIRS=
-AC_SUBST(TOOLS_TARGET_PAIRS)
 EXTRA_GNATTOOLS=
-AC_SUBST(EXTRA_GNATTOOLS)
 
 # Per-target case statement
 # -
 case "${target}" in
   *-*-aix*)
-TOOLS_TARGET_PAIRS="\
-mlib-tgt-specific.adb

Re: [PATCH] reload: Handle generating reloads that also clobbers flags

2023-04-18 Thread Eric Botcazou via Gcc-patches
> That "supposed to" is only *one* possible implementation.
> The one in CRIS - and I believe the preferred one; one I
> should advocate more - is to *always* expose clobbering of
> the flags.

Yes, both approaches are acceptable IMO and should work.

-- 
Eric Botcazou




Re: [Ada] Fix PR bootstrap/109510

2023-04-15 Thread Eric Botcazou via Gcc-patches
> Tested on Aarch64/Linux by Richard S. (thanks!) and on x86-64/Linux by me,
> and applied on the mainline.

It turns out that it slightly broke the x86/Linux compiler, which is not yet 
an acceptable trade-off.  Adjusted like this, tested on x86[_64]/Linux, this 
should not change anything for Aarch64 in particular.


PR bootstrap/109510
* gcc-interface/decl.cc (gnat_to_gnu_entity) : Do not reset
align to zero in any case.  Set TYPE_USER_ALIGN on the type only if
it is an aggregate type, or else a type whose default alignment is
specifically capped on selected platforms.

-- 
Eric Botcazou
diff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index 851a6745f77..20f43de9ea9 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -4371,10 +4371,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 	  align = validate_alignment (Alignment (gnat_entity), gnat_entity,
   TYPE_ALIGN (gnu_type));
 
-	  /* Treat confirming clauses on scalar types like the default.  */
-	  if (align == TYPE_ALIGN (gnu_type) && !AGGREGATE_TYPE_P (gnu_type))
-	align = 0;
-
 	  /* Warn on suspiciously large alignments.  This should catch
 	 errors about the (alignment,byte)/(size,bit) discrepancy.  */
 	  if (align > BIGGEST_ALIGNMENT && Has_Alignment_Clause (gnat_entity))
@@ -4657,6 +4653,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
   /* If this is not an unconstrained array type, set some flags.  */
   if (TREE_CODE (gnu_type) != UNCONSTRAINED_ARRAY_TYPE)
 	{
+	  bool align_clause;
+
 	  /* Record the property that objects of tagged types are guaranteed to
 	 be properly aligned.  This is necessary because conversions to the
 	 class-wide type are translated into conversions to the root type,
@@ -4669,8 +4667,20 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 	  if (is_by_ref && !VOID_TYPE_P (gnu_type))
 	TYPE_BY_REFERENCE_P (gnu_type) = 1;
 
-	  /* Record whether an alignment clause was specified.  */
-	  if (align > 0 && Present (Alignment_Clause (gnat_entity)))
+	  /* Record whether an alignment clause was specified.  At this point
+	 scalar types with a non-confirming clause have been wrapped into
+	 a record type, so only scalar types with a confirming clause are
+	 left untouched; we do not set the flag on them except if they are
+	 types whose default alignment is specifically capped in order not
+	 to lose the specified alignment.  */
+	  if ((AGGREGATE_TYPE_P (gnu_type)
+	   && Present (Alignment_Clause (gnat_entity)))
+	  || (double_float_alignment > 0
+		  && is_double_float_or_array (gnat_entity, _clause)
+		  && align_clause)
+	  || (double_scalar_alignment > 0
+		  && is_double_scalar_or_array (gnat_entity, _clause)
+		  && align_clause))
 	TYPE_USER_ALIGN (gnu_type) = 1;
 
 	  /* Record whether a pragma Universal_Aliasing was specified.  */


[Ada] Fix PR bootstrap/109510

2023-04-14 Thread Eric Botcazou via Gcc-patches
This is the build failure of the Ada runtime for Aarch64 targets.  The Aarch64 
back-end now asserts that the main variant of scalar types has TYPE_USER_ALIGN 
cleared, and that's not the case for scalar types declared with a confirming 
alignment clause in Ada.

Tested on Aarch64/Linux by Richard S. (thanks!) and on x86-64/Linux by me, and 
applied on the mainline.


2023-04-14  Eric Botcazou  

PR bootstrap/109510
* gcc-interface/decl.cc (gnat_to_gnu_entity) : Reset align
to zero if its value is equal to TYPE_ALIGN and the type is scalar.
Set TYPE_USER_ALIGN on the type only if align is positive.

-- 
Eric Botcazoudiff --git a/gcc/ada/gcc-interface/decl.cc b/gcc/ada/gcc-interface/decl.cc
index d24adf33601..851a6745f77 100644
--- a/gcc/ada/gcc-interface/decl.cc
+++ b/gcc/ada/gcc-interface/decl.cc
@@ -4364,13 +4364,17 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
   /* If the alignment has not already been processed and this is not
 	 an unconstrained array type, see if an alignment is specified.
 	 If not, we pick a default alignment for atomic objects.  */
-  if (align != 0 || TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
+  if (align > 0 || TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE)
 	;
   else if (Known_Alignment (gnat_entity))
 	{
 	  align = validate_alignment (Alignment (gnat_entity), gnat_entity,
   TYPE_ALIGN (gnu_type));
 
+	  /* Treat confirming clauses on scalar types like the default.  */
+	  if (align == TYPE_ALIGN (gnu_type) && !AGGREGATE_TYPE_P (gnu_type))
+	align = 0;
+
 	  /* Warn on suspiciously large alignments.  This should catch
 	 errors about the (alignment,byte)/(size,bit) discrepancy.  */
 	  if (align > BIGGEST_ALIGNMENT && Has_Alignment_Clause (gnat_entity))
@@ -4666,7 +4670,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
 	TYPE_BY_REFERENCE_P (gnu_type) = 1;
 
 	  /* Record whether an alignment clause was specified.  */
-	  if (Present (Alignment_Clause (gnat_entity)))
+	  if (align > 0 && Present (Alignment_Clause (gnat_entity)))
 	TYPE_USER_ALIGN (gnu_type) = 1;
 
 	  /* Record whether a pragma Universal_Aliasing was specified.  */


Re: gcc with the new WIN32 threads fails to compile libstdc++

2023-04-10 Thread Eric Botcazou via Gcc
> I'm assuming the problem also extends to the other __gthr_win32 routines as
> well, __gthr_win32_create just happens to be the first symbol it cannot
> find.
> 
> Is there a way to fix this issue?

How did you configure the compiler and what version of MinGW64 do you use?

-- 
Eric Botcazou




  1   2   3   4   5   6   7   8   9   10   >