[pushed] c++: default mem-init of array [PR103946]

2022-01-07 Thread Jason Merrill via Gcc-patches
In the patch for PR92385 I added asserts to see if we tried to make a
vec_init of a vec_init, but didn't see any in regression testing.  This
testcase is one case, which seems reasonable: we create a VEC_INIT_EXPR for
the aggregate initializer, and then again to express the actual
initialization of the member.  We already do similar collapsing of
TARGET_EXPR.  So let's just remove the asserts.

PR c++/103946

gcc/cp/ChangeLog:

* init.c (build_vec_init): Remove assert.
* tree.c (build_vec_init_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/nsdmi-array1.C: New test.
---
 gcc/cp/init.c | 5 +
 gcc/cp/tree.c | 5 +
 gcc/testsuite/g++.dg/cpp0x/nsdmi-array1.C | 6 ++
 3 files changed, 8 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-array1.C

diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 6226812b470..ccc4f5ece08 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -4369,10 +4369,7 @@ build_vec_init (tree base, tree maxindex, tree init,
 init = TARGET_EXPR_INITIAL (init);
 
   if (init && TREE_CODE (init) == VEC_INIT_EXPR)
-{
-  gcc_checking_assert (false);
-  init = VEC_INIT_EXPR_INIT (init);
-}
+init = VEC_INIT_EXPR_INIT (init);
 
   bool direct_init = false;
   if (from_array && init && BRACE_ENCLOSED_INITIALIZER_P (init)
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 4c1135ba386..d0c6490e42f 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -787,10 +787,7 @@ tree
 build_vec_init_expr (tree type, tree init, tsubst_flags_t complain)
 {
   if (init && TREE_CODE (init) == VEC_INIT_EXPR)
-{
-  gcc_checking_assert (false);
-  return init;
-}
+return init;
 
   tree elt_init;
   if (init && TREE_CODE (init) == CONSTRUCTOR
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-array1.C 
b/gcc/testsuite/g++.dg/cpp0x/nsdmi-array1.C
new file mode 100644
index 000..1ab14359b56
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-array1.C
@@ -0,0 +1,6 @@
+// PR c++/103946
+// { dg-do compile { target c++11 } }
+
+struct s1 {  s1(); };
+class s2 { s1 f1[2]{}; };
+s2 a;

base-commit: 75047f79550fd10a8f86f5c72deab10cde77
-- 
2.27.0



Re: [PATCH] c++, match.pd: Evaluate in constant evaluation comparisons like + 12 == + 24 [PR89074]

2022-01-07 Thread Jason Merrill via Gcc-patches

On 1/7/22 07:06, Jakub Jelinek wrote:

Hi!

The match.pd address_comparison simplification can only handle
ADDR_EXPR comparisons possibly converted to some other type (I wonder
if we shouldn't restrict it in address_compare to casts to pointer
types or pointer-sized integer types, I think we shouldn't optimize
(short) () == (short) () because we really don't know whether
it will be true or false).  On GIMPLE, most of pointer to pointer
casts are useless and optimized away and further we have in
gimple_fold_stmt_to_constant_1 an optimization that folds
 p+ const_int
into
_REF[..., off]
On GENERIC, we don't do that and e.g. for constant evaluation it
could be pretty harmful if e.g. such pointers are dereferenced, because
it can lose what exact field it was starting with etc., all it knows
is the base and offset, type and alias set.
Instead of teaching the match.pd address_compare about 3 extra variants
where one or both compared operands are pointer_plus, this patch attempts
to fold operands of comparisons similarly to gimple_fold_stmt_to_constant_1
before calling fold_binary on it.
There is another thing though, while we do have (x p+ y) p+ z to
x p+ (y + z) simplification which works on GIMPLE well because of the
useless pointer conversions, on GENERIC we can have pointer casts in between
and at that point we can end up with large expressions like
((type3) (((type2) ((type1) ( + 2) + 2) + 2) + 2))
etc.  Pointer-plus doesn't really care what exact pointer type it has as
long as it is a pointer, so the following match.pd simplification for
GENERIC only (it is useless for GIMPLE) also moves the cast so that nested
p+ can be simplified.

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


LGTM.


Note, I've noticed we don't really diagnose going out of bounds with
pointer_plus (unlike e.g. with ARRAY_REF) during constant evaluation, I
think another patch for cxx_eval_binary_expression with POINTER_PLUS will be
needed.  But it isn't clear to me what exactly it should do in case of
subobjects.  If we start with address of a whole var, (), I guess we
should diagnose if the pointer_plus gets before start of the var (i.e.
"negative") or 1 byte past the end of the var, but what if we start with
 or [3] ?  For , shall we diagnose out of
bounds of field (except perhaps flexible members? or the whole var?

The field.  And a flexible member has unknown bounds.


For ARRAY_REFs, I assume we must at least strip all the outer ARRAY_REFs
and so start with  too, right?


A strict reading suggests that we should complain about going outside 
the bounds of the inner array, but flattening multidimensional arrays as 
you suggest seems reasonable as well.



2022-01-07  Jakub Jelinek  

PR c++/89074
gcc/
* match.pd ((ptr) (x p+ y) p+ z -> (ptr) (x p+ (y + z))): New GENERIC
simplification.
gcc/cp/
* constexpr.c (cxx_maybe_fold_addr_pointer_plus): New function.
(cxx_eval_binary_expression): Use it.
gcc/testsuite/
* g++.dg/cpp1y/constexpr-89074-2.C: New test.
* g++.dg/cpp1z/constexpr-89074-1.C: New test.

--- gcc/match.pd.jj 2022-01-05 20:30:08.768806236 +0100
+++ gcc/match.pd2022-01-06 19:59:53.596114417 +0100
@@ -2143,6 +2143,11 @@ (define_operator_list SYNC_FETCH_AND_AND
  (simplify
(pointer_plus (pointer_plus:s @0 @1) @3)
(pointer_plus @0 (plus @1 @3)))
+#if GENERIC
+(simplify
+  (pointer_plus (convert:s (pointer_plus:s @0 @1)) @3)
+  (convert:type (pointer_plus @0 (plus @1 @3
+#endif
  
  /* Pattern match

   tem1 = (long) ptr1;
--- gcc/cp/constexpr.c.jj   2022-01-03 10:40:48.403063535 +0100
+++ gcc/cp/constexpr.c  2022-01-06 20:47:44.596623219 +0100
@@ -3288,6 +3288,38 @@ cxx_fold_pointer_plus_expression (const
return NULL_TREE;
  }
  
+/* Try to fold expressions like

+   (struct S *) ([0].D.2378 + 12)
+   into
+ [(void *) + 12B]
+   This is something normally done by gimple_fold_stmt_to_constant_1
+   on GIMPLE, but is undesirable on GENERIC if we are e.g. going to
+   dereference the address because some details are lost.
+   For pointer comparisons we want such folding though so that
+   match.pd address_compare optimization works.  */
+
+static tree
+cxx_maybe_fold_addr_pointer_plus (tree t)
+{
+  while (CONVERT_EXPR_P (t)
+&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0
+t = TREE_OPERAND (t, 0);
+  if (TREE_CODE (t) != POINTER_PLUS_EXPR)
+return NULL_TREE;
+  tree op0 = TREE_OPERAND (t, 0);
+  tree op1 = TREE_OPERAND (t, 1);
+  if (TREE_CODE (op1) != INTEGER_CST)
+return NULL_TREE;
+  while (CONVERT_EXPR_P (op0)
+&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0
+op0 = TREE_OPERAND (op0, 0);
+  if (TREE_CODE (op0) != ADDR_EXPR)
+return NULL_TREE;
+  op1 = fold_convert (ptr_type_node, op1);
+  tree r = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)), op0, op1);
+  return build1_loc (EXPR_LOCATION (t), ADDR_EXPR, TREE_TYPE (op0), r);
+}
+
  /* Subroutine of 

[pushed] c++: destroying delete, throw in new-expr [PR100588]

2022-01-07 Thread Jason Merrill via Gcc-patches
The standard says that a destroying operator delete is preferred, but that
only applies to the delete-expression, not the cleanup if a new-expression
initialization throws.  As a result of this patch, several of the destroying
delete tests don't get EH cleanups, but I'm turning off the warning in cases
where the initialization can't throw anyway.

It's unclear what should happen if the class does not declare a non-deleting
operator delete; a proposal in CWG was to call the global delete, which
makes sense to me if the class doesn't declare its own operator new.  If it
does, we warn and don't call any deallocation function if initialization
throws.

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

PR c++/100588

gcc/cp/ChangeLog:

* call.c (build_op_delete_call): Ignore destroying delete
if alloc_fn.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/destroying-delete6.C: New test.
---
 gcc/cp/call.c | 31 ++--
 .../g++.dg/cpp2a/destroying-delete5.C |  4 +--
 .../g++.dg/cpp2a/destroying-delete6.C | 36 +++
 3 files changed, 67 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 7f7ee88deed..44fc6d0f695 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7267,6 +7267,8 @@ build_op_delete_call (enum tree_code code, tree addr, 
tree size,
   tree oaddr = addr;
   addr = cp_convert (ptr_type_node, addr, complain);
 
+  tree excluded_destroying = NULL_TREE;
+
   if (placement)
 {
   /* "A declaration of a placement deallocation function matches the
@@ -7352,6 +7354,15 @@ build_op_delete_call (enum tree_code code, tree addr, 
tree size,
dealloc_info di_elt;
if (usual_deallocation_fn_p (elt, _elt))
  {
+   /* If we're called for an EH cleanup in a new-expression, we can't
+  use a destroying delete; the exception was thrown before the
+  object was constructed.  */
+   if (alloc_fn && di_elt.destroying)
+ {
+   excluded_destroying = elt;
+   continue;
+ }
+
if (!fn)
  {
fn = elt;
@@ -7499,6 +7510,14 @@ build_op_delete_call (enum tree_code code, tree addr, 
tree size,
   return ret;
 }
 
+  /* If there's only a destroying delete that we can't use because the
+ object isn't constructed yet, and we used global new, use global
+ delete as well.  */
+  if (excluded_destroying
+  && DECL_NAMESPACE_SCOPE_P (alloc_fn))
+return build_op_delete_call (code, addr, size, true, placement,
+alloc_fn, complain);
+
   /* [expr.new]
 
  If no unambiguous matching deallocation function can be found,
@@ -7508,8 +7527,16 @@ build_op_delete_call (enum tree_code code, tree addr, 
tree size,
 {
   if ((complain & tf_warning)
  && !placement)
-   warning (0, "no corresponding deallocation function for %qD",
-alloc_fn);
+   {
+ bool w = warning (0,
+   "no corresponding deallocation function for %qD",
+   alloc_fn);
+ if (w && excluded_destroying)
+   inform (DECL_SOURCE_LOCATION (excluded_destroying), "destroying "
+   "delete %qD cannot be used to release the allocated memory"
+   " if the initialization throws because the object is not "
+   "constructed yet", excluded_destroying);
+   }
   return NULL_TREE;
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C 
b/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C
index 553c964b9e9..6113d7f3d9e 100644
--- a/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C
+++ b/gcc/testsuite/g++.dg/cpp2a/destroying-delete5.C
@@ -18,7 +18,7 @@ void * Expression::operator new(std::size_t sz)
 
 int i;
 
-void Expression::operator delete(Expression *p, std::destroying_delete_t)
+void Expression::operator delete(Expression *p, std::destroying_delete_t) // { 
dg-message "destroying delete" }
 {
   Expression * e = p;
   ::i = e->i;
@@ -28,7 +28,7 @@ void Expression::operator delete(Expression *p, 
std::destroying_delete_t)
 
 int main()
 {
-  auto p = new Expression();
+  auto p = new Expression();   // { dg-warning "no corresponding dealloc" }
   p->i = 1;
   delete p;
   if (i != 1)
diff --git a/gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C 
b/gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C
new file mode 100644
index 000..be783738082
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/destroying-delete6.C
@@ -0,0 +1,36 @@
+// PR c++/100588
+// { dg-do run { target c++20 } }
+
+extern "C" void abort ();
+extern "C" int puts (const char *);
+#include 
+
+#ifndef DEBUG
+#define puts(S)
+#endif
+
+class A {
+ public:
+  A() { throw 42; }
+  ~A() { puts("A::~A"); }
+
+  void operator delete(void* p) {
+puts("regular 

[PATCH 2/2]: C N2653 char8_t: New tests​

2022-01-07 Thread Tom Honermann via Gcc-patches
This patch provides new tests for the core language and compiler 
dependent library changes proposed in WG14 N2653 [1] for C2x.


Tested on Linux x86_64.

gcc/testsuite/ChangeLog:

2021-05-31  Tom Honermann  

* gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c: New test.
* gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c: New test.
* gcc.dg/c2x-predefined-macros.c: New test.
* gcc.dg/c2x-utf8str-type.c: New test.
* gcc.dg/c2x-utf8str.c: New test.
* gcc.dg/gnu2x-predefined-macros.c: New test.
* gcc.dg/gnu2x-utf8str-type.c: New test.
* gcc.dg/gnu2x-utf8str.c: New test.

Tom.

[1]: WG14 N2653
 "char8_t: A type for UTF-8 characters and strings (Revision 1)"
 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm
commit f4eee2bf403b62714d1ccb4542b8c85dc552a411
Author: Tom Honermann 
Date:   Sun Jan 2 00:26:17 2022 -0500

N2653 char8_t for C: New tests

This change provides new tests for the core language and compiler
dependent library changes proposed in WG14 N2653 for C.

diff --git a/gcc/testsuite/gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c b/gcc/testsuite/gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c
new file mode 100644
index 000..37ea4c8926c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/atomic/c2x-stdatomic-lockfree-char8_t.c
@@ -0,0 +1,42 @@
+/* Test atomic_is_lock_free for char8_t.  */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -D_ISOC2X_SOURCE -pedantic-errors" } */
+
+#include 
+#include 
+
+extern void abort (void);
+
+_Atomic __CHAR8_TYPE__ ac8a;
+atomic_char8_t ac8t;
+
+#define CHECK_TYPE(MACRO, V1, V2)		\
+  do		\
+{		\
+  int r1 = MACRO;\
+  int r2 = atomic_is_lock_free ();	\
+  int r3 = atomic_is_lock_free ();	\
+  if (r1 != 0 && r1 != 1 && r1 != 2)	\
+	abort ();\
+  if (r2 != 0 && r2 != 1)			\
+	abort ();\
+  if (r3 != 0 && r3 != 1)			\
+	abort ();\
+  if (r1 == 2 && r2 != 1)			\
+	abort ();\
+  if (r1 == 2 && r3 != 1)			\
+	abort ();\
+  if (r1 == 0 && r2 != 0)			\
+	abort ();\
+  if (r1 == 0 && r3 != 0)			\
+	abort ();\
+}		\
+  while (0)
+
+int
+main ()
+{
+  CHECK_TYPE (ATOMIC_CHAR8_T_LOCK_FREE, ac8a, ac8t);
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c b/gcc/testsuite/gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c
new file mode 100644
index 000..a017b134817
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/atomic/gnu2x-stdatomic-lockfree-char8_t.c
@@ -0,0 +1,5 @@
+/* Test atomic_is_lock_free for char8_t with -std=gnu2x.  */
+/* { dg-do run } */
+/* { dg-options "-std=gnu2x -D_GNU_SOURCE -pedantic-errors" } */
+
+#include "c2x-stdatomic-lockfree-char8_t.c"
diff --git a/gcc/testsuite/gcc.dg/c2x-predefined-macros.c b/gcc/testsuite/gcc.dg/c2x-predefined-macros.c
new file mode 100644
index 000..c88e51b54c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-predefined-macros.c
@@ -0,0 +1,11 @@
+/* Test C2x predefined macros.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x" } */
+
+#if !defined(__CHAR8_TYPE__)
+# error __CHAR8_TYPE__ is not defined!
+#endif
+
+#if !defined(__GCC_ATOMIC_CHAR8_T_LOCK_FREE)
+# error __GCC_ATOMIC_CHAR8_T_LOCK_FREE is not defined!
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-utf8str-type.c b/gcc/testsuite/gcc.dg/c2x-utf8str-type.c
new file mode 100644
index 000..76559c0b19b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-utf8str-type.c
@@ -0,0 +1,6 @@
+/* Test C2x UTF-8 string literal type.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x" } */
+
+_Static_assert (_Generic (u8"text", char*: 1, unsigned char*: 2) == 2, "UTF-8 string literals have an unexpected type");
+_Static_assert (_Generic (u8"x"[0], char:  1, unsigned char:  2) == 2, "UTF-8 string literal elements have an unexpected type");
diff --git a/gcc/testsuite/gcc.dg/c2x-utf8str.c b/gcc/testsuite/gcc.dg/c2x-utf8str.c
new file mode 100644
index 000..712482c6569
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-utf8str.c
@@ -0,0 +1,34 @@
+/* Test initialization by UTF-8 string literal in C2x.  */
+/* { dg-do compile } */
+/* { dg-require-effective-target wchar } */
+/* { dg-options "-std=c2x" } */
+
+typedef __CHAR8_TYPE__	char8_t;
+typedef __CHAR16_TYPE__	char16_t;
+typedef __CHAR32_TYPE__ char32_t;
+typedef __WCHAR_TYPE__	wchar_t;
+
+/* Test that char, signed char, unsigned char, and char8_t arrays can be
+   initialized by a UTF-8 string literal.  */
+const char cbuf1[] = u8"text";
+const char cbuf2[] = { u8"text" };
+const signed char scbuf1[] = u8"text";
+const signed char scbuf2[] = { u8"text" };
+const unsigned char ucbuf1[] = u8"text";
+const unsigned char ucbuf2[] = { u8"text" };
+const char8_t c8buf1[] = u8"text";
+const char8_t c8buf2[] = { u8"text" };
+
+/* Test that a diagnostic is issued for attempted initialization of
+   other character types by a UTF-8 string literal.  */
+const char16_t c16buf1[] = u8"text";		/* { dg-error "from 

[PATCH 1/2]: C N2653 char8_t: Language support

2022-01-07 Thread Tom Honermann via Gcc-patches
This patch implements the core language and compiler dependent library 
changes proposed in WG14 N2653 [1] for C2x. The changes include:

- Change of type for UTF-8 string literals from array of char to array
  of char8_t (unsigned char) when targeting C2x.
- A new atomic_char8_t typedef.
- A new ATOMIC_CHAR8_T_LOCK_FREE macro defined in terms of the existing
  __GCC_ATOMIC_CHAR8_T_LOCK_FREE predefined macro.

Tested on Linux x86_64.

gcc/ChangeLog:

2022-01-07  Tom Honermann  

* ginclude/stdatomic.h (atomic_char8_t,
ATOMIC_CHAR8_T_LOCK_FREE): New typedef and macro.

gcc/c/ChangeLog:

2022-01-07  Tom Honermann  

* c-parser.c (c_parser_string_literal): Use char8_t as the type
of CPP_UTF8STRING when char8_t support is enabled.
* c-typeck.c (digest_init): Allow initialization of an array
of character type by a string literal with type array of
char8_t.

gcc/c-family/ChangeLog:

2022-01-07  Tom Honermann  

* c-lex.c (lex_string, lex_charconst): Use char8_t as the type
of CPP_UTF8CHAR and CPP_UTF8STRING when char8_t support is
enabled.
* c-opts.c (c_common_post_options): Set flag_char8_t if
targeting C2x.

Tom.

[1]: WG14 N2653
 "char8_t: A type for UTF-8 characters and strings (Revision 1)"
 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm
commit c041cce5d262908349be3f1f2e361c824db15845
Author: Tom Honermann 
Date:   Sat Jan 1 18:10:41 2022 -0500

N2653 char8_t for C: Language support

This patch implements the core language and compiler dependent library
changes proposed in WG14 N2653 for C2X.  The changes include:
- Change of type for UTF-8 string literals from array of const char to
  array of const char8_t (unsigned char).
- A new atomic_char8_t typedef.
- A new ATOMIC_CHAR8_T_LOCK_FREE macro defined in terms of the existing
  __GCC_ATOMIC_CHAR8_T_LOCK_FREE predefined macro.

diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index 2651331e683..0b3debbb9bd 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -1352,7 +1352,14 @@ lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
 	default:
 	case CPP_STRING:
 	case CPP_UTF8STRING:
-	  value = build_string (1, "");
+	  if (type == CPP_UTF8STRING && flag_char8_t)
+	{
+	  value = build_string (TYPE_PRECISION (char8_type_node)
+/ TYPE_PRECISION (char_type_node),
+"");  /* char8_t is 8 bits */
+	}
+	  else
+	value = build_string (1, "");
 	  break;
 	case CPP_STRING16:
 	  value = build_string (TYPE_PRECISION (char16_type_node)
@@ -1425,10 +1432,10 @@ lex_charconst (const cpp_token *token)
 type = char16_type_node;
   else if (token->type == CPP_UTF8CHAR)
 {
-  if (!c_dialect_cxx ())
-	type = unsigned_char_type_node;
-  else if (flag_char8_t)
+  if (flag_char8_t)
 type = char8_type_node;
+  else if (!c_dialect_cxx ())
+	type = unsigned_char_type_node;
   else
 type = char_type_node;
 }
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 4c20e44f5b5..bd96e1319ad 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -1060,9 +1060,9 @@ c_common_post_options (const char **pfilename)
   if (flag_sized_deallocation == -1)
 flag_sized_deallocation = (cxx_dialect >= cxx14);
 
-  /* char8_t support is new in C++20.  */
+  /* char8_t support is implicitly enabled in C++20 and C2x.  */
   if (flag_char8_t == -1)
-flag_char8_t = (cxx_dialect >= cxx20);
+flag_char8_t = (cxx_dialect >= cxx20) || flag_isoc2x;
 
   if (flag_extern_tls_init)
 {
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index b09ad307acd..4239633e295 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -7439,7 +7439,14 @@ c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
 	default:
 	case CPP_STRING:
 	case CPP_UTF8STRING:
-	  value = build_string (1, "");
+	  if (type == CPP_UTF8STRING && flag_char8_t)
+	{
+	  value = build_string (TYPE_PRECISION (char8_type_node)
+/ TYPE_PRECISION (char_type_node),
+"");  /* char8_t is 8 bits */
+	}
+	  else
+	value = build_string (1, "");
 	  break;
 	case CPP_STRING16:
 	  value = build_string (TYPE_PRECISION (char16_type_node)
@@ -7464,9 +7471,14 @@ c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
 {
 default:
 case CPP_STRING:
-case CPP_UTF8STRING:
   TREE_TYPE (value) = char_array_type_node;
   break;
+case CPP_UTF8STRING:
+  if (flag_char8_t)
+	TREE_TYPE (value) = char8_array_type_node;
+  else
+	TREE_TYPE (value) = char_array_type_node;
+  break;
 case CPP_STRING16:
   TREE_TYPE (value) = char16_array_type_node;
   break;
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 78a6c68aaa6..b4eeea545a9 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -8028,7 +8028,7 @@ digest_init (location_t init_loc, tree type, 

[PATCH 0/2]: C N2653 char8_t implementation

2022-01-07 Thread Tom Honermann via Gcc-patches
This series of patches implements the core language features for the 
WG14 N2653 [1] proposal to provide char8_t support in C. These changes 
are intended to align char8_t support in C with the support provided in 
C++20 via WG21 P0482R6 [2].


These patches addresses feedback provided in response to a previous 
submission [3][4].


These changes do not impact default gcc behavior. Per prior feedback by 
Joseph Myers, the existing -fchar8_t and -fno-char8_t options used to 
opt-in to or opt-out of char8_t support in C++ are NOT reused for C. 
Instead, the C related core language changes are enabled when targeting 
C2x. Note that N2653 has not yet been accepted by WG14 for C2x, but the 
patches enable these changes for C2x in order to avoid an additional 
language dialect flag (e.g., -fchar8_t).


Patch 1: Language support
Patch 2: New tests

Tom.

[1]: WG14 N2653
 "char8_t: A type for UTF-8 characters and strings (Revision 1)"
 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2653.htm

[2]: WG21 P0482R6
 "char8_t: A type for UTF-8 characters and strings (Revision 6)"
 https://wg21.link/p0482r6

[3]: [PATCH 0/3]: C N2653 char8_t implementation
 https://gcc.gnu.org/pipermail/gcc-patches/2021-June/572022.html

[4]: [PATCH 1/3]: C N2653 char8_t: Language support
 https://gcc.gnu.org/pipermail/gcc-patches/2021-June/572023.html


[PATCH] C++ P0482R6 char8_t: declare std::c8rtomb and std::mbrtoc8 if provided by the C library

2022-01-07 Thread Tom Honermann via Gcc-patches
This patch completes implementation of the C++20 proposal P0482R6 [1] by 
adding declarations of std::c8rtomb() and std::mbrtoc8() in  if 
provided by the C library in .


This patch addresses feedback provided in response to a previous patch 
submission [2].


Autoconf changes determine if the C library declares c8rtomb and mbrtoc8 
at global scope when uchar.h is included and compiled with either 
-fchar8_t or -std=c++20. New _GLIBCXX_USE_UCHAR_C8RTOMB_MBRTOC8_FCHAR8_T 
and _GLIBCXX_USE_UCHAR_C8RTOMB_MBRTOC8_CXX20 configuration macros 
reflect the probe results. The  header declares these functions 
in the std namespace only if available and the _GLIBCXX_USE_CHAR8_T 
configuration macro is defined (by default it is defined if the C++20 
__cpp_char8_t feature test macro is defined)


Patches to glibc to implement c8rtomb and mbrtoc8 have been submitted [3].

New tests validate the presence of these declarations. The tests pass 
trivially if the C library does not provide these functions. Otherwise 
they ensure that the functions are declared when  is included 
and either -fchar8_t or -std=c++20 is enabled.


Tested on Linux x86_64.

libstdc++-v3/ChangeLog:

2022-01-07  Tom Honermann  

* acinclude.m4 Define config macros if uchar.h provides
c8rtomb() and mbrtoc8().
* config.h.in: Re-generate.
* configure: Re-generate.
* include/c_compatibility/uchar.h: Declare ::c8rtomb and
::mbrtoc8.
* include/c_global/cuchar: Declare std::c8rtomb and
std::mbrtoc8.
* include/c_std/cuchar: Declare std::c8rtomb and std::mbrtoc8.
* testsuite/21_strings/headers/cuchar/functions_std_cxx20.cc:
New test.
* testsuite/21_strings/headers/cuchar/functions_std_fchar8_t.cc:
New test.

Tom.

[1]: WG21 P0482R6
 "char8_t: A type for UTF-8 characters and strings (Revision 6)"
 https://wg21.link/p0482r6

[2]: [PATCH] C++ P0482R6 char8_t: declare std::c8rtomb and std::mbrtoc8 
if provided by the C library

 https://gcc.gnu.org/pipermail/libstdc++/2021-June/052685.html

[3]: "C++20 P0482R6 and C2X N2653"
 [Patch 0/3]: 
https://sourceware.org/pipermail/libc-alpha/2022-January/135061.html
 [Patch 1/3]: 
https://sourceware.org/pipermail/libc-alpha/2022-January/135062.html
 [Patch 2/3]: 
https://sourceware.org/pipermail/libc-alpha/2022-January/135063.html
 [Patch 3/3]: 
https://sourceware.org/pipermail/libc-alpha/2022-January/135064.html


Tom.
commit 3d40bc9bf5c79343ea5a6cc355539542f4b56c9b
Author: Tom Honermann 
Date:   Sat Jan 1 17:26:31 2022 -0500

P0482R6 char8_t: declare std::c8rtomb and std::mbrtoc8 if provided by the C library.

This change completes implementation of the C++20 proposal P0482R6 by
adding declarations of std::c8rtomb() and std::mbrtoc8() if provided
by the C library.

Autoconf changes determine if the C library declares c8rtomb and mbrtoc8
at global scope when uchar.h is included and compiled with either -fchar8_t
or -std=c++20 enabled; new _GLIBCXX_USE_UCHAR_C8RTOMB_MBRTOC8_FCHAR8_T and
_GLIBCXX_USE_UCHAR_C8RTOMB_MBRTOC8_CXX20 configuration macros are defined
accordingly. The  header declares these functions in the std
namespace only if available and the _GLIBCXX_USE_CHAR8_T configuration
macro is defined (by default it is defined if the C++20 __cpp_char8_t
feature test macro is defined).

New tests validate the presence of these declarations. The tests pass
trivially if the C library does not provide these functions. Otherwise they
ensure that the functions are declared when  is included and
either -fchar8_t or -std=c++20 is enabled.

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 635168d7e25..85235005c7e 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2039,6 +2039,50 @@ AC_DEFUN([GLIBCXX_CHECK_UCHAR_H], [
 	  namespace std in .])
   fi
 
+  CXXFLAGS="$CXXFLAGS -fchar8_t"
+  if test x"$ac_has_uchar_h" = x"yes"; then
+AC_MSG_CHECKING([for c8rtomb and mbrtoc8 in  with -fchar8_t])
+AC_TRY_COMPILE([#include 
+		namespace test
+		{
+		  using ::c8rtomb;
+		  using ::mbrtoc8;
+		}
+		   ],
+		   [], [ac_uchar_c8rtomb_mbrtoc8_fchar8_t=yes],
+		   [ac_uchar_c8rtomb_mbrtoc8_fchar8_t=no])
+  else
+ac_uchar_c8rtomb_mbrtoc8_fchar8_t=no
+  fi
+  AC_MSG_RESULT($ac_uchar_c8rtomb_mbrtoc8_fchar8_t)
+  if test x"$ac_uchar_c8rtomb_mbrtoc8_fchar8_t" = x"yes"; then
+AC_DEFINE(_GLIBCXX_USE_UCHAR_C8RTOMB_MBRTOC8_FCHAR8_T, 1,
+	  [Define if c8rtomb and mbrtoc8 functions in  should be
+	  imported into namespace std in  for -fchar8_t.])
+  fi
+
+  CXXFLAGS="$CXXFLAGS -std=c++20"
+  if test x"$ac_has_uchar_h" = x"yes"; then
+AC_MSG_CHECKING([for c8rtomb and mbrtoc8 in  with -std=c++20])
+AC_TRY_COMPILE([#include 
+		namespace test
+		{
+		  using ::c8rtomb;
+		  using ::mbrtoc8;
+		}
+		   ],
+		   [], 

[PATCH] PR 102935, Fix pr101384-1.c code generation test.

2022-01-07 Thread Michael Meissner via Gcc-patches
Fix pr101384-1.c code generation test.

Add support for the compiler using XXSPLTIB reg,255 to load all 1's into a
register on power9 and above instead of using VSPLTI{B,H,W} reg,-1.

gcc/testsuite/
2022-01-07  Michael Meissner  

PR testsuite/102935
* gcc.target/powerpc/pr101384-1.c: Update insn regexp for power9
and power10.
---
 gcc/testsuite/gcc.target/powerpc/pr101384-1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.target/powerpc/pr101384-1.c 
b/gcc/testsuite/gcc.target/powerpc/pr101384-1.c
index 627d7d76721..41cf84bf8bc 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr101384-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr101384-1.c
@@ -2,7 +2,7 @@
 /* { dg-do compile { target le } } */
 /* { dg-options "-O2 -maltivec" } */
 /* { dg-require-effective-target powerpc_altivec_ok } */
-/* { dg-final { scan-assembler-times {\mvspltis[whb] [^\n\r]*,-1\M} 9 } } */
+/* { dg-final { scan-assembler-times {\mvspltis[whb] 
[^\n\r]*,-1\M|\mxxspltib[^\n\r]*,255\M} 9 } } */
 /* { dg-final { scan-assembler-times {\mvslw\M} 3 } } */
 /* { dg-final { scan-assembler-times {\mvslh\M} 3 } } */
 /* { dg-final { scan-assembler-times {\mvslb\M} 3 } } */
-- 
2.33.1


-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: meiss...@linux.ibm.com


[committed] analyzer: add logging of aliasing

2022-01-07 Thread David Malcolm via Gcc-patches
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as 11a2ff8d981110e1562caf7d98e41c1ff2e76056.

gcc/analyzer/ChangeLog:
* engine.cc (impl_run_checkers): Pass logger to engine ctor.
* region-model-manager.cc
(region_model_manager::region_model_manager): Add logger param and
use it to initialize m_logger.
* region-model.cc (engine::engine): New.
* region-model.h (region_model_manager::region_model_manager):
Add logger param.
(region_model_manager::get_logger): New.
(region_model_manager::m_logger): New field.
(engine::engine): New.
* store.cc (store_manager::get_logger): New.
(store::set_value): Log scope.  Log when marking a cluster as
unknown due to possible aliasing.
* store.h (store_manager::get_logger): New decl.
---
 gcc/analyzer/engine.cc   |  2 +-
 gcc/analyzer/region-model-manager.cc |  5 +++--
 gcc/analyzer/region-model.cc |  7 +++
 gcc/analyzer/region-model.h  |  7 ++-
 gcc/analyzer/store.cc| 21 +
 gcc/analyzer/store.h |  2 ++
 6 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 0d456a14639..346b65973b2 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -5329,7 +5329,7 @@ impl_run_checkers (logger *logger)
   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
 node->get_untransformed_body ();
 
-  engine eng;
+  engine eng (logger);
 
   /* Create the supergraph.  */
   supergraph sg (logger);
diff --git a/gcc/analyzer/region-model-manager.cc 
b/gcc/analyzer/region-model-manager.cc
index 19e1a93b89e..998bbe7858c 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -66,8 +66,9 @@ namespace ana {
 
 /* region_model_manager's ctor.  */
 
-region_model_manager::region_model_manager ()
-: m_next_region_id (0),
+region_model_manager::region_model_manager (logger *logger)
+: m_logger (logger),
+  m_next_region_id (0),
   m_root_region (alloc_region_id ()),
   m_stack_region (alloc_region_id (), _root_region),
   m_heap_region (alloc_region_id (), _root_region),
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index cb86d79c99d..8708a91551d 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -3965,6 +3965,13 @@ rejected_ranges_constraint::dump_to_pp (pretty_printer 
*pp) const
 
 /* class engine.  */
 
+/* engine's ctor.  */
+
+engine::engine (logger *logger)
+: m_mgr (logger)
+{
+}
+
 /* Dump the managed objects by class to LOGGER, and the per-class totals.  */
 
 void
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 669f1c748ce..b1fa4fc82af 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -240,7 +240,7 @@ namespace ana {
 class region_model_manager
 {
 public:
-  region_model_manager ();
+  region_model_manager (logger *logger = NULL);
   ~region_model_manager ();
 
   /* svalue consolidation.  */
@@ -335,6 +335,8 @@ public:
   void enable_complexity_check (void) { m_check_complexity = true; }
   void disable_complexity_check (void) { m_check_complexity = false; }
 
+  logger *get_logger () const { return m_logger; }
+
 private:
   bool too_complex_p (const complexity ) const;
   bool reject_if_too_complex (svalue *sval);
@@ -358,6 +360,8 @@ private:
   const svalue *maybe_fold_asm_output_svalue (tree type,
  const vec 
);
 
+  logger *m_logger;
+
   unsigned m_next_region_id;
   root_region m_root_region;
   stack_region m_stack_region;
@@ -1080,6 +1084,7 @@ private:
 class engine
 {
 public:
+  engine (logger *logger = NULL);
   region_model_manager *get_model_manager () { return _mgr; }
 
   void log_stats (logger *logger) const;
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 3f91b6107a9..ade6dec624d 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -1987,6 +1987,12 @@ binding_cluster::maybe_get_simple_value (store_manager 
*mgr) const
 
 /* class store_manager.  */
 
+logger *
+store_manager::get_logger () const
+{
+  return m_mgr->get_logger ();
+}
+
 /* binding consolidation.  */
 
 const concrete_binding *
@@ -2353,6 +2359,9 @@ store::set_value (store_manager *mgr, const region 
*lhs_reg,
  const svalue *rhs_sval,
  uncertainty_t *uncertainty)
 {
+  logger *logger = mgr->get_logger ();
+  LOG_SCOPE (logger);
+
   remove_overlapping_bindings (mgr, lhs_reg);
 
   rhs_sval = simplify_for_binding (rhs_sval);
@@ -2405,6 +2414,18 @@ store::set_value (store_manager *mgr, const region 
*lhs_reg,
  gcc_unreachable ();
 
case tristate::TS_UNKNOWN:
+ if (logger)
+   {
+ pretty_printer *pp = logger->get_printer ();
+ logger->start_log_line ();
+ 

[committed] analyzer: implement __analyzer_dump_escaped

2022-01-07 Thread David Malcolm via Gcc-patches
PR analyzer/103546 seems to involve an issue in how the analyzer
tracks which decls have escaped, so this patch adds a way to directly
test this from DejaGnu.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r12-6377-g4409152a4acaec5b58a93996088d0df9aaa779b8.

gcc/analyzer/ChangeLog:
* region-model-impl-calls.cc (cmp_decls): New.
(cmp_decls_ptr_ptr): New.
(region_model::impl_call_analyzer_dump_escaped): New.
* region-model.cc (region_model::on_stmt_pre): Handle
__analyzer_dump_escaped.
* region-model.h (region_model::impl_call_analyzer_dump_escaped):
New decl.
* store.h (binding_cluster::get_base_region): New accessor.

gcc/ChangeLog:
* doc/analyzer.texi
(Special Functions for Debugging the Analyzer): Document
__analyzer_dump_escaped.

gcc/testsuite/ChangeLog:
* gcc.dg/analyzer/analyzer-decls.h (__analyzer_dump_escaped): New
decl.
* gcc.dg/analyzer/escaping-1.c: New test.
---
 gcc/analyzer/region-model-impl-calls.cc   | 69 +++
 gcc/analyzer/region-model.cc  |  2 +
 gcc/analyzer/region-model.h   |  1 +
 gcc/analyzer/store.h  |  2 +
 gcc/doc/analyzer.texi |  8 +++
 .../gcc.dg/analyzer/analyzer-decls.h  |  3 +
 gcc/testsuite/gcc.dg/analyzer/escaping-1.c| 27 
 7 files changed, 112 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/escaping-1.c

diff --git a/gcc/analyzer/region-model-impl-calls.cc 
b/gcc/analyzer/region-model-impl-calls.cc
index 9063acd6be5..c20058ec778 100644
--- a/gcc/analyzer/region-model-impl-calls.cc
+++ b/gcc/analyzer/region-model-impl-calls.cc
@@ -264,6 +264,75 @@ region_model::impl_call_analyzer_dump_capacity (const 
gcall *call,
   warning_at (call->location, 0, "capacity: %qs", desc.m_buffer);
 }
 
+/* Compare D1 and D2 using their names, and then IDs to order them.  */
+
+static int
+cmp_decls (tree d1, tree d2)
+{
+  gcc_assert (DECL_P (d1));
+  gcc_assert (DECL_P (d2));
+  if (DECL_NAME (d1) && DECL_NAME (d2))
+if (int cmp = strcmp (IDENTIFIER_POINTER (DECL_NAME (d1)),
+ IDENTIFIER_POINTER (DECL_NAME (d2
+  return cmp;
+  return (int)DECL_UID (d1) - (int)DECL_UID (d2);
+}
+
+/* Comparator for use by vec::qsort,
+   using their names, and then IDs to order them.  */
+
+static int
+cmp_decls_ptr_ptr (const void *p1, const void *p2)
+{
+  tree const *d1 = (tree const *)p1;
+  tree const *d2 = (tree const *)p2;
+
+  return cmp_decls (*d1, *d2);
+}
+
+/* Handle a call to "__analyzer_dump_escaped".
+
+   Emit a warning giving the number of decls that have escaped, followed
+   by a comma-separated list of their names, in alphabetical order.
+
+   This is for use when debugging, and may be of use in DejaGnu tests.  */
+
+void
+region_model::impl_call_analyzer_dump_escaped (const gcall *call)
+{
+  auto_vec escaped_decls;
+  for (auto iter : m_store)
+{
+  const binding_cluster *c = iter.second;
+  if (!c->escaped_p ())
+   continue;
+  if (tree decl = c->get_base_region ()->maybe_get_decl ())
+   escaped_decls.safe_push (decl);
+}
+
+  /* Sort them into deterministic order; alphabetical is
+ probably most user-friendly.  */
+  escaped_decls.qsort (cmp_decls_ptr_ptr);
+
+  pretty_printer pp;
+  pp_format_decoder () = default_tree_printer;
+  pp_show_color () = pp_show_color (global_dc->printer);
+  bool first = true;
+  for (auto iter : escaped_decls)
+{
+  if (first)
+   first = false;
+  else
+   pp_string (, ", ");
+  pp_printf (, "%qD", iter);
+}
+  /* Print the number to make it easier to write DejaGnu tests for
+ the "nothing has escaped" case.  */
+  warning_at (call->location, 0, "escaped: %i: %s",
+ escaped_decls.length (),
+ pp_formatted_text ());
+}
+
 /* Handle a call to "__analyzer_eval" by evaluating the input
and dumping as a dummy warning, so that test cases can use
dg-warning to validate the result (and so unexpected warnings will
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index b7371948873..cb86d79c99d 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -999,6 +999,8 @@ region_model::on_stmt_pre (const gimple *stmt,
  impl_call_analyzer_describe (call, ctxt);
else if (is_special_named_call_p (call, "__analyzer_dump_capacity", 1))
  impl_call_analyzer_dump_capacity (call, ctxt);
+   else if (is_special_named_call_p (call, "__analyzer_dump_escaped", 0))
+ impl_call_analyzer_dump_escaped (call);
else if (is_special_named_call_p (call, "__analyzer_dump_path", 0))
  {
/* Handle the builtin "__analyzer_dump_path" by queuing a
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 8e35be1f180..669f1c748ce 100644
--- 

[committed] analyzer: add region::is_named_decl_p

2022-01-07 Thread David Malcolm via Gcc-patches
This patch adds a debug function that I've found handy when debugging
a problem with handling the decl yy_buffer_stack" in PR analyzer/103546.

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r12-6376-gc1b7d28a5987e74232b7f054849f8bd8ccc7e7de.

gcc/analyzer/ChangeLog:
* region.cc (region::is_named_decl_p): New.
* region.h (region::is_named_decl_p): New decl.

gcc/ChangeLog:
* doc/analyzer.texi (Other Debugging Techniques): Document
region::is_named_decl_p.
---
 gcc/analyzer/region.cc | 14 ++
 gcc/analyzer/region.h  |  2 ++
 gcc/doc/analyzer.texi  | 10 ++
 3 files changed, 26 insertions(+)

diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index befcaa495cd..161e7e1fb10 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -638,6 +638,20 @@ region::symbolic_for_unknown_ptr_p () const
   return false;
 }
 
+/* Return true if this is a region for a decl with name DECL_NAME.
+   Intended for use when debugging (for assertions and conditional
+   breakpoints).  */
+
+DEBUG_FUNCTION bool
+region::is_named_decl_p (const char *decl_name) const
+{
+  if (tree decl = maybe_get_decl ())
+if (DECL_NAME (decl)
+   && !strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), decl_name))
+  return true;
+  return false;
+}
+
 /* region's ctor.  */
 
 region::region (complexity c, unsigned id, const region *parent, tree type)
diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h
index fbb50a1817a..d97bbc1e3f1 100644
--- a/gcc/analyzer/region.h
+++ b/gcc/analyzer/region.h
@@ -189,6 +189,8 @@ public:
 
   const complexity _complexity () const { return m_complexity; }
 
+  bool is_named_decl_p (const char *decl_name) const;
+
  protected:
   region (complexity c, unsigned id, const region *parent, tree type);
 
diff --git a/gcc/doc/analyzer.texi b/gcc/doc/analyzer.texi
index 657798101c2..62faac44d7f 100644
--- a/gcc/doc/analyzer.texi
+++ b/gcc/doc/analyzer.texi
@@ -545,3 +545,13 @@ and the exploded graph in compressed JSON form.
 One approach when tracking down where a particular bogus state is
 introduced into the @code{exploded_graph} is to add custom code to
 @code{program_state::validate}.
+
+The debug function @code{region::is_named_decl_p} can be used when debugging,
+such as for assertions and conditional breakpoints.  For example, when
+tracking down a bug in handling a decl called @code{yy_buffer_stack}, I
+temporarily added a:
+@smallexample
+  gcc_assert (!m_base_region->is_named_decl_p ("yy_buffer_stack"));
+@end smallexample
+to @code{binding_cluster::mark_as_escaped} to trap a point where
+@code{yy_buffer_stack} was mistakenly being treated as having escaped.
-- 
2.26.3



Re: [Patch][V2]Enable -Wuninitialized + -ftrivial-auto-var-init for address taken variables

2022-01-07 Thread Qing Zhao via Gcc-patches


> On Jan 5, 2022, at 10:59 AM, Qing Zhao via Gcc-patches 
>  wrote:
> 
> Hi, Richard,
> 
> Thanks a lot for the review and questions.
> See my reply embedded below:
> 
> 
>> On Jan 5, 2022, at 4:33 AM, Richard Biener  
>> wrote:
>> 
>> On Thu, Dec 16, 2021 at 5:00 PM Qing Zhao  wrote:
>>> 
>>> Hi,
>>> 
>>> This is the 2nd version of the patch.
>>> The original patch is at:
>>> 
>>> https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586341.html
>>> 
>>> In addition to resolve the two issues mentioned in the original patch,
>>> This patch also can be used as a very good workaround for the issue in 
>>> PR103720
>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103720
>>> 
>>> And as I checked, the patch can fix all the bogus uninitialized warnings 
>>> when
>>> building kernel with -O2 + -ftrivial-auto-var-init=zero + -Wuninitialized.
>>> 
>>> So, this is a very important patch that need to be included into gcc12.
>>> 
>>> Compared to the 1st patch, the major changes are to resolve Martin’s 
>>> comments on
>>> tree-ssa-uninit.c
>>> 
>>> 1.  Add some meaningful temporaries to break the long expression to make it
>>>Readable. And also add comments to explain the purpose of the statement;
>>> 
>>> 2.  Resolve the memory leakage of the dynamically created string.
>>> 
>>> The patch has been bootstrapped and regressing tested on both x86 and 
>>> aarch64, no issues.
>>> Okay for commit?
>> 
>> tree decl_name
>> += build_string_literal (IDENTIFIER_LENGTH (DECL_NAME (decl)) + 1,
>> +   IDENTIFIER_POINTER (DECL_NAME (decl)));
>> 
>> you need to deal with DECL_NAME being NULL.
> 
> Okay. 
> Usually under what situation, the decl_name will be NULL?

Anyway, I made the following change in gimplify.c to address this concern:

[opc@qinzhao-ol8u3-x86 gcc]$ git diff

diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index cc6b643312e..a9714c9f9c4 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -1764,9 +1764,12 @@ gimple_add_init_for_auto_var (tree decl,
 
   tree init_type_node
 = build_int_cst (integer_type_node, (int) init_type);
+  const char *decl_name_str = DECL_NAME (decl)
+ ? IDENTIFIER_POINTER (DECL_NAME (decl))
+ : "";
   tree decl_name
-= build_string_literal (IDENTIFIER_LENGTH (DECL_NAME (decl)) + 1,
-   IDENTIFIER_POINTER (DECL_NAME (decl)));
+= build_string_literal (strlen (decl_name_str) + 1,
+   decl_name_str);
 
Let me know if you see any issue with this solution.


> 
>> It's also a bit awkward
>> to build another
>> copy of all decl names :/  
> 
> Yes, this is awkward. But it might be unavoidable for address taken variables 
> since the original variable might be completely deleted by optimizations.
> See the details at:
> https://gcc.gnu.org/pipermail/gcc-patches/2021-August/577431.html
> 
> We had a previous discussion on this issue, and the idea of adding this 3rd 
> argument with the name of the variable was proposed by you at that time. -:)
> And I think that’s a good solution to this problem.
> 
> 
>> The changes in the uninit warning are also
>> quite ugly, refactoring
>> things to always pass down a name / location pair might improve that
>> (but I'd like to
>> understand the case to fix first).
> 
> I will try this idea to see whether it will work. 

Martin Sebor raised the similar concern and similar suggestions in the previous 
round of review, and I tried to pass the name string and use “%qs” consistently.
However, that didn’t work since there are some special cases that %qD handles 
specially other than %qs. There were multiple testing cases failed after the 
change.
In order to resolve the regression, we have to copy multiple details from the 
handling of “%D” to uninit warning.

Please see:

https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586814.html

For more details.

> 
>> 
>> + /* The LHS of the call is a temporary variable, we use it as a
>> +placeholder to record the information on whether the warning
>> +has been issued or not.  */
>> + repl_var = gimple_call_lhs (def_stmt);
>> 
>> this seems to be a change that can be done independently?
> 
> The major purpose of this “repl_var” is used to record the info whether the 
> warning has been issued for the variable or not, then avoid emitting it again 
> later.
> Since the original variable has been completely deleted by optimization, we 
> have to use this “repl_var” for a placeholder to record such info.
>> 
>> + /* Ignore the call to .DEFERRED_INIT that define the original
>> +var itself.  */
>> + if (is_gimple_assign (context))
>> +   {
>> + if (TREE_CODE (gimple_assign_lhs (context)) == VAR_DECL)
>> +   lhs_var = gimple_assign_lhs (context);
>> + else if (TREE_CODE (gimple_assign_lhs (context)) == SSA_NAME)
>> +   lhs_var = SSA_NAME_VAR 

[pushed] c++: check delete access with trivial init [PR20040]

2022-01-07 Thread Jason Merrill via Gcc-patches
Apparently we need to check the accessibility of the deallocation function
even if there is no initialization.

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

PR c++/20040

gcc/cp/ChangeLog:

* init.c (build_new_1): Also build pointer cleanup if
TYPE_GETS_DELETE.
* cp-tree.h (TYPE_GETS_VEC_DELETE): New.

gcc/testsuite/ChangeLog:

* g++.dg/init/delete4.C: New test.
---
 gcc/cp/cp-tree.h|   1 +
 gcc/cp/init.c   | 142 +++-
 gcc/testsuite/g++.dg/init/delete4.C |  14 +++
 3 files changed, 89 insertions(+), 68 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/init/delete4.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index e204182da97..f8225c18a48 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2395,6 +2395,7 @@ struct GTY(()) lang_type {
 /* Nonzero for _CLASSTYPE means that operator delete is defined.  */
 #define TYPE_GETS_DELETE(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->gets_delete)
 #define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1)
+#define TYPE_GETS_VEC_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 2)
 
 /* Nonzero if `new NODE[x]' should cause the allocation of extra
storage to indicate how many array elements are in use.  */
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index c932699ffa6..6226812b470 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -3316,6 +3316,12 @@ build_new_1 (vec **placement, tree type, 
tree nelts,
 ? TYPE_HAS_ARRAY_NEW_OPERATOR (elt_type)
 : TYPE_HAS_NEW_OPERATOR (elt_type));
 
+  bool member_delete_p = (!globally_qualified_p
+ && CLASS_TYPE_P (elt_type)
+ && (array_p
+ ? TYPE_GETS_VEC_DELETE (elt_type)
+ : TYPE_GETS_REG_DELETE (elt_type)));
+
   if (member_new_p)
 {
   /* Use a class-specific operator new.  */
@@ -3473,7 +3479,7 @@ build_new_1 (vec **placement, tree type, 
tree nelts,
 
   /* In the simple case, we can stop now.  */
   pointer_type = build_pointer_type (type);
-  if (!cookie_size && !is_initialized)
+  if (!cookie_size && !is_initialized && !member_delete_p)
 return build_nop (pointer_type, alloc_call);
 
   /* Store the result of the allocation call in a variable so that we can
@@ -3700,77 +3706,77 @@ build_new_1 (vec **placement, tree type, 
tree nelts,
 
   if (init_expr == error_mark_node)
return error_mark_node;
-
-  /* If any part of the object initialization terminates by throwing an
-exception and a suitable deallocation function can be found, the
-deallocation function is called to free the memory in which the
-object was being constructed, after which the exception continues
-to propagate in the context of the new-expression. If no
-unambiguous matching deallocation function can be found,
-propagating the exception does not cause the object's memory to be
-freed.  */
-  if (flag_exceptions)
-   {
- enum tree_code dcode = array_p ? VEC_DELETE_EXPR : DELETE_EXPR;
- tree cleanup;
-
- /* The Standard is unclear here, but the right thing to do
-is to use the same method for finding deallocation
-functions that we use for finding allocation functions.  */
- cleanup = (build_op_delete_call
-(dcode,
- alloc_node,
- size,
- globally_qualified_p,
- placement_allocation_fn_p ? alloc_call : NULL_TREE,
- alloc_fn,
- complain));
-
- if (cleanup && !processing_template_decl)
-   /* Ack!  First we allocate the memory.  Then we set our sentry
-  variable to true, and expand a cleanup that deletes the
-  memory if sentry is true.  Then we run the constructor, and
-  finally clear the sentry.
-
-  We need to do this because we allocate the space first, so
-  if there are any temporaries with cleanups in the
-  constructor args, we need this EH region to extend until
-  end of full-expression to preserve nesting.
-
-  We used to try to evaluate the args first to avoid this, but
-  since C++17 [expr.new] says that "The invocation of the
-  allocation function is sequenced before the evaluations of
-  expressions in the new-initializer."  */
-   {
- tree end, sentry, begin;
-
- begin = get_target_expr (boolean_true_node);
- CLEANUP_EH_ONLY (begin) = 1;
-
- sentry = TARGET_EXPR_SLOT (begin);
-
- /* CLEANUP is compiler-generated, so no diagnostics.  */
- suppress_warning (cleanup);
-
- TARGET_EXPR_CLEANUP (begin)
-   = build3 (COND_EXPR, void_type_node, sentry,
-

Re: [power-ieee128] OPEN CONV

2022-01-07 Thread Jakub Jelinek via Gcc-patches
On Fri, Jan 07, 2022 at 10:40:50PM +0100, Thomas Koenig wrote:
> One thing that one has to watch out for is a big-endian IBM long double
> file, so the byte swapping will have to be done before assigning
> the value.

I've tried to handle that right, i.e. on unformatted read with
byte-swapping and r16 <-> r17 conversions first do byte-swapping
and then r16 <-> r17 conversions, while for unformatted writes
first r16 <-> r17 conversions and then byte-swapping.

Jakub



Re: [power-ieee128] OPEN CONV

2022-01-07 Thread Thomas Koenig via Gcc-patches



On 07.01.22 20:52, Jakub Jelinek wrote:

Here is completely untested patch that implements something,
but doesn't implement the gcc option stuff, nor the CONVERT=
syntax to supply multiple conversion options nor done anything
about env var nor any testcases.

But it tries to have the native/swap/big/little choice orthogonal from
native/r16_ieee/r16_ibm with r16_ieee and r16_ibm only supported on
ppc64le-linux.

For INQUIRE it has the so far perhaps manageable set of possibilities
handled so that it uses string literals and doesn't have to construct
those strings at runtime (haven't studied how it would need to be done).

I'm afraid I don't know that stuff enough to move forward from this.


That looks like the direction to go.

I will take it from there and see if I can find some hours over the
weekend to work on something. Unfortunately, my daytime job will
kick in again on Monday :-)

One thing that one has to watch out for is a big-endian IBM long double
file, so the byte swapping will have to be done before assigning
the value.

Best regards

Thomas


Re: [power-ieee128] RFH: LTO broken

2022-01-07 Thread Thomas Koenig via Gcc-patches



Hi Jakub,


So, the following patch adds -fbuilding-libgfortran option and uses
it together with TARGET_GLIBC_M* checks to decide whether to use
libquadmath APIs (for the IEEE quad kind=16 if -fbuilding-libgfortran
and not glibc or glibc is older than 2.32) or glibc 2.32 APIs
(otherwise).  This way, libgfortran uses solely the libquadmath APIs
on glibc < 2.32 and __*ieee128 APIs on glibc 2.32, while user code
always uses the latter.

Ok for power-ieee128?


OK!

Best regards

Thomas


[PATCH] PR 103763, Fix fold-vec-splat-floatdouble on power10.

2022-01-07 Thread Michael Meissner via Gcc-patches
Fix fold-vec-splat-floatdouble testsuite failure on power10

When I added support for generating XXSPLTIDP on December 15th, 2021, I
missed updating the fold-vec-splat-floatdouble.c test to add to the regex
for the instructions generated.  This patch fixes that.

gcc/testsuite/
2022-01-07  Michael Meissner  

PR testsuite/103763
* gcc.target/powerpc/fold-vec-splat-floatdouble.c: Fix insn regex
on power10.
---
 .../gcc.target/powerpc/fold-vec-splat-floatdouble.c  | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c
index b95fa324633..01f1b0dadf3 100644
--- a/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-splat-floatdouble.c
@@ -21,12 +21,11 @@ vector double test_dc ()
 { const vector double y = { 3.0, 5.0 }; return vec_splat (y, 0b1); }
 
 /* If the source vector is a known constant, we will generate a load or 
possibly
-   XXSPLTIW.  */
-/* { dg-final { scan-assembler-times 
{\mlvx\M|\mlxvd2x\M|\mlxv\M|\mplxv\M|\mxxspltiw\M} 2 } } */
+   XXSPLTIW/XXSPLTIDP.  */
+/* { dg-final { scan-assembler-times 
{\mlvx\M|\mlxvd2x\M|\mlxv\M|\mplxv\M|\mxxspltiw\M|\mxxspltidp\M} 2 } } */
 
 /* For float types, we generate a splat.  */
 /* { dg-final { scan-assembler-times {\mvspltw\M|\mxxspltw\M} 3 } } */
 
 /* For double types, we will generate xxpermdi instructions.  */
 /* { dg-final { scan-assembler-times "xxpermdi" 2 } } */
-
-- 
2.33.1


-- 
Michael Meissner, IBM
PO Box 98, Ayer, Massachusetts, USA, 01432
email: meiss...@linux.ibm.com


Re: [Patch, fortran] PR103366 - [9/10/11/12 Regression] ICE in gfc_conv_gfc_desc_to_cfi_desc, at fortran/trans-expr.c:5647

2022-01-07 Thread Harald Anlauf via Gcc-patches

Hi Paul,

Am 07.01.22 um 14:42 schrieb Paul Richard Thomas via Fortran:

I doubt that this is a regression on 9-11 branches since the testcase
compiles correctly on each of my copies of these branches. IMHO it is
rather more likely to have been caused by
64f9623765da3306b0ab6a47997dc5d62c2ea261, which introduced this new form of
gfc_conv_gfc_desc_to_cfi_desc.

The patch is self-explanatory. OK for mainline?


I do not have a copy of F2017; but I can find your comment in the F2018
document.

OK with this change.

Thanks for the patch!

Harald


Paul

Fortran: Match unlimited polymorphic argument to assumed type [PR103366].

2022-01-07  Paul Thomas  

gcc/fortran
PR fortran/103366
* trans-expr.c (gfc_conv_gfc_desc_to_cfi_desc): Allow unlimited
polymorphic actual argument passed to assumed type formal.

gcc/testsuite/
PR fortran/103366
* gfortran.dg/pr103366.f90: New test.


Re: [PATCH] rs6000: Add optimizations for _mm_sad_epu8

2022-01-07 Thread David Edelsohn via Gcc-patches
On Fri, Jan 7, 2022 at 3:57 PM Paul A. Clarke  wrote:
>
> On Fri, Jan 07, 2022 at 02:40:51PM -0500, David Edelsohn via Gcc-patches 
> wrote:
> > +#ifdef __LITTLE_ENDIAN__
> > +  /* Sum across four integers with two integer results.  */
> > +  asm ("vsum2sws %0,%1,%2" : "=v" (result) : "v" (vsum), "v" (zero));
> > +  /* Note: vec_sum2s could be used here, but on little-endian, vector
> > + shifts are added that are not needed for this use-case.
> > + A vector shift to correctly position the 32-bit integer results
> > + (currently at [0] and [2]) to [1] and [3] would then need to be
> > + swapped back again since the desired results are two 64-bit
> > + integers ([1]|[0] and [3]|[2]).  Thus, no shift is performed.  */
> > +#else
> >/* Sum across four integers with two integer results.  */
> >result = vec_sum2s (vsum, (__vector signed int) zero);
> >
> > If little-endian adds shifts to correct for the position and
> > big-endian does not, why not use the inline asm without the shifts for
> > both?  It seems confusing to add the inline asm only for LE instead of
> > always using it with the appropriate comment.
> >
> > It's a good and valuable optimization for LE.  Fewer variants are less
> > fragile, easier to test and easier to maintain.  If you're going to go
> > to the trouble of using inline asm for LE, use it for both.
>
> BE (only) _does_ need a shift as seen on the next two lines after the
> code snippet above:
>   /* Sum across four integers with two integer results.  */
>   result = vec_sum2s (vsum, (__vector signed int) zero);
>   /* Rotate the sums into the correct position.  */
>   result = vec_sld (result, result, 6);
>
> So, when using {vec_sum2s;vec_sld}:
> - LE gets an implicit shift in vec_sum2s which just needs to be undone
>   by the vec_sld, and those shifts don't "cancel out" and get removed
>   by GCC.
> - BE does not get any implicit shifts, but needs one that comes from
>   vec_sld.
>
> Are you saying use the asm(vsum2sws) and then conditionally call
> vec_sld on BE only?
>
> I viewed this change as a temporary bandage unless and until GCC can
> remove the unnecessary swaps.  It seems like the preferred code is
> vec_sum2s/vec_sld, not the asm, but that currently is suboptimal for LE.

Nevermind.  I thought that these patches had not been reviewed.

Thanks, David


Re: [PATCH] rs6000: Add optimizations for _mm_sad_epu8

2022-01-07 Thread Paul A. Clarke via Gcc-patches
On Fri, Jan 07, 2022 at 02:40:51PM -0500, David Edelsohn via Gcc-patches wrote:
> +#ifdef __LITTLE_ENDIAN__
> +  /* Sum across four integers with two integer results.  */
> +  asm ("vsum2sws %0,%1,%2" : "=v" (result) : "v" (vsum), "v" (zero));
> +  /* Note: vec_sum2s could be used here, but on little-endian, vector
> + shifts are added that are not needed for this use-case.
> + A vector shift to correctly position the 32-bit integer results
> + (currently at [0] and [2]) to [1] and [3] would then need to be
> + swapped back again since the desired results are two 64-bit
> + integers ([1]|[0] and [3]|[2]).  Thus, no shift is performed.  */
> +#else
>/* Sum across four integers with two integer results.  */
>result = vec_sum2s (vsum, (__vector signed int) zero);
> 
> If little-endian adds shifts to correct for the position and
> big-endian does not, why not use the inline asm without the shifts for
> both?  It seems confusing to add the inline asm only for LE instead of
> always using it with the appropriate comment.
> 
> It's a good and valuable optimization for LE.  Fewer variants are less
> fragile, easier to test and easier to maintain.  If you're going to go
> to the trouble of using inline asm for LE, use it for both.

BE (only) _does_ need a shift as seen on the next two lines after the
code snippet above:
  /* Sum across four integers with two integer results.  */
  result = vec_sum2s (vsum, (__vector signed int) zero);
  /* Rotate the sums into the correct position.  */
  result = vec_sld (result, result, 6);

So, when using {vec_sum2s;vec_sld}:
- LE gets an implicit shift in vec_sum2s which just needs to be undone
  by the vec_sld, and those shifts don't "cancel out" and get removed
  by GCC.
- BE does not get any implicit shifts, but needs one that comes from
  vec_sld.

Are you saying use the asm(vsum2sws) and then conditionally call
vec_sld on BE only?

I viewed this change as a temporary bandage unless and until GCC can
remove the unnecessary swaps.  It seems like the preferred code is
vec_sum2s/vec_sld, not the asm, but that currently is suboptimal for LE.

PC


Re: [PATCH] rs6000: Add Power10 optimization for most _mm_movemask*

2022-01-07 Thread David Edelsohn via Gcc-patches
On Fri, Jan 7, 2022 at 3:35 PM Paul A. Clarke  wrote:
>
> On Fri, Jan 07, 2022 at 02:23:14PM -0500, David Edelsohn wrote:
> > > Power10 ISA added `vextract*` instructions which are realized in the
> > > `vec_extractm` instrinsic.
> > >
> > > Use `vec_extractm` for `_mm_movemask_ps`, `_mm_movemask_pd`, and
> > > `_mm_movemask_epi8` compatibility intrinsics, when `_ARCH_PWR10`.
> > >
> > > 2021-10-21  Paul A. Clarke  
> > >
> > > gcc
> > > * config/rs6000/xmmintrin.h (_mm_movemask_ps): Use vec_extractm
> > > when _ARCH_PWR10.
> > > * config/rs6000/emmintrin.h (_mm_movemask_pd): Likewise.
> > > (_mm_movemask_epi8): Likewise.
> > > ---
> > > Tested on Power10 powerpc64le-linux (compiled with and without
> > > `-mcpu=power10`).
> > >
> > > OK for trunk?
> >
> > This is okay modulo
> >
> > > + return vec_extractm ((__v16qu) __A);
> >
> > Should the above be __v16qi like x86?
>
> That would match x86 better, but we don't have a function signature
> for vec_extractm which accepts a signed type.

Okay, nevermind.  I thought that vec_extractm also allowed signed.

Thanks, David


Re: [PATCH] rs6000: Add Power10 optimization for _mm_blendv*

2022-01-07 Thread David Edelsohn via Gcc-patches
On Fri, Jan 7, 2022 at 3:32 PM Paul A. Clarke  wrote:
>
> On Fri, Jan 07, 2022 at 02:15:22PM -0500, David Edelsohn wrote:
> > > Power10 ISA added `xxblendv*` instructions which are realized in the
> > > `vec_blendv` instrinsic.
> > >
> > > Use `vec_blendv` for `_mm_blendv_epi8`, `_mm_blendv_ps`, and
> > > `_mm_blendv_pd` compatibility intrinsics, when `_ARCH_PWR10`.
> > >
> > > Also, copy a test from i386 for testing `_mm_blendv_ps`.
> > > This should have come with commit 
> > > ed04cf6d73e233c74c4e55c27f1cbd89ae4710e8,
> > > but was inadvertently omitted.
> > >
> > > 2021-10-20  Paul A. Clarke  
> > >
> > > gcc
> > > * config/rs6000/smmintrin.h (_mm_blendv_epi8): Use vec_blendv
> > > when _ARCH_PWR10.
> > > (_mm_blendv_ps): Likewise.
> > > (_mm_blendv_pd): Likewise.
> > >
> > > gcc/testsuite
> > > * gcc.target/powerpc/sse4_1-blendvps.c: Copy from gcc.target/i386,
> > > adjust dg directives to suit.
> > > ---
> > > Tested on Power10 powerpc64le-linux (compiled with and without
> > > `-mcpu=power10`).
> > >
> > > OK for trunk?
> >
> > This is okay modulo
> >
> > > + return (__m128i) vec_blendv ((__v16qu) __A, (__v16qu) __B, (__v16qu) 
> > > __mask);
> >
> > Should the above be __v16qi like x86?
>
> That does arguably match the types involved (epi8) better.
>
> Shall I change the original implementation as well (4 lines later)?
>
> >   return (__m128i) vec_sel ((__v16qi) __A, (__v16qi) __B, __lmask);

vec_blendv supports the signed type, so it seems that the function
should use that type, unless unsigned is preferred because PowerPC
defaults to unsigned char.

I wasn't going to recommend changing the existing code because I don't
know how the signed type interacts with the other builtins.

Thanks, David


Re: [PATCH] rs6000: Add Power10 optimization for most _mm_movemask*

2022-01-07 Thread Paul A. Clarke via Gcc-patches
On Fri, Jan 07, 2022 at 02:23:14PM -0500, David Edelsohn wrote:
> > Power10 ISA added `vextract*` instructions which are realized in the
> > `vec_extractm` instrinsic.
> >
> > Use `vec_extractm` for `_mm_movemask_ps`, `_mm_movemask_pd`, and
> > `_mm_movemask_epi8` compatibility intrinsics, when `_ARCH_PWR10`.
> >
> > 2021-10-21  Paul A. Clarke  
> >
> > gcc
> > * config/rs6000/xmmintrin.h (_mm_movemask_ps): Use vec_extractm
> > when _ARCH_PWR10.
> > * config/rs6000/emmintrin.h (_mm_movemask_pd): Likewise.
> > (_mm_movemask_epi8): Likewise.
> > ---
> > Tested on Power10 powerpc64le-linux (compiled with and without
> > `-mcpu=power10`).
> >
> > OK for trunk?
> 
> This is okay modulo
> 
> > + return vec_extractm ((__v16qu) __A);
> 
> Should the above be __v16qi like x86?

That would match x86 better, but we don't have a function signature
for vec_extractm which accepts a signed type.

PC


Re: [PATCH] rs6000: Add Power10 optimization for _mm_blendv*

2022-01-07 Thread Paul A. Clarke via Gcc-patches
On Fri, Jan 07, 2022 at 02:15:22PM -0500, David Edelsohn wrote:
> > Power10 ISA added `xxblendv*` instructions which are realized in the
> > `vec_blendv` instrinsic.
> >
> > Use `vec_blendv` for `_mm_blendv_epi8`, `_mm_blendv_ps`, and
> > `_mm_blendv_pd` compatibility intrinsics, when `_ARCH_PWR10`.
> >
> > Also, copy a test from i386 for testing `_mm_blendv_ps`.
> > This should have come with commit ed04cf6d73e233c74c4e55c27f1cbd89ae4710e8,
> > but was inadvertently omitted.
> >
> > 2021-10-20  Paul A. Clarke  
> >
> > gcc
> > * config/rs6000/smmintrin.h (_mm_blendv_epi8): Use vec_blendv
> > when _ARCH_PWR10.
> > (_mm_blendv_ps): Likewise.
> > (_mm_blendv_pd): Likewise.
> >
> > gcc/testsuite
> > * gcc.target/powerpc/sse4_1-blendvps.c: Copy from gcc.target/i386,
> > adjust dg directives to suit.
> > ---
> > Tested on Power10 powerpc64le-linux (compiled with and without
> > `-mcpu=power10`).
> >
> > OK for trunk?
> 
> This is okay modulo
> 
> > + return (__m128i) vec_blendv ((__v16qu) __A, (__v16qu) __B, (__v16qu) 
> > __mask);
> 
> Should the above be __v16qi like x86?

That does arguably match the types involved (epi8) better.

Shall I change the original implementation as well (4 lines later)?

>   return (__m128i) vec_sel ((__v16qi) __A, (__v16qi) __B, __lmask);

PC


Re: [PATCH v4] c-format: Add -Wformat-int-precision option [PR80060]

2022-01-07 Thread Joseph Myers
On Fri, 7 Jan 2022, Daniil Stas via Gcc-patches wrote:

> > > @@ -4248,7 +4248,7 @@ check_format_types (const substring_loc
> > > _loc, && (!pedantic || i < 2)
> > > && char_type_flag)
> > >   continue;
> > > -  if (types->scalar_identity_flag
> > > +  if ((types->scalar_identity_flag ||
> > > !warn_format_int_precision) && (TREE_CODE (cur_type) == TREE_CODE

This makes the option apply to all types, not just integer types.  Thus, 
it means a test such as

void f (void) { __builtin_printf ("%f", 0.0f64); }

is not diagnosed with -Wformat -Wno-format-int-precision.  Given the 
option name, I don't think it should affect diagnosing that test (and 
there should be such a test added to the testsuite to verify that it 
doesn't affect diagnostics for non-integer types).

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


Re: [power-ieee128] OPEN CONV

2022-01-07 Thread Jakub Jelinek via Gcc-patches
On Fri, Jan 07, 2022 at 11:26:15AM +0100, Thomas Koenig wrote:
> In
> 
> https://gcc.gnu.org/pipermail/fortran/2021-October/056895.html
> 
> I made a suggestion how how the format could look like.  I used
> a plus sign instead of a comma because I thought the environment
> variable should follow the same syntax as the CONVERT specifier,
> and I did not want to think about having commas in there :-)
> 
> Thinking about this again after some time, I think the syntax of
> the environment variable would be clearer if the keywords for
> the two conversions were separate, so somethig like
> 
> big_endian;r16_ieee;r16_ibm:10-20;
> 
> for the environment variable and
> 
> CONVERT="big_endian,r16_ibm"
> 
> would probably be better.

Here is completely untested patch that implements something,
but doesn't implement the gcc option stuff, nor the CONVERT=
syntax to supply multiple conversion options nor done anything
about env var nor any testcases.

But it tries to have the native/swap/big/little choice orthogonal from
native/r16_ieee/r16_ibm with r16_ieee and r16_ibm only supported on
ppc64le-linux.

For INQUIRE it has the so far perhaps manageable set of possibilities
handled so that it uses string literals and doesn't have to construct
those strings at runtime (haven't studied how it would need to be done).

I'm afraid I don't know that stuff enough to move forward from this.

--- gcc/fortran/libgfortran.h.jj2022-01-07 18:41:55.473722388 +0100
+++ gcc/fortran/libgfortran.h   2022-01-07 19:14:23.881784305 +0100
@@ -86,14 +86,16 @@ along with GCC; see the file COPYING3.
 #define GFC_INVALID_UNIT   -3
 
 /* Possible values for the CONVERT I/O specifier.  */
-/* Keep in sync with GFC_FLAG_CONVERT_* in gcc/flags.h.  */
+/* Keep in sync with GFC_FLAG_CONVERT_* in gcc/flag-types.h.  */
 typedef enum
 {
   GFC_CONVERT_NONE = -1,
   GFC_CONVERT_NATIVE = 0,
   GFC_CONVERT_SWAP,
   GFC_CONVERT_BIG,
-  GFC_CONVERT_LITTLE
+  GFC_CONVERT_LITTLE,
+  GFC_CONVERT_R16_IEEE = 4,
+  GFC_CONVERT_R16_IBM = 8
 }
 unit_convert;
 
--- gcc/flag-types.h.jj 2022-01-07 18:41:55.452722678 +0100
+++ gcc/flag-types.h2022-01-07 19:13:55.953170776 +0100
@@ -424,7 +424,9 @@ enum gfc_convert
   GFC_FLAG_CONVERT_NATIVE = 0,
   GFC_FLAG_CONVERT_SWAP,
   GFC_FLAG_CONVERT_BIG,
-  GFC_FLAG_CONVERT_LITTLE
+  GFC_FLAG_CONVERT_LITTLE,
+  GFC_FLAG_CONVERT_R16_IEEE = 4,
+  GFC_FLAG_CONVERT_R16_IBM = 8
 };
 
 
--- libgfortran/io/open.c.jj2022-01-07 18:41:56.078714031 +0100
+++ libgfortran/io/open.c   2022-01-07 19:19:11.582780100 +0100
@@ -153,6 +153,10 @@ static const st_option convert_opt[] =
   { "swap", GFC_CONVERT_SWAP},
   { "big_endian", GFC_CONVERT_BIG},
   { "little_endian", GFC_CONVERT_LITTLE},
+#ifdef HAVE_GFC_REAL_17
+  { "r16_ieee", GFC_CONVERT_R16_IEEE},
+  { "r16_ibm", GFC_CONVERT_R16_IBM},
+#endif
   { NULL, 0}
 };
 
@@ -820,7 +824,14 @@ st_open (st_parameter_open *opp)
   else
conv = compile_options.convert;
 }
-  
+
+  flags.convert = 0;
+
+#ifdef HAVE_GFC_REAL_17
+  flags.convert = conv & (GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
+  conv &= ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
+#endif
+
   switch (conv)
 {
 case GFC_CONVERT_NATIVE:
@@ -840,7 +851,7 @@ st_open (st_parameter_open *opp)
   break;
 }
 
-  flags.convert = conv;
+  flags.convert |= conv;
 
   if (flags.position != POSITION_UNSPECIFIED
   && flags.access == ACCESS_DIRECT)
--- libgfortran/io/transfer.c.jj2022-01-07 18:41:56.080714003 +0100
+++ libgfortran/io/transfer.c   2022-01-07 20:43:36.146920392 +0100
@@ -1126,7 +1126,11 @@ unformatted_read (st_parameter_dt *dtp,
 size *= GFC_SIZE_OF_CHAR_KIND(kind);
   read_block_direct (dtp, dest, size * nelems);
 
-  if (unlikely (dtp->u.p.current_unit->flags.convert == GFC_CONVERT_SWAP)
+  int convert = dtp->u.p.current_unit->flags.convert;
+#ifdef HAVE_GFC_REAL_17
+  convert &= ~(GFC_CONVERT_R16_IEEE | GFC_CONVERT_R16_IBM);
+#endif
+  if (unlikely (convert == GFC_CONVERT_SWAP)
   && kind != 1)
 {
   /* Handle wide chracters.  */
@@ -1144,6 +1148,48 @@ unformatted_read (st_parameter_dt *dtp,
}
   bswap_array (dest, dest, size, nelems);
 }
+#ifdef HAVE_GFC_REAL_17
+  if ((dtp->u.p.current_unit->flags.convert & GFC_CONVERT_R16_IEEE)
+  && kind == 16
+  && (type == BT_REAL || type == BT_COMPLEX))
+{
+  if (type == BT_COMPLEX && size == 32)
+   {
+ nelems *= 2;
+ size /= 2;
+   }
+  char *pd = dest;
+  for (size_t i = 0; i < nelems; i++)
+   {
+ GFC_REAL_16 r16;
+ GFC_REAL_17 r17;
+ memcpy (, pd, 16);
+ r16 = r17;
+ memcpy (pd, , 16);
+ pd += size;
+   }
+}
+  else if ((dtp->u.p.current_unit->flags.convert & GFC_CONVERT_R16_IBM)
+  && kind == 17
+  && (type == BT_REAL || type == BT_COMPLEX))
+{
+  if (type == BT_COMPLEX && size == 32)
+   {
+ nelems *= 2;
+ size /= 2;
+   }
+  

[PATCH] i386: Robustify V2QI and V4QI move patterns

2022-01-07 Thread Uros Bizjak via Gcc-patches
Add sse2 isa attribute where needed and remove where not needed.

2022-01-07  Uroš Bizjak  

gcc/ChangeLog:

* config/i386/mmx.md (*move_internal): Add isa attribute.
(*movv2qi_internal): Remve sse2 requirement for alternatives 4,5.

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

Pushed to master.

Uros.
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 8e0a6490b7b..4fc3e00f100 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -285,7 +285,12 @@
   gcc_unreachable ();
 }
 }
-  [(set (attr "type")
+  [(set (attr "isa")
+ (cond [(eq_attr "alternative" "6,7")
+ (const_string "sse2")
+  ]
+  (const_string "*")))
+   (set (attr "type")
  (cond [(eq_attr "alternative" "2")
  (const_string "sselog1")
(eq_attr "alternative" "3,4,5,6,7")
@@ -306,12 +311,15 @@
   (const_string "V4SF")
 (match_test "TARGET_AVX")
   (const_string "TI")
-(match_test "optimize_function_for_size_p (cfun)")
+(ior (not (match_test "TARGET_SSE2"))
+ (match_test "optimize_function_for_size_p (cfun)"))
   (const_string "V4SF")
]
(const_string "TI"))
+
(and (eq_attr "alternative" "4,5")
-(match_test "mode == V2HFmode"))
+(ior (match_test "mode == V2HFmode")
+ (not (match_test "TARGET_SSE2"
  (const_string "SF")
   ]
   (const_string "SI")))
@@ -401,7 +409,7 @@
 }
 }
   [(set (attr "isa")
-   (cond [(eq_attr "alternative" "4,5,6,8,9")
+   (cond [(eq_attr "alternative" "6,8,9")
  (const_string "sse2")
   (eq_attr "alternative" "7")
  (const_string "sse4")


Re: [PATCH] rs6000: Add optimizations for _mm_sad_epu8

2022-01-07 Thread David Edelsohn via Gcc-patches
+#ifdef __LITTLE_ENDIAN__
+  /* Sum across four integers with two integer results.  */
+  asm ("vsum2sws %0,%1,%2" : "=v" (result) : "v" (vsum), "v" (zero));
+  /* Note: vec_sum2s could be used here, but on little-endian, vector
+ shifts are added that are not needed for this use-case.
+ A vector shift to correctly position the 32-bit integer results
+ (currently at [0] and [2]) to [1] and [3] would then need to be
+ swapped back again since the desired results are two 64-bit
+ integers ([1]|[0] and [3]|[2]).  Thus, no shift is performed.  */
+#else
   /* Sum across four integers with two integer results.  */
   result = vec_sum2s (vsum, (__vector signed int) zero);

If little-endian adds shifts to correct for the position and
big-endian does not, why not use the inline asm without the shifts for
both?  It seems confusing to add the inline asm only for LE instead of
always using it with the appropriate comment.

It's a good and valuable optimization for LE.  Fewer variants are less
fragile, easier to test and easier to maintain.  If you're going to go
to the trouble of using inline asm for LE, use it for both.

Thanks, David


Re: [PATCH] rs6000: Add Power10 optimization for most _mm_movemask*

2022-01-07 Thread David Edelsohn via Gcc-patches
> Power10 ISA added `vextract*` instructions which are realized in the
> `vec_extractm` instrinsic.
>
> Use `vec_extractm` for `_mm_movemask_ps`, `_mm_movemask_pd`, and
> `_mm_movemask_epi8` compatibility intrinsics, when `_ARCH_PWR10`.
>
> 2021-10-21  Paul A. Clarke  
>
> gcc
> * config/rs6000/xmmintrin.h (_mm_movemask_ps): Use vec_extractm
> when _ARCH_PWR10.
> * config/rs6000/emmintrin.h (_mm_movemask_pd): Likewise.
> (_mm_movemask_epi8): Likewise.
> ---
> Tested on Power10 powerpc64le-linux (compiled with and without
> `-mcpu=power10`).
>
> OK for trunk?

This is okay modulo

> + return vec_extractm ((__v16qu) __A);

Should the above be __v16qi like x86?

Thanks, David


Re: [PATCH] rs6000: Add Power10 optimization for _mm_blendv*

2022-01-07 Thread David Edelsohn via Gcc-patches
> Power10 ISA added `xxblendv*` instructions which are realized in the
> `vec_blendv` instrinsic.
>
> Use `vec_blendv` for `_mm_blendv_epi8`, `_mm_blendv_ps`, and
> `_mm_blendv_pd` compatibility intrinsics, when `_ARCH_PWR10`.
>
> Also, copy a test from i386 for testing `_mm_blendv_ps`.
> This should have come with commit ed04cf6d73e233c74c4e55c27f1cbd89ae4710e8,
> but was inadvertently omitted.
>
> 2021-10-20  Paul A. Clarke  
>
> gcc
> * config/rs6000/smmintrin.h (_mm_blendv_epi8): Use vec_blendv
> when _ARCH_PWR10.
> (_mm_blendv_ps): Likewise.
> (_mm_blendv_pd): Likewise.
>
> gcc/testsuite
> * gcc.target/powerpc/sse4_1-blendvps.c: Copy from gcc.target/i386,
> adjust dg directives to suit.
> ---
> Tested on Power10 powerpc64le-linux (compiled with and without
> `-mcpu=power10`).
>
> OK for trunk?

This is okay modulo

> + return (__m128i) vec_blendv ((__v16qu) __A, (__v16qu) __B, (__v16qu) 
> __mask);

Should the above be __v16qi like x86?

Thanks, David


[PATCH] [12/11/10] Fix invalid format warnings on Windows

2022-01-07 Thread Tomas Kalibera via Gcc-patches

Mingw32 targets use ms_printf format for printf, but mingw-w64 when
configured for UCRT uses gnu_format (via stdio.h).  GCC then checks both
formats, which means that one cannot print a 64-bit integer without a 
warning.

All these lines issue a warning:

  printf("Hello %"PRIu64"\n", x); // 1
  printf("Hello %I64u\n", x); // 2
  printf("Hello %llu\n", x);  // 3

because each of them violates one of the formats.  This causes trouble
particularly for systems that turn warnings into errors or otherwise require
no warnings (leading to the use of -Wno-format or of various printf
replacements).

Also, one gets a warning twice if the format string violates both formats.

These issues have been reported as PR 95130 and PR 92292:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95130
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92292

This patch fixes these issues following the suggestion of Joseph Myers, it
disables the built in format in case there are additional ones. It applies
to GCC 12, 11, 10 and fixes the example above as tested on cross
compilers built on Linux.  I've also verified that R built using a 10.3
native compiler with the patch applied builds and passes its tests.  I've
updated the patch based on advice and comments from Martin Liska and
Martin Storsjo.

Could this or a variant of please be accepted to 12/11/10?

Thanks
Tomas

gcc/c-family/ChangeLog:

    * c-common.c (check_function_arguments): Pass also function
  declaration to check_function_format.

    * c-common.h (check_function_format): Extra argument - function
  declaration.

    * c-format.c (check_function_format): For builtin functions with a
  built in format and at least one more, do not check the first 
one.


diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 13341fa315e..be4d8400447 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -6057,7 +6057,7 @@ check_function_arguments (location_t loc, 
const_tree fndecl, const_tree fntype,

   /* Check for errors in format strings.  */

   if (warn_format || warn_suggest_attribute_format)
-    check_function_format (fntype, TYPE_ATTRIBUTES (fntype), nargs, 
argarray,
+    check_function_format (fndecl, fntype, TYPE_ATTRIBUTES (fntype), 
nargs, argarray,

            arglocs);

   if (warn_format)
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 8b7bf35e888..ee370eafbbc 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -856,7 +856,7 @@ extern void check_function_arguments_recurse (void (*)
                   unsigned HOST_WIDE_INT);
 extern bool check_builtin_function_arguments (location_t, vec,
                   tree, tree, int, tree *);
-extern void check_function_format (const_tree, tree, int, tree *,
+extern void check_function_format (const_tree, const_tree, tree, int, 
tree *,

                vec *);
 extern bool attribute_fallthrough_p (tree);
 extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index afa77810a5c..8155ee8c6f2 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -1160,12 +1160,13 @@ decode_format_type (const char *s, bool *is_raw 
/* = NULL */)

    attribute themselves.  */

 void
-check_function_format (const_tree fntype, tree attrs, int nargs,
+check_function_format (const_tree fndecl, const_tree fntype, tree 
attrs, int nargs,

        tree *argarray, vec *arglocs)
 {
-  tree a;
+  tree a, aa;

   tree atname = get_identifier ("format");
+  int skipped_default_format = 0;

   /* See if this function has any format attributes.  */
   for (a = attrs; a; a = TREE_CHAIN (a))
@@ -1176,6 +1177,58 @@ check_function_format (const_tree fntype, tree 
attrs, int nargs,

   function_format_info info;
   decode_format_attr (fntype, atname, TREE_VALUE (a), ,
           /*validated=*/true);
+
+      /* Mingw32 targets have traditionally used ms_printf format for the
+     printf function, and this format is built in GCC. But nowadays,
+     if mingw-w64 is configured to target UCRT, the printf function
+     uses the gnu_printf format (specified in the stdio.h header). This
+     causes GCC to check both formats, which means that there is no way
+     to e.g. print a long long unsigned without a warning (ms_printf
+     warns for %llu and gnu_printf warns for %I64u). Also, GCC 
would warn

+     twice about the same issue when both formats are violated, e.g.
+     for %lu used to print long long unsigned.
+
+     Hence, if there are multiple format specifiers, we skip the first
+     one. See PR 95130, PR 92292.  */
+
+      if (!skipped_default_format && fndecl)
+        {
+      for(aa = TREE_CHAIN (a); aa; aa = TREE_CHAIN(aa))
+        {
+          if (is_attribute_p ("format", get_attribute_name (aa)) &&
+          fndecl && fndecl_built_in_p (fndecl, 

Re: [PATCH][GCC11] PR tree-optimization/103603 - Directly resolve range_of_stmt dependencies. (Port of PR 103231/103464)

2022-01-07 Thread Andrew MacLeod via Gcc-patches

On 12/7/21 15:19, Andrew MacLeod wrote:
The following patch is a slight rework of the 2 patches which flatten 
rangers call stack.  It needed some tweaking since some of the 
routines have changed name or been adjusted.


This has been bootstrapped on x86_64-pc-linux-gnu with no 
regressions.  OK for gcc-11 release branch?


Andrew


ping.  I don't think anyone OK'd this.

Andrew



Re: [PING^3 PATCH] rs6000: Add Power10 optimization for _mm_blendv*

2022-01-07 Thread Paul A. Clarke via Gcc-patches
On Thu, Nov 18, 2021 at 08:25:35PM -0600, Paul A. Clarke via Gcc-patches wrote:
> On Mon, Nov 08, 2021 at 11:42:27AM -0600, Paul A. Clarke via Gcc-patches 
> wrote:
> > Gentle ping...
> 
> Gentle re-ping.

Gentle re-re-ping.

> > On Wed, Oct 20, 2021 at 08:42:07PM -0500, Paul A. Clarke via Gcc-patches 
> > wrote:
> > > Power10 ISA added `xxblendv*` instructions which are realized in the
> > > `vec_blendv` instrinsic.
> > > 
> > > Use `vec_blendv` for `_mm_blendv_epi8`, `_mm_blendv_ps`, and
> > > `_mm_blendv_pd` compatibility intrinsics, when `_ARCH_PWR10`.
> > > 
> > > Also, copy a test from i386 for testing `_mm_blendv_ps`.
> > > This should have come with commit 
> > > ed04cf6d73e233c74c4e55c27f1cbd89ae4710e8,
> > > but was inadvertently omitted.
> > > 
> > > 2021-10-20  Paul A. Clarke  
> > > 
> > > gcc
> > >   * config/rs6000/smmintrin.h (_mm_blendv_epi8): Use vec_blendv
> > >   when _ARCH_PWR10.
> > >   (_mm_blendv_ps): Likewise.
> > >   (_mm_blendv_pd): Likewise.
> > > 
> > > gcc/testsuite
> > >   * gcc.target/powerpc/sse4_1-blendvps.c: Copy from gcc.target/i386,
> > >   adjust dg directives to suit.
> > > ---
> > > Tested on Power10 powerpc64le-linux (compiled with and without
> > > `-mcpu=power10`).
> > > 
> > > OK for trunk?
> > > 
> > >  gcc/config/rs6000/smmintrin.h | 12 
> > >  .../gcc.target/powerpc/sse4_1-blendvps.c  | 65 +++
> > >  2 files changed, 77 insertions(+)
> > >  create mode 100644 gcc/testsuite/gcc.target/powerpc/sse4_1-blendvps.c
> > > 
> > > diff --git a/gcc/config/rs6000/smmintrin.h b/gcc/config/rs6000/smmintrin.h
> > > index b732fbca7b09..5d87fd7b6f61 100644
> > > --- a/gcc/config/rs6000/smmintrin.h
> > > +++ b/gcc/config/rs6000/smmintrin.h
> > > @@ -113,9 +113,13 @@ _mm_blend_epi16 (__m128i __A, __m128i __B, const int 
> > > __imm8)
> > >  extern __inline __m128i __attribute__((__gnu_inline__, 
> > > __always_inline__, __artificial__))
> > >  _mm_blendv_epi8 (__m128i __A, __m128i __B, __m128i __mask)
> > >  {
> > > +#ifdef _ARCH_PWR10
> > > +  return (__m128i) vec_blendv ((__v16qu) __A, (__v16qu) __B, (__v16qu) 
> > > __mask);
> > > +#else
> > >const __v16qu __seven = vec_splats ((unsigned char) 0x07);
> > >__v16qu __lmask = vec_sra ((__v16qu) __mask, __seven);
> > >return (__m128i) vec_sel ((__v16qu) __A, (__v16qu) __B, __lmask);
> > > +#endif
> > >  }
> > >  
> > >  __inline __m128
> > > @@ -149,9 +153,13 @@ __inline __m128
> > >  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
> > >  _mm_blendv_ps (__m128 __A, __m128 __B, __m128 __mask)
> > >  {
> > > +#ifdef _ARCH_PWR10
> > > +  return (__m128) vec_blendv ((__v4sf) __A, (__v4sf) __B, (__v4su) 
> > > __mask);
> > > +#else
> > >const __v4si __zero = {0};
> > >const __vector __bool int __boolmask = vec_cmplt ((__v4si) __mask, 
> > > __zero);
> > >return (__m128) vec_sel ((__v4su) __A, (__v4su) __B, (__v4su) 
> > > __boolmask);
> > > +#endif
> > >  }
> > >  
> > >  __inline __m128d
> > > @@ -174,9 +182,13 @@ __inline __m128d
> > >  __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
> > >  _mm_blendv_pd (__m128d __A, __m128d __B, __m128d __mask)
> > >  {
> > > +#ifdef _ARCH_PWR10
> > > +  return (__m128d) vec_blendv ((__v2df) __A, (__v2df) __B, (__v2du) 
> > > __mask);
> > > +#else
> > >const __v2di __zero = {0};
> > >const __vector __bool long long __boolmask = vec_cmplt ((__v2di) 
> > > __mask, __zero);
> > >return (__m128d) vec_sel ((__v2du) __A, (__v2du) __B, (__v2du) 
> > > __boolmask);
> > > +#endif
> > >  }
> > >  #endif
> > >  
> > > diff --git a/gcc/testsuite/gcc.target/powerpc/sse4_1-blendvps.c 
> > > b/gcc/testsuite/gcc.target/powerpc/sse4_1-blendvps.c
> > > new file mode 100644
> > > index ..8fcb55383047
> > > --- /dev/null
> > > +++ b/gcc/testsuite/gcc.target/powerpc/sse4_1-blendvps.c
> > > @@ -0,0 +1,65 @@
> > > +/* { dg-do run } */
> > > +/* { dg-require-effective-target p8vector_hw } */
> > > +/* { dg-options "-O2 -mpower8-vector -Wno-psabi" } */
> > > +
> > > +#include "sse4_1-check.h"
> > > +
> > > +#include 
> > > +#include 
> > > +
> > > +#define NUM 20
> > > +
> > > +static void
> > > +init_blendvps (float *src1, float *src2, float *mask)
> > > +{
> > > +  int i, msk, sign = 1; 
> > > +
> > > +  msk = -1;
> > > +  for (i = 0; i < NUM * 4; i++)
> > > +{
> > > +  if((i % 4) == 0)
> > > + msk++;
> > > +  src1[i] = i* (i + 1) * sign;
> > > +  src2[i] = (i + 20) * sign;
> > > +  mask[i] = (i + 120) * i;
> > > +  if( (msk & (1 << (i % 4
> > > + mask[i] = -mask[i];
> > > +  sign = -sign;
> > > +}
> > > +}
> > > +
> > > +static int
> > > +check_blendvps (__m128 *dst, float *src1, float *src2,
> > > + float *mask)
> > > +{
> > > +  float tmp[4];
> > > +  int j;
> > > +
> > > +  memcpy ([0], src1, sizeof (tmp));
> > > +  for (j = 0; j < 4; j++)
> > > +if (mask [j] < 0.0)
> > > +  tmp[j] = src2[j];
> > > +
> > > +  return memcmp (dst, [0], 

Re: [power-ieee128] RFH: LTO broken

2022-01-07 Thread Jakub Jelinek via Gcc-patches
On Fri, Jan 07, 2022 at 03:25:57PM +0100, Thomas Koenig wrote:
> > > 00251038  06ad0015 R_PPC64_JMP_SLOT   
> > >  __cabsieee128 + 0
> > > All these should for POWER_IEEE128 use atan2q@QUADMATH_1.0 etc.
> > 
> > So, seems all these come from f951 compiled sources.
> > For user code, I think the agreement was if you want to use successfully
> > -mabi=ieeelongdouble, you need glibc 2.32 or later, which is why the Fortran
> > FE doesn't conditionalize on whether glibc 2.32 is available or not and just
> > emits __WHATEVERieee128 entrypoints.
> 
> That was the idea, I think.
> 
> > But for Fortran compiled sources in libgfortran, we need to use
> > __WHATEVERieee128 only if glibc 2.32 or later and WHATEVERq (from
> > libquadmath) otherwise.
> > I guess easiest would be to do this always in the FE, but we need to
> > determine in the FE if the target is glibc 2.32 or later.
> 
> Instead of determining this in the front end, maybe we can add
> an option (documented, but marked as useful as only for internal
> use and with no guarantee that it will remain) and use that option
> when compiling libgfortran.

We apparently have already TARGET_GLIBC_MAJOR and TARGET_GLIBC_MINOR target
macros, and e.g. libgcc or D testsuite uses internal options like
-fbuilding-libgcc.

So, the following patch adds -fbuilding-libgfortran option and uses
it together with TARGET_GLIBC_M* checks to decide whether to use
libquadmath APIs (for the IEEE quad kind=16 if -fbuilding-libgfortran
and not glibc or glibc is older than 2.32) or glibc 2.32 APIs
(otherwise).  This way, libgfortran uses solely the libquadmath APIs
on glibc < 2.32 and __*ieee128 APIs on glibc 2.32, while user code
always uses the latter.

Ok for power-ieee128?

2022-01-07  Jakub Jelinek  

gcc/fortran/
* trans-types.c (gfc_init_kinds): When setting abi_kind to 17, if not
targetting glibc 2.32 or later and -fbuilding-libgfortran, set
gfc_real16_is_float128 and c_float128 in gfc_real_kinds.
(gfc_build_real_type): Don't set c_long_double if c_float128 is
already set.
* trans-intrinsic.c (builtin_decl_for_precision): Don't use
long_double_built_in if gfc_real16_is_float128 and
long_double_type_node == gfc_float128_type_node.
* lang.opt (fbuilding-libgfortran): New undocumented option.
libgfortran/
* Makefile.am (AM_FCFLAGS): Add -fbuilding-libgfortran after
-fallow-leading-underscore.
* Makefile.in: Regenerated.

--- gcc/fortran/trans-types.c.jj2022-01-04 10:27:56.498322942 +
+++ gcc/fortran/trans-types.c   2022-01-07 16:19:06.737066905 +
@@ -516,7 +516,16 @@ gfc_init_kinds (void)
 {
   for (int i = 0; i < r_index; ++i)
if (gfc_real_kinds[i].kind == 16)
- gfc_real_kinds[i].abi_kind = 17;
+ {
+   gfc_real_kinds[i].abi_kind = 17;
+   if (flag_building_libgfortran
+   && (TARGET_GLIBC_MAJOR < 2
+   || (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR < 32)))
+ {
+   gfc_real16_is_float128 = true;
+   gfc_real_kinds[i].c_float128 = 1;
+ }
+ }
 }
 
   /* Choose the default integer kind.  We choose 4 unless the user directs us
@@ -859,7 +868,7 @@ gfc_build_real_type (gfc_real_info *info
 info->c_float = 1;
   if (mode_precision == DOUBLE_TYPE_SIZE)
 info->c_double = 1;
-  if (mode_precision == LONG_DOUBLE_TYPE_SIZE)
+  if (mode_precision == LONG_DOUBLE_TYPE_SIZE && !info->c_float128)
 info->c_long_double = 1;
   if (mode_precision != LONG_DOUBLE_TYPE_SIZE && mode_precision == 128)
 {
--- gcc/fortran/trans-intrinsic.c.jj2022-01-07 09:39:10.222157644 +
+++ gcc/fortran/trans-intrinsic.c   2022-01-07 13:57:35.451495059 +
@@ -154,7 +154,9 @@ builtin_decl_for_precision (enum built_i
 i = m->float_built_in;
   else if (precision == TYPE_PRECISION (double_type_node))
 i = m->double_built_in;
-  else if (precision == TYPE_PRECISION (long_double_type_node))
+  else if (precision == TYPE_PRECISION (long_double_type_node)
+  && (!gfc_real16_is_float128
+  || long_double_type_node != gfc_float128_type_node))
 i = m->long_double_built_in;
   else if (precision == TYPE_PRECISION (gfc_float128_type_node))
 {
--- gcc/fortran/lang.opt.jj 2021-12-31 11:00:15.042190365 +
+++ gcc/fortran/lang.opt2022-01-07 16:18:17.685995005 +
@@ -413,6 +413,9 @@ fblas-matmul-limit=
 Fortran RejectNegative Joined UInteger Var(flag_blas_matmul_limit) Init(30)
 -fblas-matmul-limit=Size of the smallest matrix for which matmul 
will use BLAS.
 
+fbuilding-libgfortran
+Fortran Undocumented Var(flag_building_libgfortran)
+
 fcheck-array-temporaries
 Fortran
 Produce a warning at runtime if a array temporary has been created for a 
procedure argument.
--- libgfortran/Makefile.am.jj  2022-01-04 10:27:56.498322942 +
+++ libgfortran/Makefile.am 

[Ada] Read directory in Ada.Directories.Start_Search rather than Get_Next_Entry

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
The Ada.Directories directory search function is changed so the contents
of the directory is now read in Start_Search instead of in
Get_Next_Entry.  Start_Search now stores the result of the directory
search in the search object, with Get_Next_Entry returning results from
the search object. This differs from the prior implementation where
Get_Next_Entry would query the directory directly for the next item
using the POSIX readdir function.

The problem with building Get_Next_Entry around the readdir function is
POSIX does not specify the behavior of readdir when files are added or
removed from the directory being read. For example: on most systems,
deleting files from the folder being read does not impact readdir.
However, some systems, like RTEMS and HFS+ volumes on macOS, will return
NULL instead of the next item in the directory if the current item
returned by readdir is deleted.

To avoid this issue, the contents of the directory is read in
Start_Search and the user is given a copy of these results.
Consequently, any subsequent modification to the directory does not
affect the ability to iterate through the results. This approach is the
same taken by the popular fts C functions.

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

gcc/ada/

* libgnat/a-direct.adb (Search_Data): Remove type.
(Directory_Vectors): New package instantiation.
(Search_State): New type.
(Fetch_Next_Entry): Remove.
(Close): Remove.
(Finalize): Rewritten.
(Full_Name): Ditto.
(Get_Next_Entry): Return next entry from Search results vector
rather than querying the directory directly using readdir.
(Kind): Rewritten.
(Modification_Time): Rewritten.
(More_Entries): Use Search state cursor to determine if more
entries are available for users to read.
(Simple_Name): Rewritten.
(Size): Rewritten.
(Start_Search_Internal): Rewritten to load the contents of the
directory that matches the pattern and filter into the search
object.
* libgnat/a-direct.ads (Search_Type): New type.
(Search_Ptr): Ditto.
(Directory_Entry_Type): Rewritten to support new Start_Search
procedure.
* libgnat/s-filatt.ads (File_Length_Attr): New function.

patch.diff.gz
Description: application/gzip


[Ada] Fix the check of the 'Old prefix

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
The check did miss the part of Ada 2022 RM 6.1.1 (27/5) that the use of
an entity declared within the postcondition expression is allowed if
it's declared within the prefix itself.

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

gcc/ada/

* sem_attr.adb (Check_Reference): Fix condition.diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -5151,11 +5151,14 @@ package body Sem_Attr is
--  Entities mentioned within the prefix of attribute 'Old must
--  be global to the related postcondition. If this is not the
--  case, then the scope of the local entity is nested within
-   --  that of the subprogram.
+   --  that of the subprogram. Moreover, we need to know whether
+   --  Entity (Nod) occurs in the tree rooted at the prefix to
+   --  ensure the entity is not declared within then prefix itself.
 
elsif Is_Entity_Name (Nod)
  and then Present (Entity (Nod))
  and then Scope_Within (Scope (Entity (Nod)), Subp_Id)
+ and then not In_Subtree (Entity (Nod), P)
then
   Error_Attr
 ("prefix of attribute % cannot reference local entities",




[Ada] Fix uses of pragma Unreferenced in MinGW runtime unit

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
GNAT now emits more warnings about pragma Unreferenced.

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

gcc/ada/

* libgnarl/s-taprop__mingw.adb (Timed_Sleep): Remove "pragma
Unreferenced" for Result.
(Timed_Delay): Likewise.diff --git a/gcc/ada/libgnarl/s-taprop__mingw.adb b/gcc/ada/libgnarl/s-taprop__mingw.adb
--- a/gcc/ada/libgnarl/s-taprop__mingw.adb
+++ b/gcc/ada/libgnarl/s-taprop__mingw.adb
@@ -559,7 +559,6 @@ package body System.Task_Primitives.Operations is
   Abs_Time   : Duration;
 
   Result : Integer;
-  pragma Unreferenced (Result);
 
   Local_Timedout : Boolean;
 
@@ -615,7 +614,6 @@ package body System.Task_Primitives.Operations is
 
   Timedout : Boolean;
   Result   : Integer;
-  pragma Unreferenced (Timedout, Result);
 
begin
   Write_Lock (Self_ID);




[Ada] Fix layout of pragma Inline in generated AST unit

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Make the generated nmake.ads unit look more like it was written with
GNAT style rules in mind; semantics is unaffected.

Cleanup related to fix of default initialization in multi-dimensional
arrays, which used to explicitly call the Nmake.Make_Null routine.

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

gcc/ada/

* gen_il-gen.adb (Put_Make_Decls): Put pragma Inline in a
dedicated line, so that the current indentation is taken into
account.diff --git a/gcc/ada/gen_il-gen.adb b/gcc/ada/gen_il-gen.adb
--- a/gcc/ada/gen_il-gen.adb
+++ b/gcc/ada/gen_il-gen.adb
@@ -2472,7 +2472,8 @@ package body Gen_IL.Gen is
  for T in First_Concrete (Root) .. Last_Concrete (Root) loop
 if T not in N_Unused_At_Start | N_Unused_At_End then
Put_Make_Spec (S, Root, T);
-   Put (S, ";" & LF & "pragma " & Inline & " (Make_" &
+   Put (S, ";" & LF);
+   Put (S, "pragma " & Inline & " (Make_" &
 Image_Sans_N (T) & ");" & LF & LF);
 end if;
  end loop;




[Ada] Fix style in expansion of multi-dimensional array aggregates

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Cleanup; semantics is unaffected.

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

gcc/ada/

* exp_aggr.adb (Build_Array_Aggr_Code): Fix inconsistent style
in comments and code.diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -1021,7 +1021,7 @@ package body Exp_Aggr is
 
--  2. If the aggregate contains positional elements we
 
-   -- (a) translate the positional elements in a series of assignments
+   -- (a) Translate the positional elements in a series of assignments
 
-- (b) Generate a final loop to cover the others choice if any.
-- Note that this final loop has to be a while loop since the case
@@ -1032,7 +1032,7 @@ package body Exp_Aggr is
 
-- cannot be handled by a for loop. Thus for the following
 
-   -- array (L .. H) := (.. positional elements.., others =>E);
+   -- array (L .. H) := (.. positional elements.., others => E);
 
-- we always generate something like:
 
@@ -2063,11 +2063,9 @@ package body Exp_Aggr is
  --  Construct "for L_J in Index_Base range L .. H"
 
  L_Iteration_Scheme :=
-   Make_Iteration_Scheme
- (Loc,
+   Make_Iteration_Scheme (Loc,
   Loop_Parameter_Specification =>
-Make_Loop_Parameter_Specification
-  (Loc,
+Make_Loop_Parameter_Specification (Loc,
Defining_Identifier => L_J,
Discrete_Subtype_Definition => L_Range));
 




[Ada] Crash in class-wide pre/postconditions

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
The compiler may crash processing a class-wide pre/postcondition that
has dispatching calls using the Object.Operation notation.

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

gcc/ada/

* atree.ads (Traverse_Func_With_Parent): New generic subprogram.
(Traverse_Proc_With_Parent): Likewise.
* atree.adb (Parents_Stack): New table used to traverse trees
passing the parent field of each node.
(Internal_Traverse_With_Parent): New generic subprogram.
(Traverse_Func_With_Parent): Likewise.
(Traverse_Proc_With_Parent): Likewise.
* contracts.adb (Fix_Parents): New subprogram.
(Restore_Original_Selected_Component): Enhanced to fix the
parent field of restored nodes.
(Inherit_Condition): Adding assertions to check the parent field
of inherited conditions and to ensure that the built inherited
condition has no reference to the formals of the parent
subprogram.
* sem_util.ads, sem_util.adb (Check_Parents): New subprogram.diff --git a/gcc/ada/atree.adb b/gcc/ada/atree.adb
--- a/gcc/ada/atree.adb
+++ b/gcc/ada/atree.adb
@@ -88,6 +88,23 @@ package body Atree is
   Table_Increment  => Alloc.Node_Offsets_Increment,
   Table_Name   => "Orig_Nodes");
 
+   --
+   -- Parent Stack --
+   --
+
+   --  A separate table is used to traverse trees. It passes the parent field
+   --  of each node to the called process subprogram. It is defined global to
+   --  avoid adding performance overhead if allocated each time the traversal
+   --  functions are invoked.
+
+   package Parents_Stack is new Table.Table
+ (Table_Component_Type => Node_Id,
+  Table_Index_Type => Nat,
+  Table_Low_Bound  => 1,
+  Table_Initial=> 256,
+  Table_Increment  => 100,
+  Table_Name   => "Parents_Stack");
+
--
-- Paren_Count Handling --
--
@@ -135,6 +152,20 @@ package body Atree is
--  Fix up parent pointers for the children of Fix_Node after a copy,
--  setting them to Fix_Node when they pointed to Ref_Node.
 
+   generic
+  with function Process
+(Parent_Node : Node_Id;
+ Node: Node_Id) return Traverse_Result is <>;
+   function Internal_Traverse_With_Parent
+ (Node : Node_Id) return Traverse_Final_Result;
+   pragma Inline (Internal_Traverse_With_Parent);
+   --  Internal function that provides a functionality similar to Traverse_Func
+   --  but extended to pass the Parent node to the called Process subprogram;
+   --  delegates to Traverse_Func_With_Parent the initialization of the stack
+   --  data structure which stores the parent nodes (cf. Parents_Stack).
+   --  ??? Could we factorize the common code of Internal_Traverse_Func and
+   --  Traverse_Func?
+
procedure Mark_New_Ghost_Node (N : Node_Or_Entity_Id);
--  Mark arbitrary node or entity N as Ghost when it is created within a
--  Ghost region.
@@ -2322,6 +2353,167 @@ package body Atree is
   return Size_In_Slots (N) - N_Head;
end Size_In_Slots_Dynamic;
 
+   ---
+   -- Internal_Traverse_With_Parent --
+   ---
+
+   function Internal_Traverse_With_Parent
+  (Node : Node_Id) return Traverse_Final_Result
+   is
+  Tail_Recursion_Counter : Natural := 0;
+
+  procedure Pop_Parents;
+  --  Pop enclosing nodes of tail recursion plus the current parent.
+
+  function Traverse_Field (Fld : Union_Id) return Traverse_Final_Result;
+  --  Fld is one of the Traversed fields of Nod, which is necessarily a
+  --  Node_Id or List_Id. It is traversed, and the result is the result of
+  --  this traversal.
+
+  -
+  -- Pop_Parents --
+  -
+
+  procedure Pop_Parents is
+  begin
+ --  Pop the enclosing nodes of the tail recursion
+
+ for J in 1 .. Tail_Recursion_Counter loop
+Parents_Stack.Decrement_Last;
+ end loop;
+
+ --  Pop the current node
+
+ pragma Assert (Parents_Stack.Table (Parents_Stack.Last) = Node);
+ Parents_Stack.Decrement_Last;
+  end Pop_Parents;
+
+  
+  -- Traverse_Field --
+  
+
+  function Traverse_Field (Fld : Union_Id) return Traverse_Final_Result is
+  begin
+ if Fld /= Union_Id (Empty) then
+
+--  Descendant is a node
+
+if Fld in Node_Range then
+   return Internal_Traverse_With_Parent (Node_Id (Fld));
+
+--  Descendant is a list
+
+elsif Fld in List_Range then
+   declare
+  Elmt : Node_Id := First (List_Id (Fld));
+   begin
+  while Present (Elmt) loop
+ if Internal_Traverse_With_Parent (Elmt) = Abandon then
+

[Ada] More default initialization for multi-dim array aggregates

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Expansion of multi-dimensional array aggregates with boxes (e.g.
"(others => (others => <>))" only applied default initialization to
components of a scalar type with Default_Value aspect and of an access
type (which are initialized by default to null).

Now default initialization is applied to components of all types that
require default initialization (e.g. because of pragma
Normalize_Scalars), except for those with pragma
Suppress_Initialization.

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

gcc/ada/

* exp_aggr.adb (Gen_Assign): Remove explicit initialization for
components of access types.
(Get_Assoc_Expr): Enable initialization for components of all
types that require simple initialization.diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -1872,12 +1872,6 @@ package body Exp_Aggr is
   Set_Etype (Indexed_Comp, Ctype);
   Append_To (Stmts, Make_Invariant_Call (Indexed_Comp));
end if;
-
-elsif Is_Access_Type (Ctype) then
-   Append_To (Stmts,
- Make_Assignment_Statement (Loc,
-   Name   => New_Copy_Tree (Indexed_Comp),
-   Expression => Make_Null (Loc)));
 end if;
 
 if Needs_Finalization (Ctype) then
@@ -2212,15 +2206,10 @@ package body Exp_Aggr is
 
   begin
  if Box_Present (Assoc) then
-if Is_Scalar_Type (Ctype) then
-   if Present (Default_Aspect_Component_Value (Typ)) then
-  return Default_Aspect_Component_Value (Typ);
-   elsif Present (Default_Aspect_Value (Ctype)) then
-  return Default_Aspect_Value (Ctype);
-   else
-  return Empty;
-   end if;
-
+if Present (Default_Aspect_Component_Value (Typ)) then
+   return Default_Aspect_Component_Value (Typ);
+elsif Needs_Simple_Initialization (Ctype) then
+   return Get_Simple_Init_Val (Ctype, N);
 else
return Empty;
 end if;




[Ada] Cleanup and modification of unreferenced warnings

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
This patch modifies the behavior of pragma Unreferenced to be consistent
in its behavior, by counting all variables specified as "Out" actual
parameters as being referenced instead of only the first "Out"
parameter. Additionally, much related duplicated has been removed.

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

gcc/ada/

* comperr.adb (Delete_SCIL_Files): Replace unnecessary
Unreferenced pragma with specific pragma Warnings.
* doc/gnat_rm/implementation_defined_pragmas.rst (Unreferenced):
Add documentation for new behavior.
* gnat_rm.texi: Regenerate.
* erroutc.adb (Set_At): Remove useless assignment.
* exp_ch2.adb (In_Assignment_Context): Deleted.
(Is_Object_Renaming_Name): Replace calls to Is_LHS with calls to
Known_To_Be_Assigned.
(Expand_Current_Value): Replace calls to May_Be_Lvalue with
calls to Known_To_Be_Assigned.
(Expand_Entry_Paramter): Replace calls to In_Assignment_Context
with calls to Known_To_Be_Assigned.
* exp_ch4.adb (Expand_N_Op_Rem): Remove unnecessary Unreferenced
pragma.
* exp_imgv.adb (Build_Enumeration_Image_Tables): Default
initialize S_N.
* ghost.adb (Check_Ghost_Policy): Replace call to May_Be_Lvalue
with call to Known_To_Be_Assigned.
* lib-xref.adb (Is_On_LHS): Deleted.
(OK_To_Set_Referenced): Rewrite subprogram to encompass the new
pragma Unreferenced behavior.
(Process_Deferred_References): Replace call to Is_LHS with call
to Known_To_Be_Assigned.
* libgnarl/s-taasde.adb, libgnarl/s-tasren.adb,
libgnarl/s-tpobop.adb, libgnat/a-calend.adb,
libgnat/a-calfor.adb, libgnat/a-cbdlli.adb,
libgnat/a-cbhama.adb, libgnat/a-cbhase.adb,
libgnat/a-cbmutr.adb, libgnat/a-cborma.adb,
libgnat/a-cborse.adb, libgnat/a-cdlili.adb,
libgnat/a-cfhama.adb, libgnat/a-cforse.adb,
libgnat/a-cidlli.adb, libgnat/a-cihama.adb,
libgnat/a-cihase.adb, libgnat/a-cimutr.adb,
libgnat/a-ciorma.adb, libgnat/a-ciormu.adb,
libgnat/a-ciorse.adb, libgnat/a-cohama.adb,
libgnat/a-cohase.adb, libgnat/a-comutr.adb,
libgnat/a-convec.adb, libgnat/a-coorma.adb,
libgnat/a-coormu.adb, libgnat/a-coorse.adb,
libgnat/a-crdlli.adb, libgnat/a-tigeau.adb,
libgnat/a-wtgeau.adb, libgnat/a-ztgeau.adb,
libgnat/g-calend.adb, libgnat/g-comlin.adb,
libgnat/g-expect.adb, libgnat/g-mbflra.adb,
libgnat/g-spipat.adb, libgnat/s-fatgen.adb,
libgnat/s-fileio.adb, libgnat/s-os_lib.adb,
libgnat/s-regpat.adb, libgnat/s-valued.adb,
libgnat/s-valuer.adb: Remove unnecessary Unreferenced pragmas
* sem_ch10.adb (Process_Spec_Clauses): Remove useless
assignments.
* sem_ch13.adb (Validate_Literal_Aspect): Default initialize I.
* sem_ch3.adb (Build_Derived_Concurrent_Type): Default
initialize Corr_Decl.
* sem_ch8.adb (Undefined): Replace calls to Is_LHS with calls to
Known_To_Be_Assigned.
(In_Abstract_View_Pragma): Likewise.
* sem_eval.adb (Eval_Selected_Component): Replace calls to
Is_LHS with calls to Known_To_Be_Assigned.
* sem_res.adb (Init_Component): Replace calls to May_Be_Lvalue
with calls to Known_To_Be_Assigned.
* sem_util.adb, sem_util.ads (End_Label_Loc): Default initialize
Owner.
(Explain_Limited_Type): Default initialize Expr_Func.
(Find_Actual): Modified to handle entry families.
(Is_LHS): Deleted.
(May_Be_Lvalue): Deleted.
(Known_To_Be_Assigned): Modified and improved to handle all
cases.
* sem_warn.adb (Traverse_Result): Replace calls to May_Be_Lvalue
with calls to Known_To_Be_Assigned.
(Check_Ref): Modify error on unreferenced out parameters to take
into account different warning flags.

patch.diff.gz
Description: application/gzip


[Ada] Spurious error caused by order of interfaces in full view

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
The frontend reports a spurious error when the order of interfaces
differ between the full view and the partial view of a private type
defined in a generic unit.

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

gcc/ada/

* sem_ch3.adb (Reorder_Interfaces): When the conflicting
interface is identified we just replace the interface in the
list of interfaces of the tagged type (instead of adding a
duplicate to the list of interfaces).diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -17272,7 +17272,6 @@ package body Sem_Ch3 is
 --  append the full view's original parent to the interface list,
 --  recursively call Derived_Type_Definition on the full type, and
 --  return True. If a match is not found, return False.
---  ??? This seems broken in the case of generic packages.
 
 
 -- Reorder_Interfaces --
@@ -17281,6 +17280,7 @@ package body Sem_Ch3 is
 function Reorder_Interfaces return Boolean is
Iface : Node_Id;
New_Iface : Node_Id;
+
 begin
Iface := First (Interface_List (Def));
while Present (Iface) loop
@@ -17290,7 +17290,7 @@ package body Sem_Ch3 is
 
  New_Iface :=
Make_Identifier (Sloc (N), Chars (Parent_Type));
- Append (New_Iface, Interface_List (Def));
+ Rewrite (Iface, New_Iface);
 
  --  Analyze the transformed code
 




[Ada] Fix __gnat_kill on Windows

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Terminate process only on terminating signals.

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

gcc/ada/

* adaint.c (__gnat_kill): Terminate process only in case of
SIGKILL, SIGINT, SIGBREAK, SIGTERM, SIGABRT.  Do not call
OpenProcess if not going to terminate process.diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -3559,13 +3559,21 @@ void
 __gnat_kill (int pid, int sig, int close ATTRIBUTE_UNUSED)
 {
 #if defined(_WIN32)
-  HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
-  if (h == NULL)
-return;
+  HANDLE h;
 
-  TerminateProcess (h, sig);
+  switch (sig) {
+case 9: // SIGKILL is not declared in Windows headers
+case SIGINT:
+case SIGBREAK:
+case SIGTERM:
+case SIGABRT:
+  h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
+  if (h != NULL) {
+TerminateProcess (h, sig);
+CloseHandle (h);
+  }
+  }
 
-  CloseHandle (h);
 #elif defined (__vxworks)
   /* Not implemented */
 #else




[Ada] Fix a couple of issues with pragma Inspection_Point

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
The first issue is that the pragma may require the address of the objects
subject to it to have their address taken, like Asm_Input and Asm_Output,
so these objects need to be specifically marked.

The second issue is that the detection of unfrozen objects was not robust
enough and would miss objects that are explicit arguments of the pragma.

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

gcc/ada/

* exp_prag.adb (Expand_Pragma_Inspection_Point): Do a single pass
over the arguments of the pragma.  Set the Address_Taken flag on
them and use the Has_Delayed_Freeze flag to spot those which have
their elaboration delayed.  Reuse the location variable Loc.diff --git a/gcc/ada/exp_prag.adb b/gcc/ada/exp_prag.adb
--- a/gcc/ada/exp_prag.adb
+++ b/gcc/ada/exp_prag.adb
@@ -2354,12 +2354,13 @@ package body Exp_Prag is
 
procedure Expand_Pragma_Inspection_Point (N : Node_Id) is
   Loc : constant Source_Ptr := Sloc (N);
+
   A : List_Id;
   Assoc : Node_Id;
-  S : Entity_Id;
   E : Entity_Id;
+  Rip   : Boolean;
+  S : Entity_Id;
 
-  Remove_Inspection_Point : Boolean := False;
begin
   if No (Pragma_Argument_Associations (N)) then
  A := New_List;
@@ -2389,45 +2390,47 @@ package body Exp_Prag is
  Set_Pragma_Argument_Associations (N, A);
   end if;
 
-  --  Expand the arguments of the pragma. Expanding an entity reference
-  --  is a noop, except in a protected operation, where a reference may
-  --  have to be transformed into a reference to the corresponding prival.
-  --  Are there other pragmas that may require this ???
+  --  Process the arguments of the pragma and expand them. Expanding an
+  --  entity reference is a noop, except in a protected operation, where
+  --  a reference may have to be transformed into a reference to the
+  --  corresponding prival. Are there other pragmas that require this ???
 
+  Rip := False;
   Assoc := First (Pragma_Argument_Associations (N));
   while Present (Assoc) loop
- Expand (Expression (Assoc));
- Next (Assoc);
-  end loop;
+ --  The back end may need to take the address of the object
 
-  --  If any of the references have a freeze node, it must appear before
-  --  pragma Inspection_Point, otherwise the entity won't be available when
-  --  Gigi processes Inspection_Point.
-  --  When this requirement isn't met, turn the pragma into a no-op.
+ Set_Address_Taken (Entity (Expression (Assoc)));
 
-  Assoc := First (Pragma_Argument_Associations (N));
-  while Present (Assoc) loop
+ Expand (Expression (Assoc));
+
+ --  If any of the objects have a freeze node, it must appear before
+ --  pragma Inspection_Point, otherwise the entity won't be elaborated
+ --  when Gigi processes the pragma.
 
- if Present (Freeze_Node (Entity (Expression (Assoc and then
-   not Is_Frozen (Entity (Expression (Assoc)))
+ if Has_Delayed_Freeze (Entity (Expression (Assoc)))
+   and then not Is_Frozen (Entity (Expression (Assoc)))
  then
-Error_Msg_NE ("??inspection point references unfrozen object &",
-  Assoc,
-  Entity (Expression (Assoc)));
-Remove_Inspection_Point := True;
+Error_Msg_NE
+  ("??inspection point references unfrozen object &",
+   Assoc,
+   Entity (Expression (Assoc)));
+Rip := True;
  end if;
 
  Next (Assoc);
   end loop;
 
-  if Remove_Inspection_Point then
+  --  When the above requirement isn't met, turn the pragma into a no-op
+
+  if Rip then
  Error_Msg_N ("\pragma will be ignored", N);
 
  --  We can't just remove the pragma from the tree as it might be
  --  iterated over by the caller. Turn it into a null statement
  --  instead.
 
- Rewrite (N, Make_Null_Statement (Sloc (N)));
+ Rewrite (N, Make_Null_Statement (Loc));
   end if;
end Expand_Pragma_Inspection_Point;
 




[Ada] Remove repeated routines for printing AST in Mixed_Case

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Code cleanup; behaviour is unaffected.

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

gcc/ada/

* osint.adb (To_Lower): Clarify that only To_Lower function
causes bootstrap issues; fix style.
* treepr.adb (Print_Str_Mixed_Case): Reuse existing case
conversion routine.
(To_Mixed): Rename from Capitalize; reuse System.Case_Util
procedure and explain the bootstrap issue.diff --git a/gcc/ada/osint.adb b/gcc/ada/osint.adb
--- a/gcc/ada/osint.adb
+++ b/gcc/ada/osint.adb
@@ -1061,7 +1061,8 @@ package body Osint is
function File_Names_Equal (File1, File2 : String) return Boolean is
 
   function To_Lower (A : String) return String;
-  --  For bootstrap reasons, we cannot use To_Lower from System.Case_Util
+  --  For bootstrap reasons, we cannot use To_Lower function from
+  --  System.Case_Util.
 
   --
   -- To_Lower --
@@ -1074,6 +1075,8 @@ package body Osint is
  return Result;
   end To_Lower;
 
+   --  Start of processing for File_Names_Equal
+
begin
   if File_Names_Case_Sensitive then
  return File1 = File2;


diff --git a/gcc/ada/treepr.adb b/gcc/ada/treepr.adb
--- a/gcc/ada/treepr.adb
+++ b/gcc/ada/treepr.adb
@@ -25,7 +25,6 @@
 
 with Aspects;  use Aspects;
 with Atree;use Atree;
-with Csets;use Csets;
 with Debug;use Debug;
 with Einfo;use Einfo;
 with Einfo.Entities;   use Einfo.Entities;
@@ -45,6 +44,7 @@ with Snames;   use Snames;
 with Sinput;   use Sinput;
 with Stand;use Stand;
 with Stringt;  use Stringt;
+with System.Case_Util; use System.Case_Util;
 with SCIL_LL;  use SCIL_LL;
 with Uintp;use Uintp;
 with Urealp;   use Urealp;
@@ -135,9 +135,9 @@ package body Treepr is
function From_Union is new Unchecked_Conversion (Union_Id, Uint);
function From_Union is new Unchecked_Conversion (Union_Id, Ureal);
 
-   function Capitalize (S : String) return String;
-   procedure Capitalize (S : in out String);
-   --  Turns an identifier into Mixed_Case
+   function To_Mixed (S : String) return String;
+   --  Turns an identifier into Mixed_Case. For bootstrap reasons, we cannot
+   --  use To_Mixed function from System.Case_Util.
 
function Image (F : Node_Or_Entity_Field) return String;
 
@@ -255,35 +255,6 @@ package body Treepr is
--  descendants are to be printed. Prefix_Str is to be added to all
--  printed lines.
 
-   
-   -- Capitalize --
-   
-
-   procedure Capitalize (S : in out String) is
-  Cap : Boolean := True;
-   begin
-  for J in S'Range loop
- declare
-Old : constant Character := S (J);
- begin
-if Cap then
-   S (J) := Fold_Upper (S (J));
-else
-   S (J) := Fold_Lower (S (J));
-end if;
-
-Cap := Old = '_';
- end;
-  end loop;
-   end Capitalize;
-
-   function Capitalize (S : String) return String is
-   begin
-  return Result : String (S'Range) := S do
- Capitalize (Result);
-  end return;
-   end Capitalize;
-
--
-- Hash --
--
@@ -400,7 +371,7 @@ package body Treepr is
 
  when others =>
 declare
-   Result : constant String := Capitalize (F'Img);
+   Result : constant String := To_Mixed (F'Img);
 begin
return Result (3 .. Result'Last); -- Remove "F_"
 end;
@@ -1713,22 +1684,8 @@ package body Treepr is
--
 
procedure Print_Str_Mixed_Case (S : String) is
-  Ucase : Boolean;
-
begin
-  if Phase = Printing then
- Ucase := True;
-
- for J in S'Range loop
-if Ucase then
-   Write_Char (S (J));
-else
-   Write_Char (Fold_Lower (S (J)));
-end if;
-
-Ucase := (S (J) = '_');
- end loop;
-  end if;
+  Print_Str (To_Mixed (S));
end Print_Str_Mixed_Case;
 

@@ -1862,6 +1819,17 @@ package body Treepr is
   Next_Serial_Number := Next_Serial_Number + 1;
end Set_Serial_Number;
 
+   --
+   -- To_Mixed --
+   --
+
+   function To_Mixed (S : String) return String is
+   begin
+  return Result : String (S'Range) := S do
+ To_Mixed (Result);
+  end return;
+   end To_Mixed;
+
---
-- Tree_Dump --
---




[Ada] Simplify traversal in hooking of transient scopes

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Subprogram calls can be detected with just Traverse_Func, we don't need
a separate global variable or a Traverse_Proc (which is a wrapper for
Traverse_Func with a yet another variable).

Cleanup related to handling of transient scopes in various routines for
(pre)analysis and resolution. Semantics is unaffected.

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

gcc/ada/

* exp_ch7.adb (Process_Transients_In_Scope): Remove unnecessary
initialization of Must_Hook; change Detect_Subprogram_Call from
function to procedure; adapt caller.diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -6188,15 +6188,15 @@ package body Exp_Ch7 is
  Last_Object  : Node_Id;
  Related_Node : Node_Id)
   is
- Must_Hook : Boolean := False;
+ Must_Hook : Boolean;
  --  Flag denoting whether the context requires transient object
  --  export to the outer finalizer.
 
  function Is_Subprogram_Call (N : Node_Id) return Traverse_Result;
- --  Determine whether an arbitrary node denotes a subprogram call
+ --  Return Abandon if arbitrary node denotes a subprogram call
 
- procedure Detect_Subprogram_Call is
-   new Traverse_Proc (Is_Subprogram_Call);
+ function Has_Subprogram_Call is
+   new Traverse_Func (Is_Subprogram_Call);
 
  procedure Process_Transient_In_Scope
(Obj_Decl  : Node_Id;
@@ -6216,7 +6216,6 @@ package body Exp_Ch7 is
 --  A regular procedure or function call
 
 if Nkind (N) in N_Subprogram_Call then
-   Must_Hook := True;
return Abandon;
 
 --  Special cases
@@ -6226,20 +6225,13 @@ package body Exp_Ch7 is
 --  of the call.
 
 elsif Is_Rewrite_Substitution (N) then
-   Detect_Subprogram_Call (Original_Node (N));
-
-   if Must_Hook then
-  return Abandon;
-   else
-  return OK;
-   end if;
+   return Has_Subprogram_Call (Original_Node (N));
 
 --  Generalized indexing always involves a function call
 
 elsif Nkind (N) = N_Indexed_Component
   and then Present (Generalized_Indexing (N))
 then
-   Must_Hook := True;
return Abandon;
 
 --  Keep searching
@@ -6476,8 +6468,8 @@ package body Exp_Ch7 is
  --  due to the possibility of abnormal call termination.
 
  else
-Detect_Subprogram_Call (N);
-Blk_Ins := Last_Object;
+Must_Hook := Has_Subprogram_Call (N) = Abandon;
+Blk_Ins   := Last_Object;
  end if;
 
  if Clean then




[Ada] Remove extra space before THEN keywords

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Style cleanup; semantics is unaffected.

Offending occurrences found with:

  $ grep "[A-Za-z0-9\)]+  +then$" -C 3

and reviewed manually, because some of them were due to explicit layout.

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

gcc/ada/

* exp_ch5.adb, exp_disp.adb, exp_util.adb, par-ch4.adb,
sem_ch13.adb: Remove extra space before THEN that occurs at the
end of a line.diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -2664,7 +2664,7 @@ package body Exp_Ch5 is
 Rewrite (Lhs, OK_Convert_To (Base_Type (Typ), Lhs));
 Apply_Discriminant_Check (Rhs, Typ, Lhs);
 
- elsif Is_Array_Type (Typ) and then Is_Constrained (Typ)  then
+ elsif Is_Array_Type (Typ) and then Is_Constrained (Typ) then
 Rewrite (Rhs, OK_Convert_To (Base_Type (Typ), Rhs));
 Rewrite (Lhs, OK_Convert_To (Base_Type (Typ), Lhs));
 Apply_Length_Check (Rhs, Typ);


diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
--- a/gcc/ada/exp_disp.adb
+++ b/gcc/ada/exp_disp.adb
@@ -4615,7 +4615,7 @@ package body Exp_Disp is
--  case concerning the need for this check, and this topic may
--  go back to the ARG.
 
-   if not Is_Abstract_Subprogram (Prim)  then
+   if not Is_Abstract_Subprogram (Prim) then
   Formal := First_Formal (Prim);
   while Present (Formal) loop
  Check_Premature_Freezing (Prim, Typ, Etype (Formal));


diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -3752,7 +3752,7 @@ package body Exp_Util is
   --  Anonymous arrays in object declarations have no explicit declaration
   --  so use the related object declaration as the insertion point.
 
-  elsif Is_Itype (Work_Typ) and then Is_Array_Type (Work_Typ)  then
+  elsif Is_Itype (Work_Typ) and then Is_Array_Type (Work_Typ) then
  Typ_Decl := Associated_Node_For_Itype (Work_Typ);
 
   --  Derived types with the full view as parent do not have a partial


diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb
--- a/gcc/ada/par-ch4.adb
+++ b/gcc/ada/par-ch4.adb
@@ -2968,7 +2968,7 @@ package body Ch4 is
   Save_Scan_State (Scan_State);
   Scan;   --  past FOR
 
-  if Token = Tok_All or else Token = Tok_Some  then
+  if Token = Tok_All or else Token = Tok_Some then
  Restore_Scan_State (Scan_State);  -- To FOR
  Node1 := P_Quantified_Expression;
 


diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -16005,7 +16005,7 @@ package body Sem_Ch13 is
 
   function Valid_Empty (E :  Entity_Id) return Boolean is
   begin
- if Etype (E) /= Typ or else Scope (E) /= Scope (Typ)  then
+ if Etype (E) /= Typ or else Scope (E) /= Scope (Typ) then
 return False;
 
  elsif Ekind (E) = E_Constant then




[Ada] Fix exit status of GNAT.Expect.Close call on running process

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Fix exit status processing logic in __gnat_waitpid.  Fix
GNAT.Expect.Interrupt on Windows.  It was terminating the calling
process.

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

gcc/ada/

* expect.c (__gnat_waitpid): Use macros WIFEXITED, WEXITSTATUS,
WIFSIGNALED, WTERMSIG, WIFSTOPPED, WSTOPSIG to get exit status
or signal that caused the child process to terminate/stop.  Do
not process exit status in case of error in waitpid call.
* adaint.c (__gnat_kill): Use of GenerateConsoleCtrlEvent is
removed in Windows variant as it actually is not working and was
terminating the calling process.  Set signal number into exit
code parameter of TerminateProcess to work the same like in
Linux.diff --git a/gcc/ada/adaint.c b/gcc/ada/adaint.c
--- a/gcc/ada/adaint.c
+++ b/gcc/ada/adaint.c
@@ -3562,18 +3562,8 @@ __gnat_kill (int pid, int sig, int close ATTRIBUTE_UNUSED)
   HANDLE h = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid);
   if (h == NULL)
 return;
-  if (sig == 9)
-{
-  TerminateProcess (h, 1);
-}
-  else if (sig == SIGINT)
-GenerateConsoleCtrlEvent (CTRL_C_EVENT, pid);
-  else if (sig == SIGBREAK)
-GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT, pid);
-  /* ??? The last two alternatives don't really work. SIGBREAK requires setting
- up process groups at start time which we don't do; treating SIGINT is just
- not possible apparently. So we really only support signal 9. Fortunately
- that's all we use in GNAT.Expect */
+
+  TerminateProcess (h, sig);
 
   CloseHandle (h);
 #elif defined (__vxworks)


diff --git a/gcc/ada/expect.c b/gcc/ada/expect.c
--- a/gcc/ada/expect.c
+++ b/gcc/ada/expect.c
@@ -345,8 +345,17 @@ __gnat_waitpid (int pid)
 {
   int status = 0;
 
-  waitpid (pid, , 0);
-  status = WEXITSTATUS (status);
+  if (waitpid (pid, , 0) == -1) {
+ return -1;
+  }
+
+  if WIFEXITED (status) {
+ status = WEXITSTATUS (status);
+  } else if WIFSIGNALED (status) {
+ status = WTERMSIG (status);
+  } else if WIFSTOPPED (status) {
+ status = WSTOPSIG (status);
+  }
 
   return status;
 }




[Ada] Remove explicit expansion of block with general case statement

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
When a general case statements is rewritten into a block, it is enough
to call Analyze on this block node, because analysis of non-expressions
automatically triggers expansion.

Cleanup originating from investigating many variants of routines for
(pre)analysis and resolution.

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

gcc/ada/

* exp_ch5.adb (Expand_N_Case_Statement): Remove explicit
expansion.diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -39,7 +39,6 @@ with Exp_Dbug;   use Exp_Dbug;
 with Exp_Pakd;   use Exp_Pakd;
 with Exp_Tss;use Exp_Tss;
 with Exp_Util;   use Exp_Util;
-with Expander;   use Expander;
 with Inline; use Inline;
 with Namet;  use Namet;
 with Nlists; use Nlists;
@@ -3876,7 +3875,6 @@ package body Exp_Ch5 is
   if Extensions_Allowed and then not Is_Discrete_Type (Etype (Expr)) then
  Rewrite (N, Expand_General_Case_Statement);
  Analyze (N);
- Expand (N);
  return;
   end if;
 




[Ada] Update -gnatwr doc for import of parent package

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
This construct is now flagged with -gnatwr.

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

gcc/ada/

* doc/gnat_ugn/building_executable_programs_with_gnat.rst:
Update -gnatwr documentation.
* gnat_ugn.texi: Regenerate.diff --git a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
--- a/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
+++ b/gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst
@@ -3703,6 +3703,8 @@ of the pragma in the :title:`GNAT_Reference_manual`).
   * Comparison of an object or (unary or binary) operation of boolean type to
 an explicit True value.
 
+  * Import of parent package.
+
   The default is that warnings for redundant constructs are not given.
 
 


diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -11974,6 +11974,9 @@ to be non-negative
 @item 
 Comparison of an object or (unary or binary) operation of boolean type to
 an explicit True value.
+
+@item 
+Import of parent package.
 @end itemize
 
 The default is that warnings for redundant constructs are not given.
@@ -29241,8 +29244,8 @@ to permit their use in free software.
 
 @printindex ge
 
-@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{  }
 @anchor{cf}@w{  }
+@anchor{gnat_ugn/gnat_utility_programs switches-related-to-project-files}@w{  }
 
 @c %**end of body
 @bye




[Ada] Fix comment about subprogram unnesting and unconstrained arrays

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
The original code for subprogram unnesting used 'Access for
unconstrained arrays. This was recently changed to 'Unchecked_Access for
GNAT-to-LLVM, but a reference to 'Access still appears in the comment.

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

gcc/ada/

* exp_unst.adb (Unnest_Subprogram): Sync comment with the
current code.diff --git a/gcc/ada/exp_unst.adb b/gcc/ada/exp_unst.adb
--- a/gcc/ada/exp_unst.adb
+++ b/gcc/ada/exp_unst.adb
@@ -2093,7 +2093,8 @@ package body Exp_Unst is
 
  --  Build and insert the assignment:
  --ARECn.nam := nam'Address
- --  or else 'Access for unconstrained array
+ --  or else 'Unchecked_Access for
+ --  unconstrained array.
 
  if Needs_Fat_Pointer (Ent) then
 Attr := Name_Unchecked_Access;




[Ada] Fix inconsistent quoting in messages about compile-time errors

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
In some messages of the form "XXX_Error will be raised at run time" the
XXX_Error was enclosed in quotes, in other it was not. Now all messages
of this form are emitted without quotes.

Note: in messages emitted from routine Possible_Local_Raise we still
quote names of exceptions, but there indeed any exception name can
appear and quotes seem to be the right choice.

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

gcc/ada/

* exp_ch4.adb (Raise_Accessibility_Error): Move exception name
to the message string; move << control characters to the end,
for consistency.
* sem_ch6.adb (Analyze_Function_Return): Likewise.
* sem_util.adb (Compile_Time_Constraint_Error): Likewise.
* gcc-interface/decl.c (gnat_to_gnu_entity): Remove quotes
around Storage_Error.
* gcc-interface/trans.c (gnat_to_gnu): Remove quotes around
Constraint_Error.

gcc/testsuite/

* gnat.dg/aggr26.adb: Update expected error message.diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -11885,8 +11885,8 @@ package body Exp_Ch4 is
  Reason => PE_Accessibility_Check_Failed));
  Set_Etype (N, Target_Type);
 
- Error_Msg_N ("< (others => 0));  --  { dg-warning "\"Storage_Error\" will be raised at run time" }
+H : array (Positive) of Row := (others => (others => 0));  --  { dg-warning "Storage_Error will be raised at run time" }
 
 begin
null;




[Ada] Consistent suppression for warnings inside null loops

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Warnings for nodes inside null loops were suppressed if posted with
Error_Msg_NLE and emitted if posted with other error-reporting routines.
This was inconsistent and error-prone.

Part of removing quotes around exception names in messages, because
messages without quotes will be now emitted by Error_Msg and not by
Error_Msg_NLE.

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

gcc/ada/

* errout.adb (Error_Msg): Move warning suppression code from
Error_Msg_NLE
(Error_Msg_NLE): Warning suppression is now done by the internal
call to Error_Msg.diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -440,6 +440,28 @@ package body Errout is
 and then Warnings_Detected >= Maximum_Messages
   then
  return;
+
+  --  Suppress warnings inside a loop that is known to be null or is
+  --  probably null (i.e. when loop executes only if invalid values
+  --  present). In either case warnings in the loop are likely to be junk.
+
+  elsif Is_Warning_Msg and then Present (N) then
+
+ declare
+P : Node_Id;
+
+ begin
+P := Parent (N);
+while Present (P) loop
+   if Nkind (P) = N_Loop_Statement
+ and then Suppress_Loop_Warnings (P)
+   then
+  return;
+   end if;
+
+   P := Parent (P);
+end loop;
+ end;
   end if;
 
   --  The idea at this stage is that we have two kinds of messages
@@ -1490,26 +1512,6 @@ package body Errout is
 Last_Killed := True;
 return;
  end if;
-
- --  Suppress if inside loop that is known to be null or is probably
- --  null (case where loop executes only if invalid values present).
- --  In either case warnings in the loop are likely to be junk.
-
- declare
-P : Node_Id;
-
- begin
-P := Parent (N);
-while Present (P) loop
-   if Nkind (P) = N_Loop_Statement
- and then Suppress_Loop_Warnings (P)
-   then
-  return;
-   end if;
-
-   P := Parent (P);
-end loop;
- end;
   end if;
 
   --  Test for message to be output




[Ada] Remove unnecessary guard for inserting non-empty list

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Calls to Insert_List_After and Insert_List_Before applied to empty lists
do nothing, so there is no need to explicitly guard against such calls.

Code cleanup; semantics is unaffected.

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

gcc/ada/

* exp_ch3.adb (Expand_N_Object_Declaration): Remove unnecessary
guards.
* exp_ch4.adb (Expand_N_If_Expression): Likewise; clarify comment.
* exp_ch5.adb (Expand_N_If_Statement,
Expand_Iterator_Loop_Over_Container): Likewise.
* exp_ch9.adb (Expand_N_Task_Type_Declaration): Remove redundant
guard.
* freeze.adb (Freeze_All_Ent): Reduce scope of a local variable.diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -6908,9 +6908,7 @@ package body Exp_Ch3 is
New_Nodes := Make_DT (Base_Typ, N);
 end if;
 
-if not Is_Empty_List (New_Nodes) then
-   Insert_List_Before (N, New_Nodes);
-end if;
+Insert_List_Before (N, New_Nodes);
  end;
   end if;
 


diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -6198,18 +6198,10 @@ package body Exp_Ch4 is
  Set_Sloc (Parent (N), Loc);
   end if;
 
-  --  Make sure Then_Actions and Else_Actions are appropriately moved
-  --  to the new if statement.
+  --  Move Then_Actions and Else_Actions, if any, to the new if statement
 
-  if Present (Then_Actions (N)) then
- Insert_List_Before
-   (First (Then_Statements (New_If)), Then_Actions (N));
-  end if;
-
-  if Present (Else_Actions (N)) then
- Insert_List_Before
-   (First (Else_Statements (New_If)), Else_Actions (N));
-  end if;
+  Insert_List_Before (First (Then_Statements (New_If)), Then_Actions (N));
+  Insert_List_Before (First (Else_Statements (New_If)), Else_Actions (N));
 
   Insert_Action (N, Decl);
   Insert_Action (N, New_If);


diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -4559,9 +4559,7 @@ package body Exp_Ch5 is
 
Set_Else_Statements (N, New_List (New_If));
 
-   if Present (Condition_Actions (E)) then
-  Insert_List_Before (New_If, Condition_Actions (E));
-   end if;
+   Insert_List_Before (New_If, Condition_Actions (E));
 
Remove (E);
 
@@ -5455,9 +5453,7 @@ package body Exp_Ch5 is
   --  Condition_Actions of the iterator. Insert them now at the head of
   --  the loop.
 
-  if Present (Condition_Actions (Isc)) then
- Insert_List_Before (N, Condition_Actions (Isc));
-  end if;
+  Insert_List_Before (N, Condition_Actions (Isc));
 
   Rewrite (N, New_Loop);
   Analyze (N);


diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -12516,13 +12516,7 @@ package body Exp_Ch9 is
  --  procedure for this corresponding record type and we won't get it
  --  in time if we don't freeze now.
 
- declare
-L : constant List_Id := Freeze_Entity (Rec_Ent, N);
- begin
-if Is_Non_Empty_List (L) then
-   Insert_List_After (Body_Decl, L);
-end if;
- end;
+ Insert_List_After (Body_Decl, List => Freeze_Entity (Rec_Ent, N));
   end if;
 
   --  Complete the expansion of access types to the current task type, if


diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -2354,7 +2354,6 @@ package body Freeze is
   procedure Freeze_All_Ent (From : Entity_Id; After : in out Node_Id) is
  E : Entity_Id;
  Flist : List_Id;
- Lastn : Node_Id;
 
  procedure Process_Flist;
  --  If freeze nodes are present, insert and analyze, and reset cursor
@@ -2365,6 +2364,7 @@ package body Freeze is
  ---
 
  procedure Process_Flist is
+Lastn : Node_Id;
  begin
 if Is_Non_Empty_List (Flist) then
Lastn := Next (After);




[Ada] Remove unnecessary guards for appending non-empty lists

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Calls to Append_List and Append_List_To applied with empty lists do
nothing, so there is no need to explicitly guard against such calls.

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

gcc/ada/

* exp_ch3.adb (Build_Init_Procedure): Remove unnecessary guard.
* exp_disp.adb (Make_DT): Likewise.
* sem_ch12.adb (Analyze_Associations): Likewise.diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -2885,9 +2885,7 @@ package body Exp_Ch3 is
   Fixed_Comps=> False,
   Variable_Comps => True);
 
-   if Is_Non_Empty_List (Init_Tags_List) then
-  Append_List_To (Body_Stmts, Init_Tags_List);
-   end if;
+   Append_List_To (Body_Stmts, Init_Tags_List);
 end if;
  end if;
 


diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
--- a/gcc/ada/exp_disp.adb
+++ b/gcc/ada/exp_disp.adb
@@ -6379,9 +6379,7 @@ package body Exp_Disp is
New_List (New_Occurrence_Of (DT_Ptr, Loc;
   end if;
 
-  if not Is_Empty_List (Elab_Code) then
- Append_List_To (Result, Elab_Code);
-  end if;
+  Append_List_To (Result, Elab_Code);
 
   --  Populate the two auxiliary tables used for dispatching asynchronous,
   --  conditional and timed selects for synchronized types that implement


diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -2248,9 +2248,7 @@ package body Sem_Ch12 is
   --  explicit box associations for the formals that are covered by an
   --  Others_Choice.
 
-  if not Is_Empty_List (Default_Formals) then
- Append_List (Default_Formals, Formals);
-  end if;
+  Append_List (Default_Formals, Formals);
 
   return Assoc_List;
end Analyze_Associations;




[Ada] Check scalar range in arrays constructed by concatenation

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
When concatenating scalars, we should check their range as in the
following example:

type uint8 is range 0 .. 255;
type Array_Type is array (Positive range <>) of uint8;

Array_1 : Array_Type := 42 & 256;

This commit leads to emitting:
- a warning if a constraint error is expected but the scalar fits in the
  base type.
- an error if it does not fit in the base type

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

gcc/ada/

* sem_res.adb (Resolve_Op_Concat_Arg): Check range when
concatenating scalars.diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -10185,7 +10185,7 @@ package body Sem_Res is
("\\interpretation as call yields&", Arg, Typ);
  Error_Msg_NE
("\\interpretation as indexing of call yields&",
- Arg, Component_Type (Typ));
+ Arg, Ctyp);
 
   else
  Error_Msg_N ("ambiguous operand for concatenation!", Arg);
@@ -10208,10 +10208,30 @@ package body Sem_Res is
end;
 end if;
 
-Resolve (Arg, Component_Type (Typ));
+Resolve (Arg, Ctyp);
 
 if Nkind (Arg) = N_String_Literal then
-   Set_Etype (Arg, Component_Type (Typ));
+   Set_Etype (Arg, Ctyp);
+
+elsif Is_Scalar_Type (Etype (Arg))
+  and then Compile_Time_Known_Value (Arg)
+then
+   --  Determine if the out-of-range violation constitutes a
+   --  warning or an error according to the expression base type,
+   --  according to Ada 2022 RM 4.9 (35/2).
+
+   if Is_Out_Of_Range (Arg, Base_Type (Ctyp)) then
+  Apply_Compile_Time_Constraint_Error
+(Arg, "value not in range of}", CE_Range_Check_Failed,
+ Ent => Base_Type (Ctyp),
+ Typ => Base_Type (Ctyp));
+
+   elsif Is_Out_Of_Range (Arg, Ctyp) then
+  Apply_Compile_Time_Constraint_Error
+(Arg, "value not in range of}??", CE_Range_Check_Failed,
+ Ent => Ctyp,
+ Typ => Ctyp);
+   end if;
 end if;
 
 if Arg = Left_Opnd (N) then




[Ada] treepr: print value only for discrete types

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
Follow-on to previous change "Print value of static expression".
Print only if the type is discrete.

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

gcc/ada/

* treepr.adb (Print_Node_Ref): Change "not Is_Array_Type" to
"Is_Discrete_Type".diff --git a/gcc/ada/treepr.adb b/gcc/ada/treepr.adb
--- a/gcc/ada/treepr.adb
+++ b/gcc/ada/treepr.adb
@@ -1643,13 +1643,13 @@ package body Treepr is
 end if;
  end if;
 
- --  If this is an integer-like expression whose value is known, print
- --  that value.
+ --  If this is a discrete expression whose value is known, print that
+ --  value.
 
  if Nkind (N) in N_Subexpr
and then Compile_Time_Known_Value (N)
and then Present (Etype (N))
-   and then not Is_Array_Type (Etype (N))
+   and then Is_Discrete_Type (Etype (N))
  then
 if Is_Entity_Name (N) -- e.g. enumeration literal
   or else Nkind (N) in N_Integer_Literal




[Ada] Use non-internal representation for access subprograms if UC to Address

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
If we have an Unchecked_Conversion between an access to subprogram and
System.Address, we want to try to use a thin subprogram pointer. Try to
do this automatically as much as possible and add one to the RTS.

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

gcc/ada/

* libgnat/g-spipat.ads (Boolean_Func, Natural_Func,
VString_Func): Mark as Favor_Top_Level.
* sem_ch13.adb (Validate_Unchecked_Conversion): Avoid using
internal representation if Unchecked_Conversion between
an access to subprogram and System.Address within the same unit.diff --git a/gcc/ada/libgnat/g-spipat.ads b/gcc/ada/libgnat/g-spipat.ads
--- a/gcc/ada/libgnat/g-spipat.ads
+++ b/gcc/ada/libgnat/g-spipat.ads
@@ -654,19 +654,19 @@ package GNAT.Spitbol.Patterns is
--  operations for constructing patterns that can be used in the pattern
--  matching operations provided.
 
-   type Boolean_Func is access function return Boolean;
+   type Boolean_Func is access function return Boolean with Favor_Top_Level;
--  General Boolean function type. When this type is used as a formal
--  parameter type in this package, it indicates a deferred predicate
--  pattern. The function will be called when the pattern element is
--  matched and failure signalled if False is returned.
 
-   type Natural_Func is access function return Natural;
+   type Natural_Func is access function return Natural with Favor_Top_Level;
--  General Natural function type. When this type is used as a formal
--  parameter type in this package, it indicates a deferred pattern.
--  The function will be called when the pattern element is matched
--  to obtain the currently referenced Natural value.
 
-   type VString_Func is access function return VString;
+   type VString_Func is access function return VString with Favor_Top_Level;
--  General VString function type. When this type is used as a formal
--  parameter type in this package, it indicates a deferred pattern.
--  The function will be called when the pattern element is matched


diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -17546,6 +17546,22 @@ package body Sem_Ch13 is
  Set_No_Strict_Aliasing (Implementation_Base_Type (Target));
   end if;
 
+  --  If the unchecked conversion is between Address and an access
+  --  subprogram type, show that we shouldn't use an internal
+  --  representation for the access subprogram type.
+
+  if Is_Access_Subprogram_Type (Target)
+and then Is_Descendant_Of_Address (Source)
+and then In_Same_Source_Unit (Target, N)
+  then
+ Set_Can_Use_Internal_Rep (Target, False);
+  elsif Is_Access_Subprogram_Type (Source)
+and then Is_Descendant_Of_Address (Target)
+and then In_Same_Source_Unit (Source, N)
+  then
+ Set_Can_Use_Internal_Rep (Source, False);
+  end if;
+
   --  Generate N_Validate_Unchecked_Conversion node for back end in case
   --  the back end needs to perform special validation checks.
 




[Ada] treepr: Print value of static expression

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
When printing a node, if it happens to be an integer-like expression
whose value is known, print that value. This makes debugging a little
easier.

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

gcc/ada/

* treepr.adb (Print_Node_Ref): Print the value if available.diff --git a/gcc/ada/treepr.adb b/gcc/ada/treepr.adb
--- a/gcc/ada/treepr.adb
+++ b/gcc/ada/treepr.adb
@@ -37,6 +37,7 @@ with Namet;use Namet;
 with Nlists;   use Nlists;
 with Output;   use Output;
 with Seinfo;   use Seinfo;
+with Sem_Eval; use Sem_Eval;
 with Sinfo;use Sinfo;
 with Sinfo.Nodes;  use Sinfo.Nodes;
 with Sinfo.Utils;  use Sinfo.Utils;
@@ -1642,6 +1643,24 @@ package body Treepr is
 end if;
  end if;
 
+ --  If this is an integer-like expression whose value is known, print
+ --  that value.
+
+ if Nkind (N) in N_Subexpr
+   and then Compile_Time_Known_Value (N)
+   and then Present (Etype (N))
+   and then not Is_Array_Type (Etype (N))
+ then
+if Is_Entity_Name (N) -- e.g. enumeration literal
+  or else Nkind (N) in N_Integer_Literal
+ | N_Character_Literal
+ | N_Unchecked_Type_Conversion
+then
+   Print_Str (" val = ");
+   UI_Write (Expr_Value (N));
+end if;
+ end if;
+
  if Nkind (N) in N_Entity then
 Write_Str (" (Entity_Id=");
  else




[Ada] Add an option to Get_Fullest_View to not recurse

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
This option is used by GNAT LLVM.

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

gcc/ada/

* sem_util.ads, sem_util.adb (Get_Fullest_View): Add option to
not recurse and return the next-most-fullest view.diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -10926,7 +10926,12 @@ package body Sem_Util is
--
 
function Get_Fullest_View
- (E : Entity_Id; Include_PAT : Boolean := True) return Entity_Id is
+ (E   : Entity_Id;
+  Include_PAT : Boolean := True;
+  Recurse : Boolean := True) return Entity_Id
+   is
+  New_E : Entity_Id := Empty;
+
begin
   --  Prevent cascaded errors
 
@@ -10934,47 +10939,45 @@ package body Sem_Util is
  return E;
   end if;
 
-  --  Strictly speaking, the recursion below isn't necessary, but
-  --  it's both simplest and safest.
+  --  Look at each kind of entity to see where we may need to go deeper.
 
   case Ekind (E) is
  when Incomplete_Kind =>
 if From_Limited_With (E) then
-   return Get_Fullest_View (Non_Limited_View (E), Include_PAT);
+   New_E := Non_Limited_View (E);
 elsif Present (Full_View (E)) then
-   return Get_Fullest_View (Full_View (E), Include_PAT);
+   New_E := Full_View (E);
 elsif Ekind (E) = E_Incomplete_Subtype then
-   return Get_Fullest_View (Etype (E));
+   New_E := Etype (E);
 end if;
 
  when Private_Kind =>
 if Present (Underlying_Full_View (E)) then
-   return
- Get_Fullest_View (Underlying_Full_View (E), Include_PAT);
+   New_E := Underlying_Full_View (E);
 elsif Present (Full_View (E)) then
-   return Get_Fullest_View (Full_View (E), Include_PAT);
+   New_E := Full_View (E);
 elsif Etype (E) /= E then
-   return Get_Fullest_View (Etype (E), Include_PAT);
+   New_E := Etype (E);
 end if;
 
  when Array_Kind =>
 if Include_PAT and then Present (Packed_Array_Impl_Type (E)) then
-   return Get_Fullest_View (Packed_Array_Impl_Type (E));
+   New_E := Packed_Array_Impl_Type (E);
 end if;
 
  when E_Record_Subtype =>
 if Present (Cloned_Subtype (E)) then
-   return Get_Fullest_View (Cloned_Subtype (E), Include_PAT);
+   New_E := Cloned_Subtype (E);
 end if;
 
  when E_Class_Wide_Type =>
-return Get_Fullest_View (Root_Type (E), Include_PAT);
+New_E := Root_Type (E);
 
  when E_Class_Wide_Subtype =>
 if Present (Equivalent_Type (E)) then
-   return Get_Fullest_View (Equivalent_Type (E), Include_PAT);
+   New_E := Equivalent_Type (E);
 elsif Present (Cloned_Subtype (E)) then
-   return Get_Fullest_View (Cloned_Subtype (E), Include_PAT);
+   New_E := Cloned_Subtype (E);
 end if;
 
  when E_Protected_Subtype
@@ -10983,25 +10986,29 @@ package body Sem_Util is
 | E_Task_Type
  =>
 if Present (Corresponding_Record_Type (E)) then
-   return Get_Fullest_View (Corresponding_Record_Type (E),
-Include_PAT);
+   New_E := Corresponding_Record_Type (E);
 end if;
 
  when E_Access_Protected_Subprogram_Type
 | E_Anonymous_Access_Protected_Subprogram_Type
  =>
 if Present (Equivalent_Type (E)) then
-   return Get_Fullest_View (Equivalent_Type (E), Include_PAT);
+   New_E := Equivalent_Type (E);
 end if;
 
  when E_Access_Subtype =>
-return Get_Fullest_View (Base_Type (E), Include_PAT);
+New_E := Base_Type (E);
 
  when others =>
 null;
   end case;
 
-  return E;
+  --  If we found a fuller view, either return it or recurse. Otherwise,
+  --  return our input.
+
+  return (ifNo (New_E) then E
+  elsif Recurse then Get_Fullest_View (New_E, Include_PAT, Recurse)
+  else  New_E);
end Get_Fullest_View;
 



diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -1354,10 +1354,13 @@ package Sem_Util is
--CRec_Typ  - the corresponding record type of the full views
 
function Get_Fullest_View
- (E : Entity_Id; Include_PAT : Boolean := True) return Entity_Id;
+ (E   : Entity_Id;
+  Include_PAT : Boolean := True;
+  Recurse : Boolean := True) return Entity_Id;
--  Get the fullest possible view of E, looking through private, limited,
--  packed array and other implementation types. If 

[Ada] Warn on import of parent package

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
There is no need to say "with P;" in package P.Q.  This patch adds a
warning for that case.

We also remove with clauses in our own code that trigger the warning.

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

gcc/ada/

* sem_ch10.adb (Check_Redundant_Withs): Add a warning if a
library unit with's its own ancestor. Note that this warning is
not triggered for something like "with P.R;" in P.Q, because
there the "with P;" is considered implicit.
* fname-sf.adb, libgnarl/s-stusta.adb, libgnarl/s-tasdeb.ads,
libgnat/a-calfor.adb, libgnat/a-tiboio.adb,
libgnat/a-wwboio.adb, libgnat/a-zzboio.adb, libgnat/i-cobol.adb,
libgnat/s-bitops.adb, libgnat/s-bitops.ads,
libgnat/s-direio.adb, libgnat/s-dwalin.adb,
libgnat/s-geveop.adb, libgnat/s-mmosin__unix.adb,
libgnat/s-os_lib.adb, libgnat/s-os_lib.ads,
libgnat/s-pooglo.ads, libgnat/s-secsta.adb,
libgnat/s-shasto.adb, libgnat/s-stausa.ads,
libgnat/s-stratt.ads, libgnat/s-ststop.adb: Remove with of
parent.
* sinfo.ads: Minor comment fix.diff --git a/gcc/ada/fname-sf.adb b/gcc/ada/fname-sf.adb
--- a/gcc/ada/fname-sf.adb
+++ b/gcc/ada/fname-sf.adb
@@ -24,7 +24,6 @@
 --
 
 with Casing;use Casing;
-with Fname; use Fname;
 with Fname.UF;  use Fname.UF;
 with SFN_Scan;  use SFN_Scan;
 with Osint; use Osint;


diff --git a/gcc/ada/libgnarl/s-stusta.adb b/gcc/ada/libgnarl/s-stusta.adb
--- a/gcc/ada/libgnarl/s-stusta.adb
+++ b/gcc/ada/libgnarl/s-stusta.adb
@@ -29,8 +29,6 @@
 --  --
 --
 
-with System.Stack_Usage;
-
 --  This is why this package is part of GNARL:
 
 with System.Tasking.Debug;


diff --git a/gcc/ada/libgnarl/s-tasdeb.ads b/gcc/ada/libgnarl/s-tasdeb.ads
--- a/gcc/ada/libgnarl/s-tasdeb.ads
+++ b/gcc/ada/libgnarl/s-tasdeb.ads
@@ -32,7 +32,6 @@
 --  This package encapsulates all direct interfaces to task debugging services
 --  that are needed by gdb with gnat mode.
 
-with System.Tasking;
 with System.OS_Interface;
 
 package System.Tasking.Debug is


diff --git a/gcc/ada/libgnat/a-calfor.adb b/gcc/ada/libgnat/a-calfor.adb
--- a/gcc/ada/libgnat/a-calfor.adb
+++ b/gcc/ada/libgnat/a-calfor.adb
@@ -29,7 +29,6 @@
 --  --
 --
 
-with Ada.Calendar;use Ada.Calendar;
 with Ada.Calendar.Time_Zones; use Ada.Calendar.Time_Zones;
 
 package body Ada.Calendar.Formatting is


diff --git a/gcc/ada/libgnat/a-tiboio.adb b/gcc/ada/libgnat/a-tiboio.adb
--- a/gcc/ada/libgnat/a-tiboio.adb
+++ b/gcc/ada/libgnat/a-tiboio.adb
@@ -29,7 +29,6 @@
 --  --
 --
 
-with Ada.Text_IO; use Ada.Text_IO;
 with Ada.Unchecked_Deallocation;
 
 package body Ada.Text_IO.Bounded_IO is


diff --git a/gcc/ada/libgnat/a-wwboio.adb b/gcc/ada/libgnat/a-wwboio.adb
--- a/gcc/ada/libgnat/a-wwboio.adb
+++ b/gcc/ada/libgnat/a-wwboio.adb
@@ -29,7 +29,6 @@
 --  --
 --
 
-with Ada.Wide_Text_IO; use Ada.Wide_Text_IO;
 with Ada.Unchecked_Deallocation;
 
 package body Ada.Wide_Text_IO.Wide_Bounded_IO is


diff --git a/gcc/ada/libgnat/a-zzboio.adb b/gcc/ada/libgnat/a-zzboio.adb
--- a/gcc/ada/libgnat/a-zzboio.adb
+++ b/gcc/ada/libgnat/a-zzboio.adb
@@ -29,7 +29,6 @@
 --  --
 --
 
-with Ada.Wide_Wide_Text_IO; use Ada.Wide_Wide_Text_IO;
 with Ada.Unchecked_Deallocation;
 
 package body Ada.Wide_Wide_Text_IO.Wide_Wide_Bounded_IO is


diff --git a/gcc/ada/libgnat/i-cobol.adb b/gcc/ada/libgnat/i-cobol.adb
--- a/gcc/ada/libgnat/i-cobol.adb
+++ b/gcc/ada/libgnat/i-cobol.adb
@@ -34,8 +34,7 @@
 --  particular COBOL format is completely contained in the private part of
 --  the spec.
 
-with Interfaces; use Interfaces;
-with System; use System;
+with System; use System;
 with Ada.Unchecked_Conversion;
 
 package body Interfaces.COBOL is


diff --git a/gcc/ada/libgnat/s-bitops.adb b/gcc/ada/libgnat/s-bitops.adb
--- a/gcc/ada/libgnat/s-bitops.adb
+++ b/gcc/ada/libgnat/s-bitops.adb
@@ -29,8 +29,7 @@
 --  --
 --
 
-with System; use System;
-with System.Unsigned_Types;  use System.Unsigned_Types;
+with 

[Ada] Small cleanup of osint-m.adb

2022-01-07 Thread Pierre-Marie de Rodat via Gcc-patches
We remove the "pragma Elaborate_All (Osint)", because it is no longer
needed. That allows us to remove the "with Osint" (i.e. with of our own
parent).

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

gcc/ada/

* osint-m.adb: Remove with_clause and pragma.diff --git a/gcc/ada/osint-m.adb b/gcc/ada/osint-m.adb
--- a/gcc/ada/osint-m.adb
+++ b/gcc/ada/osint-m.adb
@@ -23,17 +23,6 @@
 --  --
 --
 
-with Osint;
-
-pragma Elaborate_All (Osint);
---  This pragma is needed because of the call to Set_Program in the
---  elaboration of the package. We cannot rely on the static model
---  of elaboration since the compiler is routinely compiled with
---  checks off (-gnatp), and with older versions of the compiler
---  (up to and including most 5.04 wavefronts), -gnatp suppresses
---  the static elaboration check mechanisms. It could be removed
---  one day, but there really is no need to do so.
-
 package body Osint.M is
 
---




Re: [PATCH v4] c-format: Add -Wformat-int-precision option [PR80060]

2022-01-07 Thread Daniil Stas via Gcc-patches
On Tue, 21 Dec 2021 00:43:24 +0200
Daniil Stas  wrote:

> On Sat, 27 Nov 2021 22:18:23 +
> Daniil Stas  wrote:
> 
> > This option is enabled by default when -Wformat option is enabled. A
> > user can specify -Wno-format-int-precision to disable emitting
> > warnings when passing an argument of an incompatible integer type to
> > a 'd', 'i', 'b', 'B', 'o', 'u', 'x', or 'X' conversion specifier
> > when it has the same precision as the expected type.
> > 
> > Signed-off-by: Daniil Stas 
> > 
> > gcc/c-family/ChangeLog:
> > 
> > * c-format.c (check_format_types): Don't emit warnings when
> > passing an argument of an incompatible integer type to
> > a 'd', 'i', 'b', 'B', 'o', 'u', 'x', or 'X' conversion
> > specifier when it has the same precision as the expected
> > type if -Wno-format-int-precision option is specified.
> > * c.opt: Add -Wformat-int-precision option.
> > 
> > gcc/ChangeLog:
> > 
> > * doc/invoke.texi: Add -Wformat-int-precision option
> > description.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * c-c++-common/Wformat-int-precision-1.c: New test.
> > * c-c++-common/Wformat-int-precision-2.c: New test.
> > ---
> > Changes for v4:
> >   - Added 'b' and 'B' format specifiers to the option descriptions.
> > 
> > Changes for v3:
> >   - Added additional @code{} derictives to the documentation where
> > needed.
> >   - Changed tests to run on "! long_neq_int" target instead of
> > "lp64".
> >   - Added a test case to check that gcc still emits warnings for
> > arguments with different precision even with
> > -Wno-format-int-precision option enabled.
> > 
> > Changes for v2:
> >   - Changed the option name to -Wformat-int-precision.
> >   - Changed the option description as was suggested by Martin.
> >   - Changed Wformat-int-precision-2.c to use dg-bogus instead of
> > previous invalid syntax.
> > 
> >  gcc/c-family/c-format.c |  2 +-
> >  gcc/c-family/c.opt  |  6 ++
> >  gcc/doc/invoke.texi | 17
> > - .../c-c++-common/Wformat-int-precision-1.c  |
> > 7 +++ .../c-c++-common/Wformat-int-precision-2.c  |  8
> >  5 files changed, 38 insertions(+), 2 deletions(-)
> >  create mode 100644
> > gcc/testsuite/c-c++-common/Wformat-int-precision-1.c create mode
> > 100644 gcc/testsuite/c-c++-common/Wformat-int-precision-2.c
> > 
> > diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
> > index e735e092043..c66787f931f 100644
> > --- a/gcc/c-family/c-format.c
> > +++ b/gcc/c-family/c-format.c
> > @@ -4248,7 +4248,7 @@ check_format_types (const substring_loc
> > _loc, && (!pedantic || i < 2)
> >   && char_type_flag)
> > continue;
> > -  if (types->scalar_identity_flag
> > +  if ((types->scalar_identity_flag ||
> > !warn_format_int_precision) && (TREE_CODE (cur_type) == TREE_CODE
> > (wanted_type) || (INTEGRAL_TYPE_P (cur_type)
> >   && INTEGRAL_TYPE_P (wanted_type)))
> > diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
> > index 4b8a094b206..d7d952765c6 100644
> > --- a/gcc/c-family/c.opt
> > +++ b/gcc/c-family/c.opt
> > @@ -684,6 +684,12 @@ C ObjC C++ LTO ObjC++ Warning
> > Alias(Wformat-overflow=, 1, 0) IntegerRange(0, 2) Warn about
> > function calls with format strings that write past the end of the
> > destination region.  Same as -Wformat-overflow=1. 
> > +Wformat-int-precision
> > +C ObjC C++ ObjC++ Var(warn_format_int_precision) Warning
> > LangEnabledBy(C ObjC C++ ObjC++,Wformat=,warn_format >= 1, 0) +Warn
> > when passing an argument of an incompatible integer type to a 'd',
> > 'i', +'b', 'B', 'o', 'u', 'x', or 'X' conversion specifier even when
> > it has the same +precision as the expected type. +
> >  Wformat-security
> >  C ObjC C++ ObjC++ Var(warn_format_security) Warning LangEnabledBy(C
> > ObjC C++ ObjC++,Wformat=, warn_format >= 2, 0) Warn about possible
> > security problems with format functions. diff --git
> > a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index
> > 3bddfbaae6a..94a7ad96c50 100644 --- a/gcc/doc/invoke.texi
> > +++ b/gcc/doc/invoke.texi
> > @@ -351,7 +351,7 @@ Objective-C and Objective-C++ Dialects}.
> >  -Werror  -Werror=*  -Wexpansion-to-defined  -Wfatal-errors @gol
> >  -Wfloat-conversion  -Wfloat-equal  -Wformat  -Wformat=2 @gol
> >  -Wno-format-contains-nul  -Wno-format-extra-args  @gol
> > --Wformat-nonliteral  -Wformat-overflow=@var{n} @gol
> > +-Wformat-nonliteral  -Wformat-overflow=@var{n}
> > -Wformat-int-precision @gol -Wformat-security  -Wformat-signedness
> > -Wformat-truncation=@var{n} @gol -Wformat-y2k  -Wframe-address @gol
> >  -Wframe-larger-than=@var{byte-size}  -Wno-free-nonheap-object @gol
> > @@ -6122,6 +6122,21 @@ If @option{-Wformat} is specified, also warn
> > if the format string is not a string literal and so cannot be
> > checked, unless the format function takes its format arguments as a
> > @code{va_list}. 
> > +@item -Wformat-int-precision
> > 

Re: [PATCH] Fix alignment of stack slots for overaligned types [PR103500]

2022-01-07 Thread H.J. Lu via Gcc-patches
On Fri, Jan 7, 2022 at 7:20 AM Alex Coplan via Gcc-patches
 wrote:
>
> Hi Richard,
>
> Thanks for the review.
>
> On 20/12/2021 13:19, Richard Sandiford wrote:
> > Alex Coplan via Gcc-patches  writes:
> > > Hi,
> > >
> > > This fixes PR103500 i.e. ensuring that stack slots for
> > > passed-by-reference overaligned types are appropriately aligned. For the
> > > testcase:
> > >
> > > typedef struct __attribute__((aligned(32))) {
> > >   long x,y;
> > > } S;
> > > S x;
> > > void f(S);
> > > void g(void) { f(x); }
> > >
> > > on AArch64, we currently generate (at -O2):
> > >
> > > g:
> > > adrpx1, .LANCHOR0
> > > add x1, x1, :lo12:.LANCHOR0
> > > stp x29, x30, [sp, -48]!
> > > mov x29, sp
> > > ldp q0, q1, [x1]
> > > add x0, sp, 16
> > > stp q0, q1, [sp, 16]
> > > bl  f
> > > ldp x29, x30, [sp], 48
> > > ret
> > >
> > > so the stack slot for the passed-by-reference copy of the structure is
> > > at sp + 16, and the sp is only guaranteed to be 16-byte aligned, so the
> > > structure is only 16-byte aligned. The PCS requires the structure to be
> > > 32-byte aligned. After this patch, we generate:
> > >
> > > g:
> > > adrpx1, .LANCHOR0
> > > add x1, x1, :lo12:.LANCHOR0
> > > stp x29, x30, [sp, -64]!
> > > mov x29, sp
> > > add x0, sp, 47
> > > ldp q0, q1, [x1]
> > > and x0, x0, -32
> > > stp q0, q1, [x0]
> > > bl  f
> > > ldp x29, x30, [sp], 64
> > > ret
> > >
> > > i.e. we ensure 32-byte alignment for the struct.
> > >
> > > The approach taken here is similar to that in
> > > function.c:assign_parm_setup_block where it handles the case for
> > > DECL_ALIGN (parm) > MAX_SUPPORTED_STACK_ALIGNMENT. This in turn is
> > > similar to the approach taken in cfgexpand.c:expand_stack_vars (where
> > > the function calls get_dynamic_stack_size) which is the code that
> > > handles the alignment for overaligned structures as addressable local
> > > variables (see the related case discussed in the PR).
> >
> > A difference with the latter is that cfgexpand (AFAICT) always
> > honours the DECL/TYPE_ALIGN, with LOCAL_DECL_ALIGNMENT supposedly
> > only increasing the alignment for efficiency reasons (rather than
> > decreasing it).
> >
> > So…
> >
> > > This patch also updates the aapcs64 test mentioned in the PR to avoid
> > > the frontend folding away the alignment check. I've confirmed that the
> > > execution test actually fails on aarch64-linux-gnu prior to the patch
> > > being applied and passes afterwards.
> > >
> > > Bootstrapped and regtested on aarch64-linux-gnu, x86_64-linux-gnu, and
> > > arm-linux-gnueabihf: no regressions.
> > >
> > > I'd appreciate any feedback. Is it OK for trunk?
> > >
> > > Thanks,
> > > Alex
> > >
> > > gcc/ChangeLog:
> > >
> > > PR middle-end/103500
> > > * function.c (get_stack_local_alignment): Align BLKmode overaligned
> > > types to the alignment required by the type.
> > > (assign_stack_temp_for_type): Handle BLKmode overaligned stack
> > > slots by allocating a larger-than-necessary buffer and aligning
> > > the address within appropriately.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > PR middle-end/103500
> > > * gcc.target/aarch64/aapcs64/rec_align-8.c (test_pass_by_ref):
> > > Prevent the frontend from folding our alignment check away by
> > > using snprintf to store the pointer into a string and recovering
> > > it with sscanf.
> > >
> > > diff --git a/gcc/function.c b/gcc/function.c
> > > index 61b3bd036b8..5ed722ab959 100644
> > > --- a/gcc/function.c
> > > +++ b/gcc/function.c
> > > @@ -278,7 +278,9 @@ get_stack_local_alignment (tree type, machine_mode 
> > > mode)
> > >unsigned int alignment;
> > >
> > >if (mode == BLKmode)
> > > -alignment = BIGGEST_ALIGNMENT;
> > > +alignment = (type && TYPE_ALIGN (type) > 
> > > MAX_SUPPORTED_STACK_ALIGNMENT)
> > > +  ? TYPE_ALIGN (type)
> > > +  : BIGGEST_ALIGNMENT;
> >
> > …I'm not sure about this calculation.  Why do we only honour TYPE_ALIGN
> > if it's greater than MAX_SUPPORTED_STACK_ALIGNMENT, and fall all the
> > way back to BIGGEST_ALIGNMENT otherwise?  It looks like on nvptx
> > this would have the effect of honouring (say) 2048-byte alignment,
> > but not 32-byte alignment (which falls between BIGGEST_ALIGNMENT
> > and MAX_SUPPORTED_STACK_ALIGNMENT).
>
> So, to be honest, this was a bit of a bodge to try and work around
> issues on x86. My original attempt at solving the PR used the more
> obvious calculation you suggest below, i.e. the max of BIGGEST_ALIGNMENT
> and TYPE_ALIGN (type). The problem with that is, on x86,
> MAX_SUPPORTED_STACK_ALIGNMENT has a huge value (2^31).

On x86, stack alignment limit is the limit of stack.   You can
align stack to any values on x86 as long as your stack allows it.

> 

Re: [PATCH] Fix alignment of stack slots for overaligned types [PR103500]

2022-01-07 Thread Alex Coplan via Gcc-patches
Hi Richard,

Thanks for the review.

On 20/12/2021 13:19, Richard Sandiford wrote:
> Alex Coplan via Gcc-patches  writes:
> > Hi,
> >
> > This fixes PR103500 i.e. ensuring that stack slots for
> > passed-by-reference overaligned types are appropriately aligned. For the
> > testcase:
> >
> > typedef struct __attribute__((aligned(32))) {
> >   long x,y;
> > } S;
> > S x;
> > void f(S);
> > void g(void) { f(x); }
> >
> > on AArch64, we currently generate (at -O2):
> >
> > g:
> > adrpx1, .LANCHOR0
> > add x1, x1, :lo12:.LANCHOR0
> > stp x29, x30, [sp, -48]!
> > mov x29, sp
> > ldp q0, q1, [x1]
> > add x0, sp, 16
> > stp q0, q1, [sp, 16]
> > bl  f
> > ldp x29, x30, [sp], 48
> > ret
> >
> > so the stack slot for the passed-by-reference copy of the structure is
> > at sp + 16, and the sp is only guaranteed to be 16-byte aligned, so the
> > structure is only 16-byte aligned. The PCS requires the structure to be
> > 32-byte aligned. After this patch, we generate:
> >
> > g:
> > adrpx1, .LANCHOR0
> > add x1, x1, :lo12:.LANCHOR0
> > stp x29, x30, [sp, -64]!
> > mov x29, sp
> > add x0, sp, 47
> > ldp q0, q1, [x1]
> > and x0, x0, -32
> > stp q0, q1, [x0]
> > bl  f
> > ldp x29, x30, [sp], 64
> > ret
> >
> > i.e. we ensure 32-byte alignment for the struct.
> >
> > The approach taken here is similar to that in
> > function.c:assign_parm_setup_block where it handles the case for
> > DECL_ALIGN (parm) > MAX_SUPPORTED_STACK_ALIGNMENT. This in turn is
> > similar to the approach taken in cfgexpand.c:expand_stack_vars (where
> > the function calls get_dynamic_stack_size) which is the code that
> > handles the alignment for overaligned structures as addressable local
> > variables (see the related case discussed in the PR).
> 
> A difference with the latter is that cfgexpand (AFAICT) always
> honours the DECL/TYPE_ALIGN, with LOCAL_DECL_ALIGNMENT supposedly
> only increasing the alignment for efficiency reasons (rather than
> decreasing it).
> 
> So…
> 
> > This patch also updates the aapcs64 test mentioned in the PR to avoid
> > the frontend folding away the alignment check. I've confirmed that the
> > execution test actually fails on aarch64-linux-gnu prior to the patch
> > being applied and passes afterwards.
> >
> > Bootstrapped and regtested on aarch64-linux-gnu, x86_64-linux-gnu, and
> > arm-linux-gnueabihf: no regressions.
> >
> > I'd appreciate any feedback. Is it OK for trunk?
> >
> > Thanks,
> > Alex
> >
> > gcc/ChangeLog:
> >
> > PR middle-end/103500
> > * function.c (get_stack_local_alignment): Align BLKmode overaligned
> > types to the alignment required by the type.
> > (assign_stack_temp_for_type): Handle BLKmode overaligned stack
> > slots by allocating a larger-than-necessary buffer and aligning
> > the address within appropriately.
> >
> > gcc/testsuite/ChangeLog:
> >
> > PR middle-end/103500
> > * gcc.target/aarch64/aapcs64/rec_align-8.c (test_pass_by_ref):
> > Prevent the frontend from folding our alignment check away by
> > using snprintf to store the pointer into a string and recovering
> > it with sscanf.
> >
> > diff --git a/gcc/function.c b/gcc/function.c
> > index 61b3bd036b8..5ed722ab959 100644
> > --- a/gcc/function.c
> > +++ b/gcc/function.c
> > @@ -278,7 +278,9 @@ get_stack_local_alignment (tree type, machine_mode mode)
> >unsigned int alignment;
> >  
> >if (mode == BLKmode)
> > -alignment = BIGGEST_ALIGNMENT;
> > +alignment = (type && TYPE_ALIGN (type) > MAX_SUPPORTED_STACK_ALIGNMENT)
> > +  ? TYPE_ALIGN (type)
> > +  : BIGGEST_ALIGNMENT;
> 
> …I'm not sure about this calculation.  Why do we only honour TYPE_ALIGN
> if it's greater than MAX_SUPPORTED_STACK_ALIGNMENT, and fall all the
> way back to BIGGEST_ALIGNMENT otherwise?  It looks like on nvptx
> this would have the effect of honouring (say) 2048-byte alignment,
> but not 32-byte alignment (which falls between BIGGEST_ALIGNMENT
> and MAX_SUPPORTED_STACK_ALIGNMENT).

So, to be honest, this was a bit of a bodge to try and work around
issues on x86. My original attempt at solving the PR used the more
obvious calculation you suggest below, i.e. the max of BIGGEST_ALIGNMENT
and TYPE_ALIGN (type). The problem with that is, on x86,
MAX_SUPPORTED_STACK_ALIGNMENT has a huge value (2^31).
explow.c:get_dynamic_stack_size has:

  if (size_align % MAX_SUPPORTED_STACK_ALIGNMENT != 0)
{
  size = round_push (size);
  [...]
}
  *psize = size;

so inevitably we end up calling round_push on x86 which in turn ends up
going down the else branch:

  else
{
  /* If crtl->preferred_stack_boundary might still grow, use
 virtual_preferred_stack_boundary_rtx instead.  This will be
 substituted by the right value in vregs 

Re: [committed] c++: Add testcase for recently fixed PR [PR69681]

2022-01-07 Thread Patrick Palka via Gcc-patches
On Fri, 7 Jan 2022, Jakub Jelinek wrote:

> On Thu, Jan 06, 2022 at 10:44:09AM -0500, Patrick Palka via Gcc-patches wrote:
> > Fixed ever since r12-6188.
> > 
> > PR c++/69681
> > 
> > gcc/testsuite/ChangeLog:
> > 
> > * g++.dg/cpp0x/constexpr-compare2.C: New test.
> 
> Note, I've tested my
> https://gcc.gnu.org/pipermail/gcc-patches/2022-January/587745.html
> patch before you've committed this test, that patch makes it FAIL
> again.
> 
> The thing is that in address_compare now we make it all the way to
>   tree sz0 = DECL_SIZE_UNIT (base0);
>   tree sz1 = DECL_SIZE_UNIT (base1);
>   /* If sizes are unknown, e.g. VLA or not representable, punt.  */
>   if (!tree_fits_poly_int64_p (sz0) || !tree_fits_poly_int64_p (sz1))
> return 2;
> which wants to check if one pointer is to a start of one object and
> another pointer to the end of another one.  But, base0 and base1
> are both FUNCTION_DECLs, and those seem to never have DECL_SIZE_UNIT
> set on them, whether the functions are external or defined locally.
> 
> We've already proven that base0 and base1 are different.  Can we
> with folding_initializer set (or even unset?) assume that if one
> or both of the bases are FUNCTION_DECLs they will compare unequal
> regardless if the other pointer is at the start or end of some
> variable?  For the !folding_initializer case, one thing is that
> while we've dealt with aliases visible to the compiler already and
> punted, there could again be aliases not visible to the compiler
> etc.  There is also a theoretical chance that .text section
> with some functions in it could be immediately followed by .rodata
> section with variables, but zero sized functions are rare and using
> address arithmetics to get to the end of a function isn't something
> we should support.  Some functions and variables could be also
> defined in assembly and could be adjacent...
> So at least limiting it to folding_initializer would be wise,
> but the question is what exactly should be valid and what should
> be invalid in C++.
> 
> So, thoughts on this?

Not totally sure but since pointer arithmetic on a function pointer
isn't a valid C++ constant expression, I suppose we could also restrict
ourselves to the case where both offsets are 0.  So probably returning
0 for FUNCTION_DECL if folding_initializer && ioff0 == 0 && ioff1 == 0
might be sufficient.

Then again, I don't see why we'd want to treat functions differently
from other decls when the offsets are 0, so perhaps we could relax
this to folding_initializer && ioff0 == 0 && ioff1 == 0.

> 
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-compare2.C
> > @@ -0,0 +1,10 @@
> > +// PR c++/69681
> > +// { dg-do compile { target c++11 } }
> > +
> > +void f();
> > +void g();
> > +static_assert(f != g, "");
> > +
> > +#if __cpp_constexpr >= 201603L
> > +static_assert([]{} != []{}, "");
> > +#endif
> > -- 
> > 2.34.1.493.ge83ba647f7
> 
>   Jakub
> 
> 



Re: [PATCH 3/6] ira: Add ira_subloop_allocnos_can_differ_p

2022-01-07 Thread Vladimir Makarov via Gcc-patches



On 2022-01-06 09:47, Richard Sandiford wrote:

color_pass has two instances of the same code for propagating non-cap
assignments from parent loops to subloops.  This patch adds a helper
function for testing when such propagations are required for correctness
and uses it to remove the duplicated code.

A later patch will use this in ira-build.c too, which is why the
function is exported to ira-int.h.

No functional change intended.

gcc/
PR rtl-optimization/98782
* ira-int.h (ira_subloop_allocnos_can_differ_p): New function,
extracted from...
* ira-color.c (color_pass): ...here.

OK.



Re: [PATCH 2/6] ira: Add comments and fix move_spill_restore calculation

2022-01-07 Thread Vladimir Makarov via Gcc-patches



On 2022-01-06 09:46, Richard Sandiford wrote:

This patch adds comments to describe each use of ira_loop_border_costs.
I think this highlights that move_spill_restore was using the wrong cost
in one case, which came from tranposing [0] and [1] in the original
(pre-ira_loop_border_costs) ira_memory_move_cost expressions.  The
difference would only be noticeable on targets that distinguish between
load and store costs.

gcc/
PR rtl-optimization/98782
* ira-color.c (color_pass): Add comments to describe the spill costs.
(move_spill_restore): Likewise.  Fix reversed calculation.

OK for me.  Thank you for fixing the cost typo.



Re: [PATCH 1/6] ira: Add a ira_loop_border_costs class

2022-01-07 Thread Vladimir Makarov via Gcc-patches



On 2022-01-06 09:46, Richard Sandiford wrote:

The final index into (ira_)memory_move_cost is 1 for loads and
0 for stores.  Thus the combination:

   entry_freq * memory_cost[1] + exit_freq * memory_cost[0]

is the cost of loading a register on entry to a loop and
storing it back on exit from the loop.  This is the cost to
use if the register is successfully allocated within the
loop but is spilled in the parent loop.  Similarly:

   entry_freq * memory_cost[0] + exit_freq * memory_cost[1]

is the cost of storing a register on entry to the loop and
restoring it on exit from the loop.  This is the cost to
use if the register is spilled within the loop but is
successfully allocated in the parent loop.

The patch adds a helper class for calculating these values and
mechanically replaces the existing instances.  There is no attempt to
editorialise the choice between using “spill inside” and “spill outside”
costs.  (I think one of them is the wrong way round, but a later patch
deals with that.)

No functional change intended.

gcc/
PR rtl-optimization/98782
* ira-int.h (ira_loop_border_costs): New class.
* ira-color.c (ira_loop_border_costs::ira_loop_border_costs):
New constructor.
(calculate_allocno_spill_cost): Use ira_loop_border_costs.
(color_pass): Likewise.
(move_spill_restore): Likewise.

It is OK for me.



Re: [PATCH 0/6] ira: Fix performance regression in exchange2 [PR98782]

2022-01-07 Thread Vladimir Makarov via Gcc-patches



On 2022-01-06 09:45, Richard Sandiford wrote:

This series of patches recovers the exchange2 performance lost in the
GCC 11 timeframe (at least on aarch64 and Power9 -- thanks Pat for
testing the latter).

There are 6 patches, split into two groups of 3.  The first 3 are just
preparatory patches, although patch 2 does contain a minor bug fix.
The other 3 patches are the ones that together fix the regression.

I realise this is a bit invasive for stage 3.  However, the series is
fixing a large regression in an important benchmark and AFAIK there are
no known acceptable mitigations that we could apply instead.  I think
the series is also working with concepts that already exist in IRA:
it's really about tweaking the cost model used to control them.

We also still have at least 3 months (more realistically 4 months) of
testing before GCC 12 is released.  So perhaps one option would be to
apply any approved version of the series now, but with the understanding
that if there's significant fallout (more than a handful of small tweaks
or fixes), we would simply revert the patches rather than trying to
rework them in-situ.  The series is confined to IRA so reverting it
should be simple.  Would that be OK?


Richard. thank you for working on these issues.

I don't think there is a problem with the GCC development stage here.  
These are patches solving existing PR(s).  Of course it is better to do 
such changes earlier at the stage3, so IMHO the timing is right.


I don't expect that the changes will result in serious problems like 
wrong code generation or RA crashes as they are about improving RA 
heuristics.  They can result in new GCC test failures on some targets 
(we have many overconstrained tests expecting an exact GCC output).  If 
we are overwhelmed with the new failures we can revert the patches.


The first 3 patches are ok to commit.  I'll look at the rest 3 ones this 
weekend and write you my opinion on Monday.  I don't think there will be 
a problem with the last 3 patches.  They are clearly improving RA 
heuristics.  I just need some time to think about them.


Thank you again for picking this difficult PR and working on it.


Each patch bootstrapped & regression-tested individually on
aarch64-linux-gnu.  Also tested as a series on aarch64_be-elf,
arm-linux-gnueabihf, powerpc64le-linux-gnu, and x86_64-linux-gnu.





Re: [power-ieee128] RFH: LTO broken

2022-01-07 Thread Thomas Koenig via Gcc-patches



Hi Jakub,


00251038  06ad0015 R_PPC64_JMP_SLOT    
__cabsieee128 + 0
All these should for POWER_IEEE128 use atan2q@QUADMATH_1.0 etc.


So, seems all these come from f951 compiled sources.
For user code, I think the agreement was if you want to use successfully
-mabi=ieeelongdouble, you need glibc 2.32 or later, which is why the Fortran
FE doesn't conditionalize on whether glibc 2.32 is available or not and just
emits __WHATEVERieee128 entrypoints.


That was the idea, I think.


But for Fortran compiled sources in libgfortran, we need to use
__WHATEVERieee128 only if glibc 2.32 or later and WHATEVERq (from
libquadmath) otherwise.
I guess easiest would be to do this always in the FE, but we need to
determine in the FE if the target is glibc 2.32 or later.


Instead of determining this in the front end, maybe we can add
an option (documented, but marked as useful as only for internal
use and with no guarantee that it will remain) and use that option
when compiling libgfortran.


On the other side, on glibc 2.32+ build, we still use some libquadmath APIs
when we shouldn't:
readelf -Wr 
/home/jakub/gcc/obj/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5
 | grep QUADMATH
002502c8  00260015 R_PPC64_JMP_SLOT    
fmaq@QUADMATH_1.0 + 0
002505f8  00670015 R_PPC64_JMP_SLOT    
tanq@QUADMATH_1.0 + 0
00250930  009b0015 R_PPC64_JMP_SLOT    
fabsq@QUADMATH_1.0 + 0
00250940  009d0015 R_PPC64_JMP_SLOT    
sinq@QUADMATH_1.0 + 0
00250c98  00cf0015 R_PPC64_JMP_SLOT    
copysignq@QUADMATH_1.0 + 0
00251038  01070015 R_PPC64_JMP_SLOT    
cosq@QUADMATH_1.0 + 0
00251068  010a0015 R_PPC64_JMP_SLOT    
fmodq@QUADMATH_1.0 + 0
These should use __fmaieee128, __tanieee128 etc. instead.


This one seems easily fixed by the following patch, ok for power-ieee128?


OK!

Best regards

Thomas


Re: [PATCH] libgomp, OpenMP, nvptx: Low-latency memory allocator

2022-01-07 Thread Andrew Stubbs

On 06/01/2022 17:53, Tom de Vries wrote:
My current understanding is that this is a backend problem, and needs to 
be fixed by defining atomic_store patterns which take care of this 
peculiarity.


You mentioned on IRC that I ought to initialize the free chain using 
atomics also, and that you are working on an atomic store implementation.


This patch fixes the initialization issue. It works with my device, I 
think. Please test it with your device when the backend issue is fixed.


Thanks very much!

Andrewlibgomp, nvptx: low-latency memory allocator

This patch adds support for allocating low-latency ".shared" memory on
NVPTX GPU device, via the omp_low_lat_mem_space and omp_alloc.  The memory
can be allocated, reallocated, and freed using a basic but fast algorithm,
is thread safe and the size of the low-latency heap can be configured using
the GOMP_NVPTX_LOWLAT_POOL environment variable.

The use of the PTX dynamic_smem_size feature means that the minimum version
requirement is now bumped to 4.1 (still old at this point).

libgomp/ChangeLog:

* allocator.c (MEMSPACE_ALLOC): New macro.
(MEMSPACE_CALLOC): New macro.
(MEMSPACE_REALLOC): New macro.
(MEMSPACE_FREE): New macro.
(dynamic_smem_size): New constants.
(omp_alloc): Use MEMSPACE_ALLOC.
Implement fall-backs for predefined allocators.
(omp_free): Use MEMSPACE_FREE.
(omp_calloc): Use MEMSPACE_CALLOC.
Implement fall-backs for predefined allocators.
(omp_realloc): Use MEMSPACE_REALLOC.
Implement fall-backs for predefined allocators.
* config/nvptx/team.c (__nvptx_lowlat_heap_root): New variable.
(__nvptx_lowlat_pool): New asm varaible.
(gomp_nvptx_main): Initialize the low-latency heap.
* plugin/plugin-nvptx.c (lowlat_pool_size): New variable.
(GOMP_OFFLOAD_init_device): Read the GOMP_NVPTX_LOWLAT_POOL envvar.
(GOMP_OFFLOAD_run): Apply lowlat_pool_size.
* config/nvptx/allocator.c: New file.
* testsuite/libgomp.c/allocators-1.c: New test.
* testsuite/libgomp.c/allocators-2.c: New test.
* testsuite/libgomp.c/allocators-3.c: New test.
* testsuite/libgomp.c/allocators-4.c: New test.
* testsuite/libgomp.c/allocators-5.c: New test.
* testsuite/libgomp.c/allocators-6.c: New test.

diff --git a/libgomp/allocator.c b/libgomp/allocator.c
index 07a5645f4cc..b1f5fe0a5e2 100644
--- a/libgomp/allocator.c
+++ b/libgomp/allocator.c
@@ -34,6 +34,38 @@
 
 #define omp_max_predefined_alloc omp_thread_mem_alloc
 
+/* These macros may be overridden in config//allocator.c.  */
+#ifndef MEMSPACE_ALLOC
+#define MEMSPACE_ALLOC(MEMSPACE, SIZE) \
+  ((void)MEMSPACE, malloc (SIZE))
+#endif
+#ifndef MEMSPACE_CALLOC
+#define MEMSPACE_CALLOC(MEMSPACE, SIZE) \
+  ((void)MEMSPACE, calloc (1, SIZE))
+#endif
+#ifndef MEMSPACE_REALLOC
+#define MEMSPACE_REALLOC(MEMSPACE, ADDR, OLDSIZE, SIZE) \
+  ((void)MEMSPACE, (void)OLDSIZE, realloc (ADDR, SIZE))
+#endif
+#ifndef MEMSPACE_FREE
+#define MEMSPACE_FREE(MEMSPACE, ADDR, SIZE) \
+  ((void)MEMSPACE, (void)SIZE, free (ADDR))
+#endif
+
+/* Map the predefined allocators to the correct memory space.
+   The index to this table is the omp_allocator_handle_t enum value.  */
+static const omp_memspace_handle_t predefined_alloc_mapping[] = {
+  omp_default_mem_space,   /* omp_null_allocator. */
+  omp_default_mem_space,   /* omp_default_mem_alloc. */
+  omp_large_cap_mem_space, /* omp_large_cap_mem_alloc. */
+  omp_default_mem_space,   /* omp_const_mem_alloc. */
+  omp_high_bw_mem_space,   /* omp_high_bw_mem_alloc. */
+  omp_low_lat_mem_space,   /* omp_low_lat_mem_alloc. */
+  omp_low_lat_mem_space,   /* omp_cgroup_mem_alloc. */
+  omp_low_lat_mem_space,   /* omp_pteam_mem_alloc. */
+  omp_low_lat_mem_space,   /* omp_thread_mem_alloc. */
+};
+
 struct omp_allocator_data
 {
   omp_memspace_handle_t memspace;
@@ -281,7 +313,7 @@ retry:
   allocator_data->used_pool_size = used_pool_size;
   gomp_mutex_unlock (_data->lock);
 #endif
-  ptr = malloc (new_size);
+  ptr = MEMSPACE_ALLOC (allocator_data->memspace, new_size);
   if (ptr == NULL)
{
 #ifdef HAVE_SYNC_BUILTINS
@@ -297,7 +329,10 @@ retry:
 }
   else
 {
-  ptr = malloc (new_size);
+  omp_memspace_handle_t memspace = (allocator_data
+   ? allocator_data->memspace
+   : predefined_alloc_mapping[allocator]);
+  ptr = MEMSPACE_ALLOC (memspace, new_size);
   if (ptr == NULL)
goto fail;
 }
@@ -315,32 +350,35 @@ retry:
   return ret;
 
 fail:
-  if (allocator_data)
+  int fallback = (allocator_data
+ ? allocator_data->fallback
+ : allocator == omp_default_mem_alloc
+ ? omp_atv_null_fb
+ : omp_atv_default_mem_fb);
+  switch (fallback)
 {
-  switch (allocator_data->fallback)
+case 

[PATCH] libstdc++: Fix and simplify freestanding configuration [PR103866]

2022-01-07 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux and by building a mips-none-elf cross with
--disable-hosted-libstdcxx --without-headers (which fails currently).

Any objections?


This fixes the --disable-hosted-libstdcxx build so that it works with
--without-headers. Currently you need to also use --with-newlib, which
is confusing for users who aren't actually using newlib.

The AM_PROG_LIBTOOL checks are currently skipped for --with-newlib and
--with-avrlibc builds, with this change they are also skipped when using
--without-headers.  It would be nice if using --disable-hosted-libstdcxx
automatically skipped those checks, but GLIBCXX_ENABLE_HOSTED comes too
late to make the AM_PROG_LIBTOOL checks depend on $is_hosted.

The checks for EOF, SEEK_CUR etc. cause the build to fail if there is no
 available.  Unlike most headers, which get a HAVE_FOO_H macro,
 is in autoconf's default includes, so every check tries to
include it unconditionally. This change skips those checks for
freestanding builds.

Similarly, the checks for  types done by GCC_HEADER_STDINT try
to include  and fail for --without-headers builds. This change
skips the use of GCC_HEADER_STDINT for freestanding. We can probably
stop using GCC_HEADER_STDINT entirely, since only one file uses the
gstdint.h header that is generated, and that could easily be changed to
use  instead. That can wait for stage 1.

We also need to skip the GLIBCXX_CROSSCONFIG stage if --without-headers
was used, since we don't have any of the functions it deals with.

The end result of the changes above is that it should not be necessary
for a --disable-hosted-libstdcxx --without-headers build to also use
--with-newlib.

Finally, compile libsupc++ with -ffreestanding when --without-headers is
used, so that  will use  instead of expecting it
to come from libc.

libstdc++-v3/ChangeLog:

PR libstdc++/103866
* acinclude.m4 (GLIBCXX_COMPUTE_STDIO_INTEGER_CONSTANTS): Do
nothing for freestanding builds.
(GLIBCXX_ENABLE_HOSTED): Define FREESTANDING_FLAGS.
* configure.ac: Do not use AC_LIBTOOL_DLOPEN when configured
with --without-headers.  Do not use GCC_HEADER_STDINT for
freestanding builds.
* libsupc++/Makefile.am (HOSTED_CXXFLAGS): Use -ffreestanding
for freestanding builds.
* configure: Regenerate.
* Makefile.in: Regenerate.
* doc/Makefile.in: Regenerate.
* include/Makefile.in: Regenerate.
* libsupc++/Makefile.in: Regenerate.
* po/Makefile.in: Regenerate.
* python/Makefile.in: Regenerate.
* src/Makefile.in: Regenerate.
* src/c++11/Makefile.in: Regenerate.
* src/c++17/Makefile.in: Regenerate.
* src/c++20/Makefile.in: Regenerate.
* src/c++98/Makefile.in: Regenerate.
* src/filesystem/Makefile.in: Regenerate.
* testsuite/Makefile.in: Regenerate.
---
 libstdc++-v3/Makefile.in|  1 +
 libstdc++-v3/acinclude.m4   |  8 ++
 libstdc++-v3/configure  | 35 ++---
 libstdc++-v3/configure.ac   | 10 +--
 libstdc++-v3/doc/Makefile.in|  1 +
 libstdc++-v3/include/Makefile.in|  1 +
 libstdc++-v3/libsupc++/Makefile.am  |  2 +-
 libstdc++-v3/libsupc++/Makefile.in  |  3 ++-
 libstdc++-v3/po/Makefile.in |  1 +
 libstdc++-v3/python/Makefile.in |  1 +
 libstdc++-v3/src/Makefile.in|  1 +
 libstdc++-v3/src/c++11/Makefile.in  |  1 +
 libstdc++-v3/src/c++17/Makefile.in  |  1 +
 libstdc++-v3/src/c++20/Makefile.in  |  1 +
 libstdc++-v3/src/c++98/Makefile.in  |  1 +
 libstdc++-v3/src/filesystem/Makefile.in |  1 +
 libstdc++-v3/testsuite/Makefile.in  |  1 +
 17 files changed, 56 insertions(+), 14 deletions(-)

diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 635168d7e25..b770d5bcdc4 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2081,6 +2081,7 @@ dnl Compute the EOF, SEEK_CUR, and SEEK_END integer 
constants.
 dnl
 AC_DEFUN([GLIBCXX_COMPUTE_STDIO_INTEGER_CONSTANTS], [
 
+if test "$is_hosted" = yes; then
   AC_CACHE_CHECK([for the value of EOF], glibcxx_cv_stdio_eof, [
   AC_COMPUTE_INT([glibcxx_cv_stdio_eof], [[EOF]],
 [#include ],
@@ -2104,6 +2105,7 @@ AC_DEFUN([GLIBCXX_COMPUTE_STDIO_INTEGER_CONSTANTS], [
   ])
   AC_DEFINE_UNQUOTED(_GLIBCXX_STDIO_SEEK_END, $glibcxx_cv_stdio_seek_end,
 [Define to the value of the SEEK_END integer constant.])
+fi
 ])
 
 dnl
@@ -2923,12 +2925,16 @@ AC_DEFUN([GLIBCXX_ENABLE_HOSTED], [
enable_hosted_libstdcxx=yes
;;
  esac])
+  freestanding_flags=
   if test "$enable_hosted_libstdcxx" = no; then
 AC_MSG_NOTICE([Only freestanding libraries will be built])
 is_hosted=no
 hosted_define=0
 enable_abi_check=no
 enable_libstdcxx_pch=no
+if test "x$with_headers" = xno; then
+  freestanding_flags="-ffreestanding"
+fi
   

[Patch, fortran] PR103366 - [9/10/11/12 Regression] ICE in gfc_conv_gfc_desc_to_cfi_desc, at fortran/trans-expr.c:5647

2022-01-07 Thread Paul Richard Thomas via Gcc-patches
I doubt that this is a regression on 9-11 branches since the testcase
compiles correctly on each of my copies of these branches. IMHO it is
rather more likely to have been caused by
64f9623765da3306b0ab6a47997dc5d62c2ea261, which introduced this new form of
gfc_conv_gfc_desc_to_cfi_desc.

The patch is self-explanatory. OK for mainline?

Paul

Fortran: Match unlimited polymorphic argument to assumed type [PR103366].

2022-01-07  Paul Thomas  

gcc/fortran
PR fortran/103366
* trans-expr.c (gfc_conv_gfc_desc_to_cfi_desc): Allow unlimited
polymorphic actual argument passed to assumed type formal.

gcc/testsuite/
PR fortran/103366
* gfortran.dg/pr103366.f90: New test.
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 381915e2a76..2e15a7e874c 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -50,10 +50,10 @@ static tree
 gfc_get_character_len (tree type)
 {
   tree len;
-  
+
   gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
 	  && TYPE_STRING_FLAG (type));
-  
+
   len = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
   len = (len) ? (len) : (integer_zero_node);
   return fold_convert (gfc_charlen_type_node, len);
@@ -67,10 +67,10 @@ tree
 gfc_get_character_len_in_bytes (tree type)
 {
   tree tmp, len;
-  
+
   gcc_assert (type && TREE_CODE (type) == ARRAY_TYPE
 	  && TYPE_STRING_FLAG (type));
-  
+
   tmp = TYPE_SIZE_UNIT (TREE_TYPE (type));
   tmp = (tmp && !integer_zerop (tmp))
 ? (fold_convert (gfc_charlen_type_node, tmp)) : (NULL_TREE);
@@ -5630,6 +5630,16 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym)
 	  itype = CFI_type_other;  // FIXME: Or CFI_type_cptr ?
 	  break;
 	case BT_CLASS:
+	  if (UNLIMITED_POLY (e) && fsym->ts.type == BT_ASSUMED)
+	{
+	  // F2017: 7.3.2.2: "An entity that is declared using the TYPE(*)
+	  // type specifier is assumed-type and is an unlimited polymorphic
+	  //  entity." The actual argument _data component is passed.
+	  itype = CFI_type_other;  // FIXME: Or CFI_type_cptr ?
+	  break;
+	}
+	  else
+	gcc_unreachable ();
 	case BT_PROCEDURE:
 	case BT_HOLLERITH:
 	case BT_UNION:
! { dg-do compile }
!
! Test the fix for PR103366.
!
! Contributed by Gerhardt Steinmetz  
!
program p
  call u([1])
contains
   subroutine s(x) bind(c)
  type(*) :: x(..)
   end
   subroutine u(x)
  class(*) :: x(..)
  call s(x) ! Used to ICE here
   end
end


Re: [power-ieee128] RFH: LTO broken

2022-01-07 Thread Jakub Jelinek via Gcc-patches
On Fri, Jan 07, 2022 at 12:29:25PM +0100, Jakub Jelinek wrote:
> we don't do it consistently:
> readelf -Wr 
> /home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0
>  | grep ieee128
> 00250310  01280015 R_PPC64_JMP_SLOT    
> __atan2ieee128 + 0
> 00250340  01420015 R_PPC64_JMP_SLOT    
> __clogieee128 + 0
> 00250438  01a30015 R_PPC64_JMP_SLOT    
> __acoshieee128 + 0
> 002504b8  01cc0015 R_PPC64_JMP_SLOT    
> __csinieee128 + 0
> 00250500  01f30015 R_PPC64_JMP_SLOT    
> __sinhieee128 + 0
> 00250570  022a0015 R_PPC64_JMP_SLOT    
> __asinieee128 + 0
> 00250580  022d0015 R_PPC64_JMP_SLOT    
> __roundieee128 + 0
> 002505a0  023e0015 R_PPC64_JMP_SLOT    
> __logieee128 + 0
> 002505c8  02490015 R_PPC64_JMP_SLOT    
> __tanieee128 + 0
> 00250630  02750015 R_PPC64_JMP_SLOT    
> __ccosieee128 + 0
> 00250670  028a0015 R_PPC64_JMP_SLOT    
> __log10ieee128 + 0
> 002506c8  02bd0015 R_PPC64_JMP_SLOT    
> __cexpieee128 + 0
> 002506d8  02c80015 R_PPC64_JMP_SLOT    
> __coshieee128 + 0
> 002509b0  03ef0015 R_PPC64_JMP_SLOT    
> __truncieee128 + 0
> 00250af8  04a60015 R_PPC64_JMP_SLOT    
> __expieee128 + 0
> 00250b50  04c60015 R_PPC64_JMP_SLOT    
> __fmodieee128 + 0
> 00250bb0  04e70015 R_PPC64_JMP_SLOT    
> __tanhieee128 + 0
> 00250c38  05130015 R_PPC64_JMP_SLOT    
> __acosieee128 + 0
> 00250ce0  05540015 R_PPC64_JMP_SLOT    
> __sinieee128 + 0
> 00250d60  057e0015 R_PPC64_JMP_SLOT    
> __atanieee128 + 0
> 00250dd8  05b10015 R_PPC64_JMP_SLOT    
> __sqrtieee128 + 0
> 00250e98  06020015 R_PPC64_JMP_SLOT    
> __cosieee128 + 0
> 00250eb0  060a0015 R_PPC64_JMP_SLOT    
> __atanhieee128 + 0
> 00250ef0  06200015 R_PPC64_JMP_SLOT    
> __asinhieee128 + 0
> 00250fd8  067f0015 R_PPC64_JMP_SLOT    
> __csqrtieee128 + 0
> 00251038  06ad0015 R_PPC64_JMP_SLOT    
> __cabsieee128 + 0
> All these should for POWER_IEEE128 use atan2q@QUADMATH_1.0 etc.

So, seems all these come from f951 compiled sources.
For user code, I think the agreement was if you want to use successfully
-mabi=ieeelongdouble, you need glibc 2.32 or later, which is why the Fortran
FE doesn't conditionalize on whether glibc 2.32 is available or not and just
emits __WHATEVERieee128 entrypoints.
But for Fortran compiled sources in libgfortran, we need to use
__WHATEVERieee128 only if glibc 2.32 or later and WHATEVERq (from
libquadmath) otherwise.
I guess easiest would be to do this always in the FE, but we need to
determine in the FE if the target is glibc 2.32 or later.

> On the other side, on glibc 2.32+ build, we still use some libquadmath APIs
> when we shouldn't:
> readelf -Wr 
> /home/jakub/gcc/obj/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5
>  | grep QUADMATH
> 002502c8  00260015 R_PPC64_JMP_SLOT    
> fmaq@QUADMATH_1.0 + 0
> 002505f8  00670015 R_PPC64_JMP_SLOT    
> tanq@QUADMATH_1.0 + 0
> 00250930  009b0015 R_PPC64_JMP_SLOT    
> fabsq@QUADMATH_1.0 + 0
> 00250940  009d0015 R_PPC64_JMP_SLOT    
> sinq@QUADMATH_1.0 + 0
> 00250c98  00cf0015 R_PPC64_JMP_SLOT    
> copysignq@QUADMATH_1.0 + 0
> 00251038  01070015 R_PPC64_JMP_SLOT    
> cosq@QUADMATH_1.0 + 0
> 00251068  010a0015 R_PPC64_JMP_SLOT    
> fmodq@QUADMATH_1.0 + 0
> These should use __fmaieee128, __tanieee128 etc. instead.

This one seems easily fixed by the following patch, ok for power-ieee128?

2022-01-07  Jakub Jelinek  

* libgfortran.h (__copysignieee128, __fmaieee128, __fmodieee128):
Declare.
* intrinsics/trigd.c (COPYSIGN, FMOD, FABS, FMA, SIN, COS, TAN): If
POWER_IEEE128 is defined, define these for kind 17 include.
* intrinsics/trigd_lib.inc (COPYSIGN, FMOD, FABS, FMA, SIN, COS, TAN):
Don't define if COPYSIGN is already defined.

--- libgfortran/libgfortran.h.jj2022-01-07 09:39:10.222157644 +
+++ 

Re: [PATCH] target: [PR102941] Fix inline-asm flags with non-REG_P output

2022-01-07 Thread Richard Sandiford via Gcc-patches
apinski--- via Gcc-patches  writes:
> From: Andrew Pinski 
>
> So the problem here is that arm_md_asm_adjust would
> just create a set directly to the output memory which is wrong.
> It needs to output to a temp register first and then do a
> move.
>
> OK? Bootstrapped and tested on aarch64-linux-gnu with no regressions.
> I have no way to test on arm even though this touches common code.
>
>   PR target/102941
>
> gcc/ChangeLog:
>
>   * config/arm/aarch-common.c (arm_md_asm_adjust):
>   Use a temp if !REG_P.
>
> gcc/testsuite/ChangeLog:
>
>   * gcc.target/aarch64/asm-flag-7.c: New test.
>   * gcc.target/arm/asm-flag-7.c: New test.

OK, thanks, and sorry for the delay.

Richard

> ---
>  gcc/config/arm/aarch-common.c |  2 +-
>  gcc/testsuite/gcc.target/aarch64/asm-flag-7.c | 22 ++
>  gcc/testsuite/gcc.target/arm/asm-flag-7.c | 23 +++
>  3 files changed, 46 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/asm-flag-7.c
>  create mode 100644 gcc/testsuite/gcc.target/arm/asm-flag-7.c
>
> diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c
> index 67343fe4025..60b3516c1df 100644
> --- a/gcc/config/arm/aarch-common.c
> +++ b/gcc/config/arm/aarch-common.c
> @@ -641,7 +641,7 @@ arm_md_asm_adjust (vec , vec & 
> /*inputs*/,
>rtx x = gen_rtx_REG (mode, CC_REGNUM);
>x = gen_rtx_fmt_ee (code, word_mode, x, const0_rtx);
>  
> -  if (dest_mode == word_mode)
> +  if (dest_mode == word_mode && REG_P (dest))
>   emit_insn (gen_rtx_SET (dest, x));
>else
>   {
> diff --git a/gcc/testsuite/gcc.target/aarch64/asm-flag-7.c 
> b/gcc/testsuite/gcc.target/aarch64/asm-flag-7.c
> new file mode 100644
> index 000..6c31b854b0b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/asm-flag-7.c
> @@ -0,0 +1,22 @@
> +/* Test that "=@cc*" works with MEM_P RTX  */
> +/* PR target/102941 */
> +/* { dg-do compile } */
> +/* { dg-options "-O" } */
> +
> +#ifndef __GCC_ASM_FLAG_OUTPUTS__
> +#error "missing preprocessor define"
> +#endif
> +int test_cmpu_x;
> +
> +void f(long *);
> +long
> +test_cmpu_y() {
> +  long le;
> +  f();
> +  __asm__("cmp %"
> +  "[x], %"
> +  "[y]"
> +  : "=@ccls"(le)
> +  : [x] ""(test_cmpu_x), [y] ""(test_cmpu_y));
> +return le;
> +}
> diff --git a/gcc/testsuite/gcc.target/arm/asm-flag-7.c 
> b/gcc/testsuite/gcc.target/arm/asm-flag-7.c
> new file mode 100644
> index 000..ac11da0a3a8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/asm-flag-7.c
> @@ -0,0 +1,23 @@
> +/* Test that "=@cc*" works with MEM_P RTX  */
> +/* PR target/102941 */
> +/* { dg-do compile } */
> +/* { dg-options "-O" } */
> +/* { dg-skip-if "" { arm_thumb1 } } */
> +
> +#ifndef __GCC_ASM_FLAG_OUTPUTS__
> +#error "missing preprocessor define"
> +#endif
> +int test_cmpu_x;
> +
> +void f(long *);
> +long
> +test_cmpu_y() {
> +  long le;
> +  f();
> +  __asm__("cmp %"
> +  "[x], %"
> +  "[y]"
> +  : "=@ccls"(le)
> +  : [x] ""(test_cmpu_x), [y] ""(test_cmpu_y));
> +return le;
> +}


Re: [vect] Re-analyze all modes for epilogues

2022-01-07 Thread Richard Sandiford via Gcc-patches
"Andre Vieira (lists)"  writes:
> Made the suggested changes.
>
> Regarding the name change to partial vectors, I agree in the name change 
> since that is the terminology we are using in the loop_vinfo members 
> too, but is there an actual difference between predication/masking and 
> partial vectors that I am missing?

“Predication/masking” refers to the ability to enable and disable
operations on a lane-by-lane basis.  E.g. it means that patterns
like 10100010 are possible.

“Operating on partial vectors” is the ability to operate on just the
first N lanes of a vector, for some given N.  It means that patterns
like 1100 are possible but patterns like 10100010 might not be.

At the moment, “operating on partial vectors” also requires either
direct support for loading and storing the first N lanes, or a way of
generating a loop predicate/mask from N and using predication/masking.

So the two concepts overlap, but support for one doesn't directly
imply support for the other.

> OK for trunk?
>
> gcc/ChangeLog:
>
>      * tree-vect-loop.c (vect_better_loop_vinfo_p): Round factors up 
> for epilogue costing.
>      (vect_analyze_loop): Re-analyze all modes for epilogues, unless 
> we are guaranteed that we can't
>      have partial vectors.
>      (genopinit.c) (partial_vectors_supported): Generate new function.
>
> gcc/testsuite/ChangeLog:
>
>      * gcc.target/aarch64/masked_epilogue.c: New test.

OK, thanks.

Richard

> diff --git a/gcc/genopinit.c b/gcc/genopinit.c
> index 
> 195ddf74fa2b7d89760622073dcec9d5d339a097..2bc7cdbf53337beae181afd7bb05b366ab068c6a
>  100644
> --- a/gcc/genopinit.c
> +++ b/gcc/genopinit.c
> @@ -321,6 +321,7 @@ main (int argc, const char **argv)
>  "  bool supports_vec_scatter_store_cached;\n"
>  "};\n"
>  "extern void init_all_optabs (struct target_optabs *);\n"
> +"extern bool partial_vectors_supported_p (void);\n"
>  "\n"
>  "extern struct target_optabs default_target_optabs;\n"
>  "extern struct target_optabs *this_fn_optabs;\n"
> @@ -373,6 +374,33 @@ main (int argc, const char **argv)
>  fprintf (s_file, "  ena[%u] = HAVE_%s;\n", i, p->name);
>fprintf (s_file, "}\n\n");
>  
> +  fprintf (s_file,
> +"/* Returns TRUE if the target supports any of the partial vector\n"
> +"   optabs: while_ult_optab, len_load_optab or len_store_optab,\n"
> +"   for any mode.  */\n"
> +"bool\npartial_vectors_supported_p (void)\n{\n");
> +  bool any_match = false;
> +  fprintf (s_file, "\treturn");
> +  bool first = true;
> +  for (i = 0; patterns.iterate (i, ); ++i)
> +{
> +#define CMP_NAME(N) !strncmp (p->name, (N), strlen ((N)))
> +  if (CMP_NAME("while_ult") || CMP_NAME ("len_load")
> +   || CMP_NAME ("len_store"))
> + {
> +   if (first)
> + fprintf (s_file, " HAVE_%s", p->name);
> +   else
> + fprintf (s_file, " || HAVE_%s", p->name);
> +   first = false;
> +   any_match = true;
> + }
> +}
> +  if (!any_match)
> +fprintf (s_file, " false");
> +  fprintf (s_file, ";\n}\n");
> +
> +
>/* Perform a binary search on a pre-encoded optab+mode*2.  */
>/* ??? Perhaps even better to generate a minimal perfect hash.
>   Using gperf directly is awkward since it's so geared to working
> diff --git a/gcc/testsuite/gcc.target/aarch64/masked_epilogue.c 
> b/gcc/testsuite/gcc.target/aarch64/masked_epilogue.c
> new file mode 100644
> index 
> ..286a7be236f337fee4c4650f42da72000855c5e6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/masked_epilogue.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details 
> -march=armv8-a+sve -msve-vector-bits=scalable" } */
> +
> +void f(unsigned char y[restrict],
> +   unsigned char x[restrict], int n) {
> +  for (int i = 0; i < n; ++i)
> +y[i] = (y[i] + x[i] + 1) >> 1;
> +}
> +
> +/* { dg-final { scan-tree-dump {LOOP EPILOGUE VECTORIZED \(MODE=VNx} "vect" 
> } } */
> diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
> index 
> a28bb6321d76b8222bc8cfdade151ca9b4dca406..5af98a36678ae61e99f93beb90920e2d0940c53a
>  100644
> --- a/gcc/tree-vect-loop.c
> +++ b/gcc/tree-vect-loop.c
> @@ -2824,11 +2824,13 @@ vect_better_loop_vinfo_p (loop_vec_info 
> new_loop_vinfo,
>   {
> unsigned HOST_WIDE_INT main_vf_max
>   = estimated_poly_value (main_poly_vf, POLY_VALUE_MAX);
> +   unsigned HOST_WIDE_INT old_vf_max
> + = estimated_poly_value (old_vf, POLY_VALUE_MAX);
> +   unsigned HOST_WIDE_INT new_vf_max
> + = estimated_poly_value (new_vf, POLY_VALUE_MAX);
>  
> -   old_factor = main_vf_max / estimated_poly_value (old_vf,
> -POLY_VALUE_MAX);
> -   new_factor = main_vf_max / estimated_poly_value (new_vf,
> -

[PATCH] c++, match.pd: Evaluate in constant evaluation comparisons like + 12 == + 24 [PR89074]

2022-01-07 Thread Jakub Jelinek via Gcc-patches
Hi!

The match.pd address_comparison simplification can only handle
ADDR_EXPR comparisons possibly converted to some other type (I wonder
if we shouldn't restrict it in address_compare to casts to pointer
types or pointer-sized integer types, I think we shouldn't optimize
(short) () == (short) () because we really don't know whether
it will be true or false).  On GIMPLE, most of pointer to pointer
casts are useless and optimized away and further we have in
gimple_fold_stmt_to_constant_1 an optimization that folds
 p+ const_int
into
_REF[..., off]
On GENERIC, we don't do that and e.g. for constant evaluation it
could be pretty harmful if e.g. such pointers are dereferenced, because
it can lose what exact field it was starting with etc., all it knows
is the base and offset, type and alias set.
Instead of teaching the match.pd address_compare about 3 extra variants
where one or both compared operands are pointer_plus, this patch attempts
to fold operands of comparisons similarly to gimple_fold_stmt_to_constant_1
before calling fold_binary on it.
There is another thing though, while we do have (x p+ y) p+ z to
x p+ (y + z) simplification which works on GIMPLE well because of the
useless pointer conversions, on GENERIC we can have pointer casts in between
and at that point we can end up with large expressions like
((type3) (((type2) ((type1) ( + 2) + 2) + 2) + 2))
etc.  Pointer-plus doesn't really care what exact pointer type it has as
long as it is a pointer, so the following match.pd simplification for
GENERIC only (it is useless for GIMPLE) also moves the cast so that nested
p+ can be simplified.

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

Note, I've noticed we don't really diagnose going out of bounds with
pointer_plus (unlike e.g. with ARRAY_REF) during constant evaluation, I
think another patch for cxx_eval_binary_expression with POINTER_PLUS will be
needed.  But it isn't clear to me what exactly it should do in case of
subobjects.  If we start with address of a whole var, (), I guess we
should diagnose if the pointer_plus gets before start of the var (i.e.
"negative") or 1 byte past the end of the var, but what if we start with
 or [3] ?  For , shall we diagnose out of
bounds of field (except perhaps flexible members?) or the whole var?
For ARRAY_REFs, I assume we must at least strip all the outer ARRAY_REFs
and so start with  too, right?

2022-01-07  Jakub Jelinek  

PR c++/89074
gcc/
* match.pd ((ptr) (x p+ y) p+ z -> (ptr) (x p+ (y + z))): New GENERIC
simplification.
gcc/cp/
* constexpr.c (cxx_maybe_fold_addr_pointer_plus): New function.
(cxx_eval_binary_expression): Use it.
gcc/testsuite/
* g++.dg/cpp1y/constexpr-89074-2.C: New test.
* g++.dg/cpp1z/constexpr-89074-1.C: New test.

--- gcc/match.pd.jj 2022-01-05 20:30:08.768806236 +0100
+++ gcc/match.pd2022-01-06 19:59:53.596114417 +0100
@@ -2143,6 +2143,11 @@ (define_operator_list SYNC_FETCH_AND_AND
 (simplify
   (pointer_plus (pointer_plus:s @0 @1) @3)
   (pointer_plus @0 (plus @1 @3)))
+#if GENERIC
+(simplify
+  (pointer_plus (convert:s (pointer_plus:s @0 @1)) @3)
+  (convert:type (pointer_plus @0 (plus @1 @3
+#endif
 
 /* Pattern match
  tem1 = (long) ptr1;
--- gcc/cp/constexpr.c.jj   2022-01-03 10:40:48.403063535 +0100
+++ gcc/cp/constexpr.c  2022-01-06 20:47:44.596623219 +0100
@@ -3288,6 +3288,38 @@ cxx_fold_pointer_plus_expression (const
   return NULL_TREE;
 }
 
+/* Try to fold expressions like
+   (struct S *) ([0].D.2378 + 12)
+   into
+ [(void *) + 12B]
+   This is something normally done by gimple_fold_stmt_to_constant_1
+   on GIMPLE, but is undesirable on GENERIC if we are e.g. going to
+   dereference the address because some details are lost.
+   For pointer comparisons we want such folding though so that
+   match.pd address_compare optimization works.  */
+
+static tree
+cxx_maybe_fold_addr_pointer_plus (tree t)
+{
+  while (CONVERT_EXPR_P (t)
+&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0
+t = TREE_OPERAND (t, 0);
+  if (TREE_CODE (t) != POINTER_PLUS_EXPR)
+return NULL_TREE;
+  tree op0 = TREE_OPERAND (t, 0);
+  tree op1 = TREE_OPERAND (t, 1);
+  if (TREE_CODE (op1) != INTEGER_CST)
+return NULL_TREE;
+  while (CONVERT_EXPR_P (op0)
+&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0
+op0 = TREE_OPERAND (op0, 0);
+  if (TREE_CODE (op0) != ADDR_EXPR)
+return NULL_TREE;
+  op1 = fold_convert (ptr_type_node, op1);
+  tree r = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)), op0, op1);
+  return build1_loc (EXPR_LOCATION (t), ADDR_EXPR, TREE_TYPE (op0), r);
+}
+
 /* Subroutine of cxx_eval_constant_expression.
Like cxx_eval_unary_expression, except for binary expressions.  */
 
@@ -3347,6 +3379,15 @@ cxx_eval_binary_expression (const conste
   else if (TREE_CODE (rhs) == PTRMEM_CST)
rhs = cplus_expand_constant (rhs);
 }
+  if (r == NULL_TREE
+  && 

Re: [PATCH] [RTL/fwprop] Allow propagations from inner loop to outer loop.

2022-01-07 Thread Richard Sandiford via Gcc-patches
liuhongt via Gcc-patches  writes:
>>Huh, loop_father should never be NULL. Maybe when fwprop is run after RTL 
>>loop opts you instead want to add a check for current_loops or 
>>alternelatively initialize loops in fwprop.
>
> Oh, I didn't know that, i once saw there's ICE and thought it's related to
> NULL loop. But I can't reproduce the ICE either in GCC testsuite or buiding
> spec2017. Anyway, here's update patch.
>
> gcc/ChangeLog:
>
>   PR rtl/103750
>   * fwprop.c (forward_propagate_into): Allow propagations from
>   inner loop to outer loop.
>
> gcc/testsuite/ChangeLog:
>
>   * g++.target/i386/pr103750-fwprop-1.C: New test.
> ---
>  build.log |  0
>  gcc/fwprop.c  |  7 +++--
>  .../g++.target/i386/pr103750-fwprop-1.C   | 26 +++
>  3 files changed, 31 insertions(+), 2 deletions(-)
>  create mode 100644 build.log
>  create mode 100644 gcc/testsuite/g++.target/i386/pr103750-fwprop-1.C
>
> diff --git a/build.log b/build.log
> new file mode 100644
> index 000..e69de29bb2d
> diff --git a/gcc/fwprop.c b/gcc/fwprop.c
> index 2eab4fd4614..4f5d6a8d4fc 100644
> --- a/gcc/fwprop.c
> +++ b/gcc/fwprop.c
> @@ -866,10 +866,13 @@ forward_propagate_into (use_info *use, bool 
> reg_prop_only = false)
>rtx src = SET_SRC (def_set);
>  
>/* Allow propagations into a loop only for reg-to-reg copies, since
> - replacing one register by another shouldn't increase the cost.  */
> + replacing one register by another shouldn't increase the cost.
> + Propagations from inner loop to outer loop should be also ok.  */

“should also be ok”

OK with that change, thanks.

Richard

>struct loop *def_loop = def_insn->bb ()->cfg_bb ()->loop_father;
>struct loop *use_loop = use->bb ()->cfg_bb ()->loop_father;
> -  if ((reg_prop_only || def_loop != use_loop)
> +  if ((reg_prop_only
> +   || (def_loop != use_loop
> +&& !flow_loop_nested_p (use_loop, def_loop)))
>&& (!reg_single_def_p (dest) || !reg_single_def_p (src)))
>  return false;
>  
> diff --git a/gcc/testsuite/g++.target/i386/pr103750-fwprop-1.C 
> b/gcc/testsuite/g++.target/i386/pr103750-fwprop-1.C
> new file mode 100644
> index 000..26987d307aa
> --- /dev/null
> +++ b/gcc/testsuite/g++.target/i386/pr103750-fwprop-1.C
> @@ -0,0 +1,26 @@
> +/* PR target/103750.  */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -std=c++1y -march=cannonlake -fdump-rtl-fwprop1" } */
> +/* { dg-final { scan-rtl-dump-not "subreg:HI\[ 
> \\\(\]*reg:SI\[^\n]*\n\[^\n]*UNSPEC_TZCNT" "fwprop1" } } */
> +
> +#include
> +const char16_t *qustrchr(char16_t *n, char16_t *e, char16_t c) noexcept
> +{
> +  __m256i mch256 = _mm256_set1_epi16(c);
> +  for ( ; n < e; n += 32) {
> +__m256i data1 = _mm256_loadu_si256(reinterpret_cast(n));
> +__m256i data2 = _mm256_loadu_si256(reinterpret_cast(n) 
> + 1);
> +__mmask16 mask1 = _mm256_cmpeq_epu16_mask(data1, mch256);
> +__mmask16 mask2 = _mm256_cmpeq_epu16_mask(data2, mch256);
> +if (_kortestz_mask16_u8(mask1, mask2))
> +  continue;
> +
> +unsigned idx = _tzcnt_u32(mask1);
> +if (mask1 == 0) {
> +  idx = __tzcnt_u16(mask2);
> +  n += 16;
> +}
> +return n + idx;
> +  }
> +  return e;
> +}


Re: [PATCH v4 04/12] LoongArch Port: Machine Decsription files.

2022-01-07 Thread 程璐璐

在 2022/1/7 上午1:54, Xi Ruoyao 写道:

On Fri, 2021-12-24 at 17:28 +0800, chenglulu wrote:

+(define_insn "*zero_extendsidi2_internal"
+  [(set (match_operand:DI 0 "register_operand" "=r,r,r")
+   (subreg:DI (match_operand:SI 1 "nonimmediate_operand" "r,ZC,W") 0))]
+  "TARGET_64BIT"
+  "@
+   bstrpick.d\t%0,%1,31,0
+   ldptr.w\t%0,%1\n\tlu32i.d\t%0,0
+   ld.wu\t%0,%1"
+  [(set_attr "move_type" "arith,load,load")
+   (set_attr "mode" "DI")
+   (set_attr "insn_count" "1,2,1")])

This pattern is generating wrong code, causing

FAIL: gcc.dg/compat/scalar-by-value-3 c_compat_x_tst.o-c_compat_y_tst.o execute

This failure is a real bug, the reduced testcase is attached.  In the
assembly:

 # ...
 bstrins.d   $r5,$r13,31,0
 addi.d  $r12,$r22,-228
 bstrpick.d  $r12,$r12,31,0
 bstrins.d   $r5,$r12,63,32
 addi.w  $r4,$r0,14  # 0xe
 bl  testvaci

This obviously does not make any sense: it calculates the *address* of
g[0]'s imaginary part, truncates it to 32-bit, then pass it as the
*value* of the imaginary part to testvaci().

The problem is: before the reload pass, the compiler consider g[0] a
(virtual) register.  It only becomes MEM after the reload pass.  Adding
reload_completed as the condition of this insn seems able to fix the
issue.  However I'm not sure if other insns need the change too.


+;; See the comment before the *and3 pattern why this is generated by
+;; combine.

A minor issue: the comment before 'and3' does not exist.


Thanks, we are working on this. In addition, we will check other 
instruction templates.





Re: [power-ieee128] RFH: LTO broken

2022-01-07 Thread Jakub Jelinek via Gcc-patches
On Thu, Jan 06, 2022 at 09:01:54PM +0100, Thomas Koenig wrote:
> 
> On 06.01.22 06:00, Michael Meissner via Fortran wrote:
> > I pushed the patch to the branch.
> 
> Test results are looking quite good right now.

I've just tried to build libgfortran on an old glibc system
(gcc112.fsffrance.org) and unfortunately we still have work to do:

[jakub@gcc2-power8 obj38]$ 
LD_PRELOAD=/home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0
 /bin/true
[jakub@gcc2-power8 obj38]$ LD_BIND_NOW=1 
LD_PRELOAD=/home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0
 /bin/true
/bin/true: symbol lookup error: 
/home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0:
 undefined symbol: __atan2ieee128

While we do use some libquadmath APIs:
readelf -Wr 
/home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0
 | grep QUADMATH
00251268  05e40026 R_PPC64_ADDR64  
quadmath_snprintf@QUADMATH_1.0 + 0
00251270  03060026 R_PPC64_ADDR64  
strtoflt128@QUADMATH_1.0 + 0
002502e0  01160015 R_PPC64_JMP_SLOT    
ynq@QUADMATH_1.0 + 0
00250390  01600015 R_PPC64_JMP_SLOT    
sqrtq@QUADMATH_1.0 + 0
00250508  01fa0015 R_PPC64_JMP_SLOT    
fmaq@QUADMATH_1.0 + 0
00250530  02120015 R_PPC64_JMP_SLOT    
fabsq@QUADMATH_1.0 + 0
00250760  03060015 R_PPC64_JMP_SLOT    
strtoflt128@QUADMATH_1.0 + 0
00250990  03df0015 R_PPC64_JMP_SLOT    
cosq@QUADMATH_1.0 + 0
002509f0  040a0015 R_PPC64_JMP_SLOT    
expq@QUADMATH_1.0 + 0
00250a88  04510015 R_PPC64_JMP_SLOT    
erfcq@QUADMATH_1.0 + 0
00250a98  045e0015 R_PPC64_JMP_SLOT    
jnq@QUADMATH_1.0 + 0
00250ac8  047e0015 R_PPC64_JMP_SLOT    
sinq@QUADMATH_1.0 + 0
00250e38  05db0015 R_PPC64_JMP_SLOT    
fmodq@QUADMATH_1.0 + 0
00250e48  05e00015 R_PPC64_JMP_SLOT    
tanq@QUADMATH_1.0 + 0
00250e58  05e40015 R_PPC64_JMP_SLOT    
quadmath_snprintf@QUADMATH_1.0 + 0
00250f20  06290015 R_PPC64_JMP_SLOT    
copysignq@QUADMATH_1.0 + 0
we don't do it consistently:
readelf -Wr 
/home/jakub/gcc/obj38/powerpc64le-unknown-linux-gnu/libgfortran/.libs/libgfortran.so.5.0.0
 | grep ieee128
00250310  01280015 R_PPC64_JMP_SLOT    
__atan2ieee128 + 0
00250340  01420015 R_PPC64_JMP_SLOT    
__clogieee128 + 0
00250438  01a30015 R_PPC64_JMP_SLOT    
__acoshieee128 + 0
002504b8  01cc0015 R_PPC64_JMP_SLOT    
__csinieee128 + 0
00250500  01f30015 R_PPC64_JMP_SLOT    
__sinhieee128 + 0
00250570  022a0015 R_PPC64_JMP_SLOT    
__asinieee128 + 0
00250580  022d0015 R_PPC64_JMP_SLOT    
__roundieee128 + 0
002505a0  023e0015 R_PPC64_JMP_SLOT    
__logieee128 + 0
002505c8  02490015 R_PPC64_JMP_SLOT    
__tanieee128 + 0
00250630  02750015 R_PPC64_JMP_SLOT    
__ccosieee128 + 0
00250670  028a0015 R_PPC64_JMP_SLOT    
__log10ieee128 + 0
002506c8  02bd0015 R_PPC64_JMP_SLOT    
__cexpieee128 + 0
002506d8  02c80015 R_PPC64_JMP_SLOT    
__coshieee128 + 0
002509b0  03ef0015 R_PPC64_JMP_SLOT    
__truncieee128 + 0
00250af8  04a60015 R_PPC64_JMP_SLOT    
__expieee128 + 0
00250b50  04c60015 R_PPC64_JMP_SLOT    
__fmodieee128 + 0
00250bb0  04e70015 R_PPC64_JMP_SLOT    
__tanhieee128 + 0
00250c38  05130015 R_PPC64_JMP_SLOT    
__acosieee128 + 0
00250ce0  05540015 R_PPC64_JMP_SLOT    
__sinieee128 + 0
00250d60  057e0015 R_PPC64_JMP_SLOT    
__atanieee128 + 0
00250dd8  05b10015 R_PPC64_JMP_SLOT    
__sqrtieee128 + 0
00250e98  06020015 R_PPC64_JMP_SLOT    
__cosieee128 + 0
00250eb0  060a0015 R_PPC64_JMP_SLOT    
__atanhieee128 + 0
00250ef0  06200015 R_PPC64_JMP_SLOT    
__asinhieee128 + 0
00250fd8  

Re: [PATCH 1/6] ira: Add a ira_loop_border_costs class

2022-01-07 Thread Richard Sandiford via Gcc-patches
Jan Hubicka  writes:
>> The final index into (ira_)memory_move_cost is 1 for loads and
>> 0 for stores.  Thus the combination:
>> 
>>   entry_freq * memory_cost[1] + exit_freq * memory_cost[0]
>> 
>> is the cost of loading a register on entry to a loop and
>> storing it back on exit from the loop.  This is the cost to
>> use if the register is successfully allocated within the
>> loop but is spilled in the parent loop.  Similarly:
>> 
>>   entry_freq * memory_cost[0] + exit_freq * memory_cost[1]
>> 
>> is the cost of storing a register on entry to the loop and
>> restoring it on exit from the loop.  This is the cost to
>> use if the register is spilled within the loop but is
>> successfully allocated in the parent loop.
>> 
>> The patch adds a helper class for calculating these values and
>> mechanically replaces the existing instances.  There is no attempt to
>> editorialise the choice between using “spill inside” and “spill outside”
>> costs.  (I think one of them is the wrong way round, but a later patch
>> deals with that.)
>> 
>> No functional change intended.
>> 
>> gcc/
>>  PR rtl-optimization/98782
>>  * ira-int.h (ira_loop_border_costs): New class.
>>  * ira-color.c (ira_loop_border_costs::ira_loop_border_costs):
>>  New constructor.
>>  (calculate_allocno_spill_cost): Use ira_loop_border_costs.
>>  (color_pass): Likewise.
>>  (move_spill_restore): Likewise.
>
> Thanks for working on this.  For profile bits, the patch looks good to
> me.  In general I am trying to move away from the integer frequencies.
> It would be more precise to calculate the m_entry_freq and m_exit_freq
> as profile_count m_entry_count, m_exit_count
> and do conversion only later.
>
> count->to_frequency method basically scales it to the range 0...BB_FREQ_MAX.

Yeah.  If I get time, I'd like to see how easy it would be to move the
RAs away from the BB_FREQ_MAX scaling.  I agree it's not really precise
enough.

The problem is that the costs are multiplied by several other things,
and there have recently been overflow problems (g:7d02c8bf75980fa2468f).
I guess the way to avoid that would be to use sreals, but the problem
then is that the costing code (particularly record_reg_classes) is very
compile-time sensitive.  So it might need a bit of surgery to move
over to sreal costs without negatively affecting compile time (and
perhaps memory consumption).

Of course, RA changes would become much easier if we got rid of
old reload. :-)  (OK, bit of a cheap shot in this case, but true
in general.)

Thanks,
Richard


Re: [power-ieee128] OPEN CONV

2022-01-07 Thread Thomas Koenig via Gcc-patches



On 07.01.22 10:22, Jakub Jelinek wrote:

On Thu, Jan 06, 2022 at 09:01:54PM +0100, Thomas Koenig wrote:


On 06.01.22 06:00, Michael Meissner via Fortran wrote:
What is still missing is the conversion for unformatted I/O, both
ways.  I'll start doing some stuff on it. Just one question:
What are functions that I can use to convert from IBM long double
to IEEE and long double and vice versa?  It was in an e-mail somewhere,
but I cannot find it at the moment.


So, what's the plan for that?
Can't find CONVERT= in Fortran 2018, so I assume it is a non-standard
extension,


Correct.


https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/language-reference/file-operation-i-o-statements/open-statement-specifiers/open-convert-specifier.html#open-convert-specifier
documents the Intel one


We followed Intel on that one.  NAG also has it
(although the details differ).


and we accept
CONVERT='native'
CONVERT='swap'
CONVERT='big_endian'
CONVERT='little_endian'
Now, I suppose for powerpc64le we want to add
some more, but the question is how they play together
with the byteswapping and how to name them, so that
it is clear they talk about REAL/COMPLEX KIND=16 format
and nothing else.  Can we (or do we) want to allow
multiple comma separated strings from the orthogonal
choices, like
CONVERT='big_endian,ibm_extended'
CONVERT='swap,ieee_extended'
or add ibm_extended, ieee_extended and strings that
combine those with swap, big_endian and little_endian
ibm_extended_swap, ieee_extended_little etc.?


In

https://gcc.gnu.org/pipermail/fortran/2021-October/056895.html

I made a suggestion how how the format could look like.  I used
a plus sign instead of a comma because I thought the environment
variable should follow the same syntax as the CONVERT specifier,
and I did not want to think about having commas in there :-)

Thinking about this again after some time, I think the syntax of
the environment variable would be clearer if the keywords for
the two conversions were separate, so somethig like

big_endian;r16_ieee;r16_ibm:10-20;

for the environment variable and

CONVERT="big_endian,r16_ibm"

would probably be better.


Best regards

Thomas


Re: [committed] c++: Add testcase for recently fixed PR [PR69681]

2022-01-07 Thread Jakub Jelinek via Gcc-patches
On Thu, Jan 06, 2022 at 10:44:09AM -0500, Patrick Palka via Gcc-patches wrote:
> Fixed ever since r12-6188.
> 
>   PR c++/69681
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/cpp0x/constexpr-compare2.C: New test.

Note, I've tested my
https://gcc.gnu.org/pipermail/gcc-patches/2022-January/587745.html
patch before you've committed this test, that patch makes it FAIL
again.

The thing is that in address_compare now we make it all the way to
  tree sz0 = DECL_SIZE_UNIT (base0);
  tree sz1 = DECL_SIZE_UNIT (base1);
  /* If sizes are unknown, e.g. VLA or not representable, punt.  */
  if (!tree_fits_poly_int64_p (sz0) || !tree_fits_poly_int64_p (sz1))
return 2;
which wants to check if one pointer is to a start of one object and
another pointer to the end of another one.  But, base0 and base1
are both FUNCTION_DECLs, and those seem to never have DECL_SIZE_UNIT
set on them, whether the functions are external or defined locally.

We've already proven that base0 and base1 are different.  Can we
with folding_initializer set (or even unset?) assume that if one
or both of the bases are FUNCTION_DECLs they will compare unequal
regardless if the other pointer is at the start or end of some
variable?  For the !folding_initializer case, one thing is that
while we've dealt with aliases visible to the compiler already and
punted, there could again be aliases not visible to the compiler
etc.  There is also a theoretical chance that .text section
with some functions in it could be immediately followed by .rodata
section with variables, but zero sized functions are rare and using
address arithmetics to get to the end of a function isn't something
we should support.  Some functions and variables could be also
defined in assembly and could be adjacent...
So at least limiting it to folding_initializer would be wise,
but the question is what exactly should be valid and what should
be invalid in C++.

So, thoughts on this?

> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-compare2.C
> @@ -0,0 +1,10 @@
> +// PR c++/69681
> +// { dg-do compile { target c++11 } }
> +
> +void f();
> +void g();
> +static_assert(f != g, "");
> +
> +#if __cpp_constexpr >= 201603L
> +static_assert([]{} != []{}, "");
> +#endif
> -- 
> 2.34.1.493.ge83ba647f7

Jakub



[power-ieee128] OPEN CONV

2022-01-07 Thread Jakub Jelinek via Gcc-patches
On Thu, Jan 06, 2022 at 09:01:54PM +0100, Thomas Koenig wrote:
> 
> On 06.01.22 06:00, Michael Meissner via Fortran wrote:
> What is still missing is the conversion for unformatted I/O, both
> ways.  I'll start doing some stuff on it. Just one question:
> What are functions that I can use to convert from IBM long double
> to IEEE and long double and vice versa?  It was in an e-mail somewhere,
> but I cannot find it at the moment.

So, what's the plan for that?
Can't find CONVERT= in Fortran 2018, so I assume it is a non-standard
extension,
https://www.intel.com/content/www/us/en/develop/documentation/fortran-compiler-oneapi-dev-guide-and-reference/top/language-reference/file-operation-i-o-statements/open-statement-specifiers/open-convert-specifier.html#open-convert-specifier
documents the Intel one and we accept
CONVERT='native'
CONVERT='swap'
CONVERT='big_endian'
CONVERT='little_endian'
Now, I suppose for powerpc64le we want to add
some more, but the question is how they play together
with the byteswapping and how to name them, so that
it is clear they talk about REAL/COMPLEX KIND=16 format
and nothing else.  Can we (or do we) want to allow
multiple comma separated strings from the orthogonal
choices, like
CONVERT='big_endian,ibm_extended'
CONVERT='swap,ieee_extended'
or add ibm_extended, ieee_extended and strings that
combine those with swap, big_endian and little_endian
ibm_extended_swap, ieee_extended_little etc.?

Jakub



Re: [PATCH] nvptx: Add support for PTX's cnot instruction.

2022-01-07 Thread Tom de Vries via Gcc-patches

On 1/6/22 17:42, Roger Sayle wrote:


Happy New Year for 2022.  This is a simple patch, now that the
nvptx backend has transitioned to STORE_FLAG_VALUE=1, that adds
support for NVidia's cnot instruction, that implements C/C++
style logical negation.



Happy newyear to you too :)

LGTM, please apply.

Thanks,
- Tom


Previously, the simple function:

int foo(int x) { return !x; }

on nvptx-none with -O2 would generate:

 mov.u32 %r24, %ar0;
 setp.eq.u32 %r28, %r24, 0;
 selp.u32%value, 1, 0, %r28;

with this patch, GCC now generates:

 mov.u32 %r24, %ar0;
 cnot.b32%value, %r24;


This patch has been tested on nvptx-none hosted on x86_64-pc-linux-gnu
(including newlib) with a make and make -k check with no new failures.
Ok for mainline?


2022-01-06  Roger Sayle  

gcc/ChangeLog
* config/nvptx/nvptx.md (*cnot2): New define_insn.

gcc/testsuite/ChangeLog
* gcc.target/nvptx/cnot-1.c: New test case.


Thanks in advance,
Roger
--