Re: [PATCH] loongarch: ignore zero-size fields in calling convention

2022-04-25 Thread WANG Xuerui

On 4/25/22 13:57, Xi Ruoyao wrote:

Ping.

Normally we shouldn't ping a patch after only a few days, but we're
running out of time to catch GCC 12 milestone.  And once GCC 12 is
released the patch will become far more complicated for a psABI warning.

And please note that the ABI difference between GCC and G++ should be
considered a bug, and it has to be fixed anyway.  If you don't like the
idea of this patch, please develop another solution and apply it *before
GCC 12*.

On Wed, 2022-04-20 at 14:23 +0800, Xi Ruoyao via Gcc-patches wrote:

Currently, LoongArch ELF psABI is not clear on the handling of zero-
sized fields in aggregates arguments or return values [1].  The behavior
of GCC trunk is puzzling considering the following cases:

struct test1
{
   double a[0];
   float x;
};

struct test2
{
   float a[0];
   float x;
};

GCC trunk passes test1::x via GPR, but test2::x via FPR.  I believe no
rational Homo Sapiens can understand (or even expect) this.

And, to make things even worse, test1 behaves differently in C and C++.
GCC trunk passes test1::x via GPR, but G++ trunk passes test1::x via
FPR.

I've write a paragraph about current GCC behavior for the psABI [2], but
I think it's cleaner to just ignore all zero-sized fields in the ABI.
This will require only a two-line change in GCC (this patch), and an
one-line change in the ABI doc.

If there is not any better idea I'd like to see this reviewed and
applied ASAP.  If we finally have to apply this patch after GCC 12
release, we'll need to add a lot more boring code to emit a -Wpsabi
inform [3].  That will be an unnecessary burden for both us, and the
users using the compiler (as the compiler will spend CPU time only for
checking if a warning should be informed).

[1]:https://github.com/loongson/LoongArch-Documentation/issues/48
[2]:https://github.com/loongson/LoongArch-Documentation/pull/49
[3]:https://gcc.gnu.org/PR102024

gcc/

 * config/loongarch/loongarch.cc
 (loongarch_flatten_aggregate_field): Ignore empty fields for
 RECORD_TYPE.

gcc/testsuite/

 * gcc.target/loongarch/zero-size-field-pass.c: New test.
 * gcc.target/loongarch/zero-size-field-ret.c: New test.
---
  gcc/config/loongarch/loongarch.cc |  3 ++
  .../loongarch/zero-size-field-pass.c  | 30 +++
  .../loongarch/zero-size-field-ret.c   | 28 +
  3 files changed, 61 insertions(+)
  create mode 100644 gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c
  create mode 100644 gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c

Agreed; this is urgent. While I haven't personally got around to testing 
this yet, I have looked at the linked LoongArch psABI spec change and 
agree with the present approach.




[gcov v2 00/14] Add merge-stream subcommand to gcov-tool

2022-04-25 Thread Sebastian Huber
This patch set is for GCC 13.

The aim is to better support gcov in free-standing environments. For example,
you can run a test executable which dumps all gcov info objects in a serial
data stream using __gcov_info_to_gcda() and the new __gcov_filename_to_gcfn().
It could be encoded as base64. It could be also compressed. On the host you
unpack the encoded data stream and feed it into gcov-tool using the new
"merge-stream" subcommand:

gcov-tool --help
Usage: gcov-tool [OPTION]... SUB_COMMAND [OPTION]...

Offline tool to handle gcda counts

  -h, --helpPrint this help, then exit
  -v, --version Print version number, then exit
  merge-stream [options] [stream-file]  Merge coverage stream file (or stdin)
and coverage file contents
-v, --verbose   Verbose mode
-w, --weight Set weights (float point values)

Example:

base64 -d log.txt | gcov-tool merge-stream

The patch set does not change the format of .gcda files.

TODO:

* Tests for gcov-tool

v2:

* Address review comments from v1

* Simple test for __gcov_filename_to_gcfn()

* Use xstrerror()

* Add documentation

Sebastian Huber (14):
  gcov-tool: Allow merging of empty profile lists
  gcov: Add mode to all gcov_open()
  gcov: Add open mode parameter to gcov_do_dump()
  gcov: Make gcov_seek() static
  gcov: Add __gcov_filename_to_gcfn()
  gcov-tool: Support file input from stdin
  gcov: Use xstrdup()
  gcov: Move prepend to list to read_gcda_file()
  gcov: Move gcov_open() to caller of read_gcda_file()
  gcov: Fix integer types in ftw_read_file()
  gcov: Record EOF error during read
  gcov-tool: Add merge-stream subcommand
  gcov: Use xstrerror()
  gcov: Add section for freestanding environments

 gcc/doc/gcov-tool.texi   |  36 +++
 gcc/doc/gcov.texi| 375 +++
 gcc/doc/invoke.texi  |  31 +-
 gcc/gcov-io.cc   |  79 +++--
 gcc/gcov-io.h|  35 ++-
 gcc/gcov-tool.cc | 107 +--
 gcc/testsuite/gcc.dg/gcov-info-to-gcda.c |  36 ++-
 libgcc/gcov.h|  17 +-
 libgcc/libgcov-driver-system.c   |   7 +-
 libgcc/libgcov-driver.c  |  44 ++-
 libgcc/libgcov-util.c| 150 +++--
 libgcc/libgcov.h |   3 -
 12 files changed, 803 insertions(+), 117 deletions(-)

-- 
2.34.1



[gcov v2 01/14] gcov-tool: Allow merging of empty profile lists

2022-04-25 Thread Sebastian Huber
The gcov_profile_merge() already had code to deal with profile information
which had no counterpart to merge with.  For profile information from files
with no associated counterpart, the profile information is simply used as is
with the weighting transformation applied.  Make sure that gcov_profile_merge()
works with an empty target profile list.  Return the merged profile list.

gcc/
* gcov-tool.cc (gcov_profile_merge): Adjust return type.
(profile_merge): Allow merging of directories which contain no profile
files.

libgcc/
* libgcov-util.c (gcov_profile_merge): Return the list of merged
profiles.  Accept empty target and source profile lists.
---
 gcc/gcov-tool.cc  | 27 ++-
 libgcc/libgcov-util.c | 19 +++
 2 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index f4e42ae763c..2e4083a664d 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -40,7 +40,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 #endif
 #include 
 
-extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
+struct gcov_info*, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -141,26 +142,18 @@ profile_merge (const char *d1, const char *d2, const char 
*out, int w1, int w2)
 {
   struct gcov_info *d1_profile;
   struct gcov_info *d2_profile;
-  int ret;
+  struct gcov_info *merged_profile;
 
   d1_profile = gcov_read_profile_dir (d1, 0);
-  if (!d1_profile)
-return 1;
-
-  if (d2)
-{
-  d2_profile = gcov_read_profile_dir (d2, 0);
-  if (!d2_profile)
-return 1;
+  d2_profile = gcov_read_profile_dir (d2, 0);
 
-  /* The actual merge: we overwrite to d1_profile.  */
-  ret = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
+  /* The actual merge: we overwrite to d1_profile.  */
+  merged_profile = gcov_profile_merge (d1_profile, d2_profile, w1, w2);
 
-  if (ret)
-return ret;
-}
-
-  gcov_output_files (out, d1_profile);
+  if (merged_profile)
+gcov_output_files (out, merged_profile);
+  else if (verbose)
+fnotice (stdout, "no profile files were merged\n");
 
   return 0;
 }
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ba7fb924b53..100f1b19f1a 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -674,16 +674,16 @@ find_match_gcov_info (struct gcov_info **array, int size,
 }
 
 /* Merge the list of gcov_info objects from SRC_PROFILE to TGT_PROFILE.
-   Return 0 on success: without mismatch.
-   Reutrn 1 on error.  */
+   Return the list of merged gcov_info objects.  Return NULL if the list is
+   empty.  */
 
-int
+struct gcov_info *
 gcov_profile_merge (struct gcov_info *tgt_profile, struct gcov_info 
*src_profile,
 int w1, int w2)
 {
   struct gcov_info *gi_ptr;
   struct gcov_info **tgt_infos;
-  struct gcov_info *tgt_tail;
+  struct gcov_info **tgt_tail;
   struct gcov_info **in_src_not_tgt;
   unsigned tgt_cnt = 0, src_cnt = 0;
   unsigned unmatch_info_cnt = 0;
@@ -703,7 +703,10 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   for (gi_ptr = tgt_profile, i = 0; gi_ptr; gi_ptr = gi_ptr->next, i++)
 tgt_infos[i] = gi_ptr;
 
-  tgt_tail = tgt_infos[tgt_cnt - 1];
+  if (tgt_cnt)
+ tgt_tail = &tgt_infos[tgt_cnt - 1]->next;
+  else
+ tgt_tail = &tgt_profile;
 
   /* First pass on tgt_profile, we multiply w1 to all counters.  */
   if (w1 > 1)
@@ -732,14 +735,14 @@ gcov_profile_merge (struct gcov_info *tgt_profile, struct 
gcov_info *src_profile
   gi_ptr = in_src_not_tgt[i];
   gcov_merge (gi_ptr, gi_ptr, w2 - 1);
   gi_ptr->next = NULL;
-  tgt_tail->next = gi_ptr;
-  tgt_tail = gi_ptr;
+  *tgt_tail = gi_ptr;
+  tgt_tail = &gi_ptr->next;
 }
 
   free (in_src_not_tgt);
   free (tgt_infos);
 
-  return 0;
+  return tgt_profile;
 }
 
 typedef gcov_type (*counter_op_fn) (gcov_type, void*, void*);
-- 
2.34.1



[gcov v2 02/14] gcov: Add mode to all gcov_open()

2022-04-25 Thread Sebastian Huber
gcc/

* gcov-io.cc (gcov_open): Always use the mode parameter.
* gcov-io.h (gcov_open): Declare it unconditionally.

libgcc/

* libgcov-driver-system.c (gcov_exit_open_gcda_file): Open file for
reading and writing.
* libgcov-util.c (read_gcda_file): Open file for reading.
* libgcov.h (gcov_open): Delete declaration.
---
 gcc/gcov-io.cc | 7 ---
 gcc/gcov-io.h  | 5 +
 libgcc/libgcov-driver-system.c | 4 ++--
 libgcc/libgcov-util.c  | 2 +-
 libgcc/libgcov.h   | 1 -
 5 files changed, 4 insertions(+), 15 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 72c40f8eaa0..017a6e32a5d 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -89,15 +89,8 @@ from_file (gcov_unsigned_t value)
Return zero on failure, non-zero on success.  */
 
 GCOV_LINKAGE int
-#if IN_LIBGCOV
-gcov_open (const char *name)
-#else
 gcov_open (const char *name, int mode)
-#endif
 {
-#if IN_LIBGCOV
-  int mode = 0;
-#endif
 #if GCOV_LOCKED
   struct flock s_flock;
   int fd;
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 99ce7dbccc8..afe74b002f1 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -347,15 +347,12 @@ struct gcov_summary
functions for writing.  Your file may become corrupted if you break
these invariants.  */
 
-#if !IN_LIBGCOV
-GCOV_LINKAGE int gcov_open (const char */*name*/, int /*direction*/);
-#endif
-
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
 GCOV_LINKAGE int gcov_magic (gcov_unsigned_t, gcov_unsigned_t);
 #endif
 
 /* Available everywhere.  */
+GCOV_LINKAGE int gcov_open (const char *, int) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE int gcov_close (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE gcov_type gcov_read_counter (void) ATTRIBUTE_HIDDEN;
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index eef6e3cbda1..9abb2fe7f74 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -309,7 +309,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
 
   gf->filename = replace_filename_variables (gf->filename);
 
-  if (!gcov_open (gf->filename))
+  if (!gcov_open (gf->filename, 0))
 {
   /* Open failed likely due to missed directory.
  Create directory and retry to open file. */
@@ -318,7 +318,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
   fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
   return -1;
 }
-  if (!gcov_open (gf->filename))
+  if (!gcov_open (gf->filename, 0))
 {
   fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
   return -1;
diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 100f1b19f1a..db157220c9d 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -268,7 +268,7 @@ read_gcda_file (const char *filename)
 k_ctrs_mask[i] = 0;
   k_ctrs_types = 0;
 
-  if (!gcov_open (filename))
+  if (!gcov_open (filename, 1))
 {
   fnotice (stderr, "%s:cannot open\n", filename);
   return NULL;
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 40e845ce3ea..f190547e819 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -343,7 +343,6 @@ extern int __gcov_execve (const char *, char  *const [], 
char *const [])
   ATTRIBUTE_HIDDEN;
 
 /* Functions that only available in libgcov.  */
-GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
   const struct gcov_summary *)
 ATTRIBUTE_HIDDEN;
-- 
2.34.1



[gcov v2 04/14] gcov: Make gcov_seek() static

2022-04-25 Thread Sebastian Huber
This function is only used by gcov_write_length() in the gcov-io.cc file.

gcc/

* gcov-io.cc (gcov_seek): Make it static.
* gcov-io.h (struct gcov_summary): Do not mention gcov_seek().

libgcc/

* libgcov.h (gcov_seek): Remove define and declaration.
---
 gcc/gcov-io.cc   | 4 +---
 gcc/gcov-io.h| 6 +++---
 libgcc/libgcov.h | 2 --
 3 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 017a6e32a5d..fee3130f94a 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -294,17 +294,15 @@ gcov_write_filename (const char *filename)
 
   gcov_write_string (filename);
 }
-#endif
 
 /* Move to a given position in a gcov file.  */
 
-GCOV_LINKAGE void
+static void
 gcov_seek (gcov_position_t base)
 {
   fseek (gcov_var.file, base, SEEK_SET);
 }
 
-#if !IN_LIBGCOV
 /* Write a tag TAG and reserve space for the record length. Return a
value to be used for gcov_write_length.  */
 
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index afe74b002f1..204ae0ccf7f 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -340,9 +340,9 @@ struct gcov_summary
 /* Functions for reading and writing gcov files. In libgcov you can
open the file for reading then writing. Elsewhere you can open the
file either for reading or for writing. When reading a file you may
-   use the gcov_read_* functions, gcov_sync, gcov_position, &
-   gcov_error. When writing a file you may use the gcov_write
-   functions, gcov_seek & gcov_error. When a file is to be rewritten
+   use the gcov_read_* functions, gcov_sync, gcov_position, and
+   gcov_error. When writing a file you may use the gcov_write*
+   functions and gcov_error. When a file is to be rewritten
you use the functions for reading, then gcov_rewrite then the
functions for writing.  Your file may become corrupted if you break
these invariants.  */
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index f190547e819..487bd1464cd 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -115,7 +115,6 @@ typedef unsigned gcov_type_unsigned __attribute__ ((mode 
(QI)));
 #define gcov_open __gcov_open
 #define gcov_close __gcov_close
 #define gcov_position __gcov_position
-#define gcov_seek __gcov_seek
 #define gcov_rewrite __gcov_rewrite
 #define gcov_is_error __gcov_is_error
 #define gcov_write_unsigned __gcov_write_unsigned
@@ -346,7 +345,6 @@ extern int __gcov_execve (const char *, char  *const [], 
char *const [])
 GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
   const struct gcov_summary *)
 ATTRIBUTE_HIDDEN;
-GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
 GCOV_LINKAGE void gcov_rewrite (void) ATTRIBUTE_HIDDEN;
 
 /* "Counts" stored in gcda files can be a real counter value, or
-- 
2.34.1



[gcov v2 12/14] gcov-tool: Add merge-stream subcommand

2022-04-25 Thread Sebastian Huber
gcc/

* doc/gcov-tool.texi: Document merge-stream subcommand.
* doc/invoke.texi (fprofile-info-section): Mention merge-stream
subcommand of gcov-tool.
* gcov-tool.cc (gcov_profile_merge_stream): Declare.
(print_merge_stream_usage_message): New.
(merge_stream_usage): Likewise.
(do_merge_stream): Likewise.
(print_usage): Call print_merge_stream_usage_message().
(main): Call do_merge_stream() to execute merge-stream subcommand.

libgcc/

* libgcov-util.c (consume_stream): New.
(get_target_profiles_for_merge): Likewise.
(gcov_profile_merge_stream): Likewise.
---
 gcc/doc/gcov-tool.texi | 36 
 gcc/doc/invoke.texi|  5 +++
 gcc/gcov-tool.cc   | 76 +
 libgcc/libgcov-util.c  | 95 ++
 4 files changed, 212 insertions(+)

diff --git a/gcc/doc/gcov-tool.texi b/gcc/doc/gcov-tool.texi
index d79dbc94a8c..77150836acc 100644
--- a/gcc/doc/gcov-tool.texi
+++ b/gcc/doc/gcov-tool.texi
@@ -52,6 +52,10 @@ Current gcov-tool supports the following functionalities:
 @item
 merge two sets of profiles with weights.
 
+@item
+read a stream of profiles with associated filenames and merge it with a set of
+profiles with weights.
+
 @item
 read one set of profile and rewrite profile contents. One can scale or
 normalize the count values.
@@ -64,6 +68,12 @@ Collect the profiles for different set of inputs, and use 
this tool to merge
 them. One can specify the weight to factor in the relative importance of
 each input.
 
+@item
+Collect profiles from target systems without a filesystem (freestanding
+environments).  Merge the collected profiles with associated profiles
+present on the host system.  One can specify the weight to factor in the
+relative importance of each input.
+
 @item
 Rewrite the profile after removing a subset of the gcda files, while 
maintaining
 the consistency of the summary and the histogram.
@@ -117,6 +127,10 @@ gcov-tool merge [merge-options] @var{directory1} 
@var{directory2}
  [@option{-v}|@option{--verbose}]
  [@option{-w}|@option{--weight} @var{w1,w2}]
 
+gcov-tool merge-stream [merge-stream-options] [@var{file}]
+ [@option{-v}|@option{--verbose}]
+ [@option{-w}|@option{--weight} @var{w1,w2}]
+
 gcov-tool rewrite [rewrite-options] @var{directory}
  [@option{-n}|@option{--normalize} @var{long_long_value}]
  [@option{-o}|@option{--output} @var{directory}]
@@ -169,6 +183,28 @@ Set the merge weights of the @var{directory1} and 
@var{directory2},
 respectively. The default weights are 1 for both.
 @end table
 
+@item merge-stream
+Collect profiles with associated filenames from a @emph{gcfn} and @emph{gcda}
+data stream.  Read the stream from the file specified by @var{file} or from
+@file{stdin}.  Merge the profiles with associated profiles in the host
+filesystem.  Apply the optional weights while merging profiles.
+
+For the generation of a @emph{gcfn} and @emph{gcda} data stream on the target
+system, please have a look at the @code{__gcov_filename_to_gcfn()} and
+@code{__gcov_info_to_gcda()} functions declared in @code{#include }.
+@table @gcctabopt
+
+@item -v
+@itemx --verbose
+Set the verbose mode.
+
+@item -w @var{w1},@var{w2}
+@itemx --weight @var{w1},@var{w2}
+Set the merge weights of the profiles from the @emph{gcfn} and @emph{gcda} data
+stream and the associated profiles in the host filesystem, respectively.  The
+default weights are 1 for both.
+@end table
+
 @item rewrite
 Read the specified profile directory and rewrite to a new directory.
 @table @gcctabopt
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index af5495e75c6..cef0fa9f084 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -15537,6 +15537,11 @@ main (void)
 @}
 @end smallexample
 
+The @command{merge-stream} subcommand of @command{gcov-tool} may be used to
+deserialize the data stream generated by the @code{__gcov_filename_to_gcfn} and
+@code{__gcov_info_to_gcda} functions and merge the profile information into
+@file{.gcda} files on the host filesystem.
+
 @item -fprofile-note=@var{path}
 @opindex fprofile-note
 
diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index d712715cf7e..ceb250143c8 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 
 extern struct gcov_info *gcov_profile_merge (struct gcov_info*,
 struct gcov_info*, int, int);
+extern struct gcov_info *gcov_profile_merge_stream (const char *, int, int);
 extern int gcov_profile_overlap (struct gcov_info*, struct gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
@@ -229,6 +230,78 @@ do_merge (int argc, char **argv)
   return profile_merge (argv[optind], argv[optind+1], output_dir, w1, w2);
 }
 
+/* Usage message f

[gcov v2 03/14] gcov: Add open mode parameter to gcov_do_dump()

2022-04-25 Thread Sebastian Huber
gcc/

* gcov-tool.cc (gcov_do_dump): Add mode parameter.
(gcov_output_files): Open files for reading and writing.

libgcc/

* libgcov-driver-system.c (gcov_exit_open_gcda_file): Add mode
parameter.  Pass mode to gcov_open() calls.
* libgcov-driver.c (dump_one_gcov):  Add mode parameter.  Pass mode to
gcov_exit_open_gcda_file() call.
(gcov_do_dump): Add mode parameter.  Pass mode to dump_one_gcov()
calls.
(__gcov_dump_one):  Open file for reading and writing.
---
 gcc/gcov-tool.cc   |  4 ++--
 libgcc/libgcov-driver-system.c |  7 ---
 libgcc/libgcov-driver.c| 12 ++--
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/gcc/gcov-tool.cc b/gcc/gcov-tool.cc
index 2e4083a664d..d712715cf7e 100644
--- a/gcc/gcov-tool.cc
+++ b/gcc/gcov-tool.cc
@@ -46,7 +46,7 @@ extern int gcov_profile_overlap (struct gcov_info*, struct 
gcov_info*);
 extern int gcov_profile_normalize (struct gcov_info*, gcov_type);
 extern int gcov_profile_scale (struct gcov_info*, float, int, int);
 extern struct gcov_info* gcov_read_profile_dir (const char*, int);
-extern void gcov_do_dump (struct gcov_info *, int);
+extern void gcov_do_dump (struct gcov_info *, int, int);
 extern const char *gcov_get_filename (struct gcov_info *list);
 extern void gcov_set_verbose (void);
 
@@ -124,7 +124,7 @@ gcov_output_files (const char *out, struct gcov_info 
*profile)
 fatal_error (input_location, "output file %s already exists in folder %s",
 filename, out);
 
-  gcov_do_dump (profile, 0);
+  gcov_do_dump (profile, 0, 0);
 
   ret = chdir (pwd);
   if (ret)
diff --git a/libgcc/libgcov-driver-system.c b/libgcc/libgcov-driver-system.c
index 9abb2fe7f74..ac405c38e3a 100644
--- a/libgcc/libgcov-driver-system.c
+++ b/libgcc/libgcov-driver-system.c
@@ -261,7 +261,8 @@ allocate_filename_struct (struct gcov_filename *gf)
 
 static int
 gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
- struct gcov_filename *gf)
+ struct gcov_filename *gf,
+ int mode)
 {
   int append_slash = 0;
   const char *fname = gi_ptr->filename;
@@ -309,7 +310,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
 
   gf->filename = replace_filename_variables (gf->filename);
 
-  if (!gcov_open (gf->filename, 0))
+  if (!gcov_open (gf->filename, mode))
 {
   /* Open failed likely due to missed directory.
  Create directory and retry to open file. */
@@ -318,7 +319,7 @@ gcov_exit_open_gcda_file (struct gcov_info *gi_ptr,
   fprintf (stderr, "profiling:%s:Skip\n", gf->filename);
   return -1;
 }
-  if (!gcov_open (gf->filename, 0))
+  if (!gcov_open (gf->filename, mode))
 {
   fprintf (stderr, "profiling:%s:Cannot open\n", gf->filename);
   return -1;
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 7e52c5676e5..10831e84b61 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -595,14 +595,14 @@ write_one_data (const struct gcov_info *gi_ptr,
 static void
 dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
   unsigned run_counted ATTRIBUTE_UNUSED,
-  gcov_type run_max ATTRIBUTE_UNUSED)
+  gcov_type run_max ATTRIBUTE_UNUSED, int mode)
 {
   struct gcov_summary summary = {};
   int error;
   gcov_unsigned_t tag;
   fn_buffer = 0;
 
-  error = gcov_exit_open_gcda_file (gi_ptr, gf);
+  error = gcov_exit_open_gcda_file (gi_ptr, gf, mode);
   if (error == -1)
 return;
 
@@ -649,13 +649,13 @@ read_fatal:;
 
 /* Dump all the coverage counts for the program. It first computes program
summary and then traverses gcov_list list and dumps the gcov_info
-   objects one by one.  */
+   objects one by one.  Use MODE to open files.  */
 
 #if !IN_GCOV_TOOL
 static
 #endif
 void
-gcov_do_dump (struct gcov_info *list, int run_counted)
+gcov_do_dump (struct gcov_info *list, int run_counted, int mode)
 {
   struct gcov_info *gi_ptr;
   struct gcov_filename gf;
@@ -678,7 +678,7 @@ gcov_do_dump (struct gcov_info *list, int run_counted)
   /* Now merge each file.  */
   for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
 {
-  dump_one_gcov (gi_ptr, &gf, run_counted, run_max);
+  dump_one_gcov (gi_ptr, &gf, run_counted, run_max, mode);
   free (gf.filename);
 }
 
@@ -701,7 +701,7 @@ __gcov_dump_one (struct gcov_root *root)
   if (root->dumped)
 return;
 
-  gcov_do_dump (root->list, root->run_counted);
+  gcov_do_dump (root->list, root->run_counted, 0);
   
   root->dumped = 1;
   root->run_counted = 1;
-- 
2.34.1



[gcov v2 09/14] gcov: Move gcov_open() to caller of read_gcda_file()

2022-04-25 Thread Sebastian Huber
This allows to reuse read_gcda_file() to read multiple objects from a single
file.

libgcc/

* libgcov-util.c (read_gcda_file): Do not open file.
(ftw_read_file): Open file here.
---
 libgcc/libgcov-util.c | 16 +++-
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 906ea645547..6093a74531d 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -268,17 +268,10 @@ read_gcda_file (const char *filename)
 k_ctrs_mask[i] = 0;
   k_ctrs_types = 0;
 
-  if (!gcov_open (filename, 1))
-{
-  fnotice (stderr, "%s:cannot open\n", filename);
-  return NULL;
-}
-
   /* Read magic.  */
   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
 {
   fnotice (stderr, "%s:not a gcov data file\n", filename);
-  gcov_close ();
   return NULL;
 }
 
@@ -287,7 +280,6 @@ read_gcda_file (const char *filename)
   if (version != GCOV_VERSION)
 {
   fnotice (stderr, "%s:incorrect gcov version %d vs %d \n", filename, 
version, GCOV_VERSION);
-  gcov_close ();
   return NULL;
 }
 
@@ -379,7 +371,6 @@ read_gcda_file (const char *filename)
 }
 
   read_gcda_finalize (obj_info);
-  gcov_close ();
 
   return obj_info;
 }
@@ -412,7 +403,14 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
+  if (!gcov_open (filename, 1))
+{
+  fnotice (stderr, "%s:cannot open\n", filename);
+  return 0;
+}
+
   (void)read_gcda_file (xstrdup (filename));
+  gcov_close ();
 
   return 0;
 }
-- 
2.34.1



[gcov v2 11/14] gcov: Record EOF error during read

2022-04-25 Thread Sebastian Huber
Use an enum for file error codes.

gcc/

* gcov-io.cc (gcov_file_error): New enum.
(gcov_var): Use gcov_file_error enum for the error member.
(gcov_open): Use GCOV_FILE_NO_ERROR.
(gcov_close): Use GCOV_FILE_WRITE_ERROR.
(gcov_write): Likewise.
(gcov_write_unsigned): Likewise.
(gcov_write_string): Likewise.
(gcov_read_bytes): Set error code if EOF is reached.
(gcov_read_counter): Use GCOV_FILE_COUNTER_OVERFLOW.
---
 gcc/gcov-io.cc | 30 ++
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index 7e1fb10b612..fdf745e6ce1 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -29,10 +29,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
 static gcov_unsigned_t *gcov_read_words (void *buffer, unsigned);
 
+/* Indicates the last gcov file access error or that no error occurred
+   so far.  */
+enum gcov_file_error
+{
+  GCOV_FILE_COUNTER_OVERFLOW = -1,
+  GCOV_FILE_NO_ERROR = 0,
+  GCOV_FILE_WRITE_ERROR = 1,
+  GCOV_FILE_EOF = 2
+};
+
 struct gcov_var
 {
   FILE *file;
-  int error;   /* < 0 overflow, > 0 disk error.  */
+  enum gcov_file_error error;
   int mode;/* < 0 writing, > 0 reading.  */
   int endian;  /* Swap endianness.  */
 #ifdef IN_GCOV_TOOL
@@ -113,7 +123,7 @@ gcov_open (const char *name, int mode)
 #endif
 
   gcov_nonruntime_assert (!gcov_var.file);
-  gcov_var.error = 0;
+  gcov_var.error = GCOV_FILE_NO_ERROR;
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
   gcov_var.endian = 0;
 #endif
@@ -217,7 +227,7 @@ gcov_close (void)
   if (gcov_var.file)
 {
   if (fclose (gcov_var.file))
-   gcov_var.error = 1;
+   gcov_var.error = GCOV_FILE_WRITE_ERROR;
 
   gcov_var.file = 0;
 }
@@ -253,7 +263,7 @@ gcov_write (const void *data, unsigned length)
 {
   gcov_unsigned_t r = fwrite (data, length, 1, gcov_var.file);
   if (r != 1)
-gcov_var.error = 1;
+gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 
 /* Write unsigned VALUE to coverage file.  */
@@ -263,7 +273,7 @@ gcov_write_unsigned (gcov_unsigned_t value)
 {
   gcov_unsigned_t r = fwrite (&value, sizeof (value), 1, gcov_var.file);
   if (r != 1)
-gcov_var.error = 1;
+gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 
 #if !IN_LIBGCOV
@@ -283,7 +293,7 @@ gcov_write_string (const char *string)
 {
   gcov_unsigned_t r = fwrite (string, length, 1, gcov_var.file);
   if (r != 1)
-   gcov_var.error = 1;
+   gcov_var.error = GCOV_FILE_WRITE_ERROR;
 }
 }
 #endif
@@ -385,7 +395,11 @@ gcov_read_bytes (void *buffer, unsigned count)
 
   unsigned read = fread (buffer, count, 1, gcov_var.file);
   if (read != 1)
-return NULL;
+{
+  if (feof (gcov_var.file))
+   gcov_var.error = GCOV_FILE_EOF;
+  return NULL;
+}
 
 #ifdef IN_GCOV_TOOL
   gcov_var.pos += count;
@@ -434,7 +448,7 @@ gcov_read_counter (void)
   if (sizeof (value) > sizeof (gcov_unsigned_t))
 value |= ((gcov_type) from_file (buffer[1])) << 32;
   else if (buffer[1])
-gcov_var.error = -1;
+gcov_var.error = GCOV_FILE_COUNTER_OVERFLOW;
 
   return value;
 }
-- 
2.34.1



[gcov v2 14/14] gcov: Add section for freestanding environments

2022-04-25 Thread Sebastian Huber
gcc/

* doc/gcov.texi (Profiling and Test Coverage in Freestanding
Environments): New section.
---
 gcc/doc/gcov.texi | 375 ++
 1 file changed, 375 insertions(+)

diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
index fc39da0f02d..751a11314f3 100644
--- a/gcc/doc/gcov.texi
+++ b/gcc/doc/gcov.texi
@@ -41,6 +41,8 @@ test code coverage in your programs.
 * Gcov and Optimization::   Using gcov with GCC optimization.
 * Gcov Data Files:: The files used by gcov.
 * Cross-profiling:: Data file relocation.
+* Freestanding Environments::   How to use profiling and test
+coverage in freestanding environments.
 @end menu
 
 @node Gcov Intro
@@ -971,3 +973,376 @@ setting will name the data file 
@file{/target/run/build/foo.gcda}.
 You must move the data files to the expected directory tree in order to
 use them for profile directed optimizations (@option{-fprofile-use}), or to
 use the @command{gcov} tool.
+
+@node Freestanding Environments
+@section Profiling and Test Coverage in Freestanding Environments
+
+In case your application runs in a hosted environment such as GNU/Linux, then
+this section is likely not relevant to you.  This section is intended for
+application developers targeting freestanding environments (for example
+embedded systems) with limited resources.  In particular, systems or test cases
+which do not support constructors/destructors or the C library file I/O.  In
+this section, the @dfn{target system} runs your application instrumented for
+profiling or test coverage.  You develop and analyze your application on the
+@dfn{host system}.  We give now an overview how profiling and test coverage can
+be obtained in this scenario followed by a tutorial which can be exercised on
+the host system.  Finally, some system initialization caveats are listed.
+
+@subsection Overview
+
+For an application instrumented for profiling or test coverage, the compiler
+generates some global data structures which are updated by instrumentation code
+while the application runs.  These data structures are called the @dfn{gcov
+information}.  Normally, when the application exits, the gcov information is
+stored to @file{.gcda} files.  There is one file per translation unit
+instrumented for profiling or test coverage.  The function
+@code{__gcov_exit()}, which stores the gcov information to a file, is called by
+a global destructor function for each translation unit instrumented for
+profiling or test coverage.  It runs at process exit.  In a global constructor
+function, the @code{__gcov_init()} function is called to register the gcov
+information of a translation unit in a global list.  In some situations, this
+procedure does not work.  Firstly, if you want to profile the global
+constructor or exit processing of an operating system, the compiler generated
+functions may conflict with the test objectives.  Secondly, you may want to
+test early parts of the system initialization or abnormal program behaviour
+which do not allow a global constructor or exit processing.  Thirdly, you need
+a filesystem to store the files.
+
+The @option{-fprofile-info-section} GCC option enables you to use profiling and
+test coverage in freestanding environments.  This option disables the use of
+global constructors and destructors for the gcov information.  Instead, a
+pointer to the gcov information is stored in a special linker input section for
+each translation unit which is compiled with this option.  By default, the
+section name is @code{.gcov_info}.  The gcov information is statically
+initialized.  The pointers to the gcov information from all translation units
+of an executable can be collected by the linker in a continuous memory block.
+For the GNU linker, the below linker script output section definition can be
+used to achieve this:
+
+@smallexample
+  .gcov_info  :
+  @{
+PROVIDE (__gcov_info_start = .);
+KEEP (*(.gcov_info))
+PROVIDE (__gcov_info_end = .);
+  @}
+@end smallexample
+
+The linker will provide two global symbols, @code{__gcov_info_start} and
+@code{__gcov_info_end}, which define the start and end of the array of pointers
+to gcov information blocks, respectively.  The @code{KEEP ()} directive is
+required to prevent a garbage collection of the pointers.  They are not
+directly referenced by anything in the executable.  The section may be placed
+in a read-only memory area.
+
+In order to transfer the profiling and test coverage data from the target to
+the host system, the application has to provide a function to produce a
+reliable in order byte stream from the target to the host.  The byte stream may
+be compressed and encoded using error detection and correction codes to meet
+application-specific requirements.  The GCC provided @file{libgcov} target
+library provides two functions, @code{__gcov_info_to_gcda()} and
+@code{__gcov_filename_to_gcfn()}, to generate a b

[gcov v2 10/14] gcov: Fix integer types in ftw_read_file()

2022-04-25 Thread Sebastian Huber
libgcc/

* libgcov-util.c (ftw_read_file): Use size_t for strlen() variables.
---
 libgcc/libgcov-util.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 6093a74531d..bf96f508db0 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -384,8 +384,8 @@ ftw_read_file (const char *filename,
const struct stat *status ATTRIBUTE_UNUSED,
int type)
 {
-  int filename_len;
-  int suffix_len;
+  size_t filename_len;
+  size_t suffix_len;
 
   /* Only read regular files.  */
   if (type != FTW_F)
-- 
2.34.1



[gcov v2 08/14] gcov: Move prepend to list to read_gcda_file()

2022-04-25 Thread Sebastian Huber
This helps to reuse read_gcda_file().

libgcc/

* libgcov-util.c (read_gcda_file): Prepend new info object to global
list.
(ftw_read_file): Remove list append here.
---
 libgcc/libgcov-util.c | 11 ---
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index ae5712c0138..906ea645547 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -301,6 +301,9 @@ read_gcda_file (const char *filename)
   num_fn_info = 0;
   curr_fn_info = 0;
 
+  /* Prepend to global gcov info list.  */
+  obj_info->next = gcov_info_head;
+  gcov_info_head = obj_info;
 
   /* Read stamp.  */
   obj_info->stamp = gcov_read_unsigned ();
@@ -392,7 +395,6 @@ ftw_read_file (const char *filename,
 {
   int filename_len;
   int suffix_len;
-  struct gcov_info *obj_info;
 
   /* Only read regular files.  */
   if (type != FTW_F)
@@ -410,12 +412,7 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
-  obj_info = read_gcda_file (xstrdup (filename));
-  if (!obj_info)
-return 0;
-
-  obj_info->next = gcov_info_head;
-  gcov_info_head = obj_info;
+  (void)read_gcda_file (xstrdup (filename));
 
   return 0;
 }
-- 
2.34.1



[gcov v2 07/14] gcov: Use xstrdup()

2022-04-25 Thread Sebastian Huber
Move duplication of filename to caller and use xstrdup() instead of custom
code.  This helps to reuse read_gcda_file() for other purposes.

libgcc/

* libgcov-util.c (read_gcda_file): Do not duplicate filename.
(ftw_read_file): Duplicate filename for read_gcda_file().
---
 libgcc/libgcov-util.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index db157220c9d..ae5712c0138 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -296,16 +296,11 @@ read_gcda_file (const char *filename)
  sizeof (struct gcov_ctr_info) * GCOV_COUNTERS, 1);
 
   obj_info->version = version;
+  obj_info->filename = filename;
   obstack_init (&fn_info);
   num_fn_info = 0;
   curr_fn_info = 0;
-  {
-size_t len = strlen (filename) + 1;
-char *str_dup = (char*) xmalloc (len);
 
-memcpy (str_dup, filename, len);
-obj_info->filename = str_dup;
-  }
 
   /* Read stamp.  */
   obj_info->stamp = gcov_read_unsigned ();
@@ -415,7 +410,7 @@ ftw_read_file (const char *filename,
   if (verbose)
 fnotice (stderr, "reading file: %s\n", filename);
 
-  obj_info = read_gcda_file (filename);
+  obj_info = read_gcda_file (xstrdup (filename));
   if (!obj_info)
 return 0;
 
-- 
2.34.1



[gcov v2 06/14] gcov-tool: Support file input from stdin

2022-04-25 Thread Sebastian Huber
gcc/

* gcov-io.cc (GCOV_MODE_STDIN): Define.
(gcov_position): For gcov-tool, return calculated position if file is
stdin.
(gcov_open):  For gcov-tool, use stdin if filename is NULL.
(gcov_close): For gcov-tool, do not close stdin.
(gcov_read_bytes): For gcov-tool, update position if file is stdin.
(gcov_sync): For gcov-tool, discard input if file is stdin.
---
 gcc/gcov-io.cc | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/gcc/gcov-io.cc b/gcc/gcov-io.cc
index fee3130f94a..7e1fb10b612 100644
--- a/gcc/gcov-io.cc
+++ b/gcc/gcov-io.cc
@@ -35,8 +35,13 @@ struct gcov_var
   int error;   /* < 0 overflow, > 0 disk error.  */
   int mode;/* < 0 writing, > 0 reading.  */
   int endian;  /* Swap endianness.  */
+#ifdef IN_GCOV_TOOL
+  gcov_position_t pos; /* File position for stdin support.  */
+#endif
 } gcov_var;
 
+#define GCOV_MODE_STDIN 2
+
 /* Save the current position in the gcov file.  */
 /* We need to expose this function when compiling for gcov-tool.  */
 #ifndef IN_GCOV_TOOL
@@ -45,6 +50,10 @@ static inline
 gcov_position_t
 gcov_position (void)
 {
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.mode == GCOV_MODE_STDIN)
+return gcov_var.pos;
+#endif
   return ftell (gcov_var.file);
 }
 
@@ -108,6 +117,16 @@ gcov_open (const char *name, int mode)
 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
   gcov_var.endian = 0;
 #endif
+#ifdef IN_GCOV_TOOL
+  gcov_var.pos = 0;
+  if (!name)
+{
+  gcov_nonruntime_assert (gcov_var.mode > 0);
+  gcov_var.file = stdin;
+  gcov_var.mode = GCOV_MODE_STDIN;
+  return 1;
+}
+#endif
 #if GCOV_LOCKED
   if (mode > 0)
 {
@@ -190,6 +209,11 @@ gcov_open (const char *name, int mode)
 GCOV_LINKAGE int
 gcov_close (void)
 {
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.file == stdin)
+gcov_var.file = 0;
+  else
+#endif
   if (gcov_var.file)
 {
   if (fclose (gcov_var.file))
@@ -363,6 +387,9 @@ gcov_read_bytes (void *buffer, unsigned count)
   if (read != 1)
 return NULL;
 
+#ifdef IN_GCOV_TOOL
+  gcov_var.pos += count;
+#endif
   return buffer;
 }
 
@@ -499,6 +526,17 @@ gcov_sync (gcov_position_t base, gcov_unsigned_t length)
 {
   gcov_nonruntime_assert (gcov_var.mode > 0);
   base += length;
+#ifdef IN_GCOV_TOOL
+  if (gcov_var.mode == GCOV_MODE_STDIN)
+{
+  while (gcov_var.pos < base)
+   {
+ ++gcov_var.pos;
+ (void)fgetc (gcov_var.file);
+   }
+  return;
+}
+#endif
   fseek (gcov_var.file, base, SEEK_SET);
 }
 #endif
-- 
2.34.1



[gcov v2 13/14] gcov: Use xstrerror()

2022-04-25 Thread Sebastian Huber
libgcc/

* libgcov-util.c (ftw_read_file): Improve notice using xstrerror().
(gcov_profile_merge_stream): Likewise.
---
 libgcc/libgcov-util.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgcc/libgcov-util.c b/libgcc/libgcov-util.c
index 2508e21..ba4670b3c0d 100644
--- a/libgcc/libgcov-util.c
+++ b/libgcc/libgcov-util.c
@@ -405,7 +405,7 @@ ftw_read_file (const char *filename,
 
   if (!gcov_open (filename, 1))
 {
-  fnotice (stderr, "%s:cannot open\n", filename);
+  fnotice (stderr, "%s:cannot open:%s\n", filename, xstrerror (errno));
   return 0;
 }
 
@@ -819,7 +819,7 @@ gcov_profile_merge_stream (const char *filename, int w1, 
int w2)
 
   if (!gcov_open (filename, 1))
 {
-  fnotice (stderr, "%s:cannot open\n", filename);
+  fnotice (stderr, "%s:cannot open:%s\n", filename, xstrerror (errno));
   return NULL;
 }
 
-- 
2.34.1



[gcov v2 05/14] gcov: Add __gcov_filename_to_gcfn()

2022-04-25 Thread Sebastian Huber
gcc/

* doc/invoke.texi (fprofile-info-section): Mention
__gcov_filename_to_gcfn().  Use "freestanding" to match with C11
standard language.  Fix minor example code issues.
* gcov-io.h (GCOV_FILENAME_MAGIC): Define and document.

gcc/testsuite/

* gcc.dg/gcov-info-to-gcda.c: Test __gcov_filename_to_gcfn().

libgcc/

* gcov.h (__gcov_info_to_gcda): Mention __gcov_filename_to_gcfn().
(__gcov_filename_to_gcfn): Declare and document.
* libgcov-driver.c (dump_string): New.
(__gcov_filename_to_gcfn): Likewise.
(__gcov_info_to_gcda): Adjust comment to match C11 standard language.
---
 gcc/doc/invoke.texi  | 26 -
 gcc/gcov-io.h| 24 ++--
 gcc/testsuite/gcc.dg/gcov-info-to-gcda.c | 36 +++-
 libgcc/gcov.h| 17 ++-
 libgcc/libgcov-driver.c  | 32 -
 5 files changed, 105 insertions(+), 30 deletions(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 07b440190c3..af5495e75c6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -15462,7 +15462,7 @@ profile information generated by 
@option{-fprofile-arcs} is placed in the
 specified section for each translation unit.  This option disables the profile
 information registration through a constructor and it disables the profile
 information processing through a destructor.  This option is not intended to be
-used in hosted environments such as GNU/Linux.  It targets free-standing
+used in hosted environments such as GNU/Linux.  It targets freestanding
 environments (for example embedded systems) with limited resources which do not
 support constructors/destructors or the C library file I/O.
 
@@ -15487,14 +15487,8 @@ for example like this:
 #include 
 #include 
 
-extern const struct gcov_info *__gcov_info_start[];
-extern const struct gcov_info *__gcov_info_end[];
-
-static void
-filename (const char *f, void *arg)
-@{
-  puts (f);
-@}
+extern const struct gcov_info *const __gcov_info_start[];
+extern const struct gcov_info *const __gcov_info_end[];
 
 static void
 dump (const void *d, unsigned n, void *arg)
@@ -15505,6 +15499,12 @@ dump (const void *d, unsigned n, void *arg)
 printf ("%02x", c[i]);
 @}
 
+static void
+filename (const char *f, void *arg)
+@{
+  __gcov_filename_to_gcfn (f, dump, arg );
+@}
+
 static void *
 allocate (unsigned length, void *arg)
 @{
@@ -15514,8 +15514,8 @@ allocate (unsigned length, void *arg)
 static void
 dump_gcov_info (void)
 @{
-  const struct gcov_info **info = __gcov_info_start;
-  const struct gcov_info **end = __gcov_info_end;
+  const struct gcov_info *const *info = __gcov_info_start;
+  const struct gcov_info *const *end = __gcov_info_end;
 
   /* Obfuscate variable to prevent compiler optimizations.  */
   __asm__ ("" : "+r" (info));
@@ -15530,9 +15530,9 @@ dump_gcov_info (void)
 @}
 
 int
-main()
+main (void)
 @{
-  dump_gcov_info();
+  dump_gcov_info ();
   return 0;
 @}
 @end smallexample
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 204ae0ccf7f..30947634d73 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -60,14 +60,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
If not, see
 
file : int32:magic int32:version int32:stamp record*
 
-   The magic ident is different for the notes and the data files.  The
-   magic ident is used to determine the endianness of the file, when
-   reading.  The version is the same for both files and is derived
-   from gcc's version number. The stamp value is used to synchronize
-   note and data files and to synchronize merging within a data
-   file. It need not be an absolute time stamp, merely a ticker that
-   increments fast enough and cycles slow enough to distinguish
-   different compile/run/compile cycles.
+   A filename header may be used to provide a filename for the data in
+   a stream of data to support gcov in freestanding environments.  This
+   header is used by the merge-stream subcommand of the gcov-tool.  The
+   format of the filename header is
+
+   filename-header : int32:magic int32:version string
+
+   The magic ident is different for the notes and the data files as
+   well as the filename header.  The magic ident is used to determine
+   the endianness of the file, when reading.  The version is the same
+   for both files and is derived from gcc's version number. The stamp
+   value is used to synchronize note and data files and to synchronize
+   merging within a data file. It need not be an absolute time stamp,
+   merely a ticker that increments fast enough and cycles slow enough
+   to distinguish different compile/run/compile cycles.
 
Although the ident and version are formally 32 bit numbers, they
are derived from 4 character ASCII strings.  The version number
@@ -228,6 +235,7 @@ typedef uint64_t gcov_type_unsigned;
 /* File magic. Must not be palindromes.  

Re: [PATCH] loongarch: ignore zero-size fields in calling convention

2022-04-25 Thread Lulu Cheng

This modification will cause the ABI to change, we are discussing solutions.

And we will give a conclusion at the latest tommorrow.

Thanks!

在 2022/4/25 下午1:57, Xi Ruoyao 写道:

Ping.

Normally we shouldn't ping a patch after only a few days, but we're
running out of time to catch GCC 12 milestone.  And once GCC 12 is
released the patch will become far more complicated for a psABI warning.

And please note that the ABI difference between GCC and G++ should be
considered a bug, and it has to be fixed anyway.  If you don't like the
idea of this patch, please develop another solution and apply it *before
GCC 12*.

On Wed, 2022-04-20 at 14:23 +0800, Xi Ruoyao via Gcc-patches wrote:

Currently, LoongArch ELF psABI is not clear on the handling of zero-
sized fields in aggregates arguments or return values [1].  The behavior
of GCC trunk is puzzling considering the following cases:

struct test1
{
   double a[0];
   float x;
};

struct test2
{
   float a[0];
   float x;
};

GCC trunk passes test1::x via GPR, but test2::x via FPR.  I believe no
rational Homo Sapiens can understand (or even expect) this.

And, to make things even worse, test1 behaves differently in C and C++.
GCC trunk passes test1::x via GPR, but G++ trunk passes test1::x via
FPR.

I've write a paragraph about current GCC behavior for the psABI [2], but
I think it's cleaner to just ignore all zero-sized fields in the ABI.
This will require only a two-line change in GCC (this patch), and an
one-line change in the ABI doc.

If there is not any better idea I'd like to see this reviewed and
applied ASAP.  If we finally have to apply this patch after GCC 12
release, we'll need to add a lot more boring code to emit a -Wpsabi
inform [3].  That will be an unnecessary burden for both us, and the
users using the compiler (as the compiler will spend CPU time only for
checking if a warning should be informed).

[1]:https://github.com/loongson/LoongArch-Documentation/issues/48
[2]:https://github.com/loongson/LoongArch-Documentation/pull/49
[3]:https://gcc.gnu.org/PR102024

gcc/

 * config/loongarch/loongarch.cc
 (loongarch_flatten_aggregate_field): Ignore empty fields for
 RECORD_TYPE.

gcc/testsuite/

 * gcc.target/loongarch/zero-size-field-pass.c: New test.
 * gcc.target/loongarch/zero-size-field-ret.c: New test.
---
  gcc/config/loongarch/loongarch.cc |  3 ++
  .../loongarch/zero-size-field-pass.c  | 30 +++
  .../loongarch/zero-size-field-ret.c   | 28 +
  3 files changed, 61 insertions(+)
  create mode 100644 gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c
  create mode 100644 gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c

diff --git a/gcc/config/loongarch/loongarch.cc 
b/gcc/config/loongarch/loongarch.cc
index f22150a60cc..57e4d9f82ce 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -326,6 +326,9 @@ loongarch_flatten_aggregate_field (const_tree type,
    for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
 if (TREE_CODE (f) == FIELD_DECL)
   {
+   if (DECL_SIZE (f) && integer_zerop (DECL_SIZE (f)))
+ continue;
+
     if (!TYPE_P (TREE_TYPE (f)))
   return -1;
  
diff --git a/gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c b/gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c

new file mode 100644
index 000..999dc913a71
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c
@@ -0,0 +1,30 @@
+/* Test that LoongArch backend ignores zero-sized fields of aggregates in
+   argument passing.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdouble-float -mabi=lp64d" } */
+/* { dg-final { scan-assembler "\\\$f1" } } */
+
+struct test
+{
+  int empty1[0];
+  double empty2[0];
+  int : 0;
+  float x;
+  long empty3[0];
+  long : 0;
+  float y;
+  unsigned : 0;
+  char empty4[0];
+};
+
+extern void callee (struct test);
+
+void
+caller (void)
+{
+  struct test test;
+  test.x = 114;
+  test.y = 514;
+  callee (test);
+}
diff --git a/gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c 
b/gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c
new file mode 100644
index 000..40137d97555
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c
@@ -0,0 +1,28 @@
+/* Test that LoongArch backend ignores zero-sized fields of aggregates in
+   returning.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdouble-float -mabi=lp64d" } */
+/* { dg-final { scan-assembler-not "\\\$r4" } } */
+
+struct test
+{
+  int empty1[0];
+  double empty2[0];
+  int : 0;
+  float x;
+  long empty3[0];
+  long : 0;
+  float y;
+  unsigned : 0;
+  char empty4[0];
+};
+
+extern struct test callee (void);
+
+float
+caller (void)
+{
+  struct test test = callee ();
+  return test.x + test.y;
+}




Re: [PATCH] PR target/89125

2022-04-25 Thread Richard Biener via Gcc-patches
On Sat, Apr 23, 2022 at 8:40 PM Steve Kargl via Gcc-patches
 wrote:
>
> ping.

I have tested the patch on x86_64-linux and pushed it.

Richard.

> On Fri, Apr 15, 2022 at 09:23:43AM -0700, Steve Kargl wrote:
> > Can someone, anyone, please commit the attach patch, which is
> > also attached to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89125
> > where one can read the audit trail.  The original patch was
> > submitted 2 years ago, and required manual intervention due to
> > the recent *.c to *.cc rename.
> >
> > Back story: When GCC is configured and built on non-glibc platforms,
> > it seems very little to no effort is made to enumerate the available
> > C99 libm functions.  It is all or nothing for C99 libm.  The patch
> > introduces a new function, used on only FreeBSD, to inform gcc that
> > it has C99 libm functions (minus a few which clearly GCC does not check
> > nor test).
> >
> > The patch introduces no regression on x86_64-*-freebsd while
> > allowing an additional 31 new passes.
> >
> > === gcc Summary ===
> > w/o patch  w patch
> > # of expected passes175405 175434
> > # of unexpected failures1081   1051
> > # of unexpected successes   20 20
> > # of expected failures  1459   1459
> > # of unresolved testcases   10 10
> > # of unsupported tests  3252   3252
> >
> > === g++ Summary ===
> > w/o patch  w patch
> > # of expected passes225338 225341
> > # of unexpected failures678676
> > # of expected failures  2071   2071
> > # of unresolved testcases   11 11
> > # of unsupported tests  10353  10353
> >
> > === gfortran Summary ===
> > w/o patch  w patch
> > # of expected passes65901  65901
> > # of unexpected failures12 12
> > # of expected failures  272272
> > # of unsupported tests  100100
> >
> >
> > 2022-04-15  Steven G. Kargl  
> >
> >   PR target/89125
> >   * config/freebsd.h: Define TARGET_LIBC_HAS_FUNCTION to be
> >   bsd_libc_has_function.
> >   * gcc/targhooks.cc(bsd_libc_has_function): New function.
> >   Expand the supported math functions to inclue C99 libm.
> >   * gcc/targhooks.h: Prototype for bsd_libc_has_function.
> >
> > --
> > Steve
>
> > diff --git a/gcc/config/freebsd.h b/gcc/config/freebsd.h
> > index 28ebcad88d4..d89ee7dfc97 100644
> > --- a/gcc/config/freebsd.h
> > +++ b/gcc/config/freebsd.h
> > @@ -55,7 +55,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #endif
> >
> >  #undef TARGET_LIBC_HAS_FUNCTION
> > -#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
> > +#define TARGET_LIBC_HAS_FUNCTION bsd_libc_has_function
> >
> >  /* Use --as-needed -lgcc_s for eh support.  */
> >  #ifdef HAVE_LD_AS_NEEDED
> > diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
> > index e22bc66a6c8..ff127763cf2 100644
> > --- a/gcc/targhooks.cc
> > +++ b/gcc/targhooks.cc
> > @@ -1843,6 +1843,20 @@ no_c99_libc_has_function (enum function_class 
> > fn_class ATTRIBUTE_UNUSED,
> >return false;
> >  }
> >
> > +/* Assume some c99 functions are present at the runtime including sincos.  
> > */
> > +bool
> > +bsd_libc_has_function (enum function_class fn_class,
> > +tree type ATTRIBUTE_UNUSED)
> > +{
> > +  if (fn_class == function_c94
> > +  || fn_class == function_c99_misc
> > +  || fn_class == function_sincos)
> > +return true;
> > +
> > +  return false;
> > +}
> > +
> > +
> >  tree
> >  default_builtin_tm_load_store (tree ARG_UNUSED (type))
> >  {
> > diff --git a/gcc/targhooks.h b/gcc/targhooks.h
> > index ecfa11287ef..ecce55ebe79 100644
> > --- a/gcc/targhooks.h
> > +++ b/gcc/targhooks.h
> > @@ -212,6 +212,7 @@ extern bool default_libc_has_function (enum 
> > function_class, tree);
> >  extern bool default_libc_has_fast_function (int fcode);
> >  extern bool no_c99_libc_has_function (enum function_class, tree);
> >  extern bool gnu_libc_has_function (enum function_class, tree);
> > +extern bool bsd_libc_has_function (enum function_class, tree);
> >
> >  extern tree default_builtin_tm_load_store (tree);
> >
>
>
> --
> Steve


Re: [PATCH] PR target/89125

2022-04-25 Thread Steve Kargl via Gcc-patches
On Mon, Apr 25, 2022 at 09:26:26AM +0200, Richard Biener wrote:
> On Sat, Apr 23, 2022 at 8:40 PM Steve Kargl via Gcc-patches
>  wrote:
> >
> > ping.
> 
> I have tested the patch on x86_64-linux and pushed it.
> 

Thanks.

-- 
Steve


Re: [PING] Re: [PATCH] tree-optimization/100810 - avoid undefs in IVOPT rewrites

2022-04-25 Thread Richard Biener via Gcc-patches
On Tue, Apr 19, 2022 at 1:06 PM Richard Biener via Gcc-patches
 wrote:
>
> On Fri, 1 Apr 2022, Richard Biener wrote:
>
> > The following attempts to avoid IVOPTs rewriting uses using
> > IV candidates that involve undefined behavior by using uninitialized
> > SSA names.  First we restrict the set of candidates we produce
> > for such IVs to the original ones and mark them as not important.
> > Second we try to only allow expressing uses with such IV if they
> > originally use them.  That is to avoid rewriting all such uses
> > in terms of other IVs.  Since cand->iv and use->iv seem to never
> > exactly match up we resort to comparing the IV bases.
> >
> > The approach ends up similar to the one posted by Roger at
> > https://gcc.gnu.org/pipermail/gcc-patches/2021-August/578441.html
> > but it marks IV candidates rather than use groups and the cases
> > we allow in determine_group_iv_cost_generic are slightly different.
> >
> > Bootstrapped and tested on x86_64-unknown-linux-gnu.
> >
> > OK for trunk?
>
> Ping?  Any opinions?

I have now pushed the patch.

Richard.

> Thanks,
> Richard.
>
> > Thanks,
> > Richard.
> >
> > 2022-01-04  Richard Biener  
> >
> >   PR tree-optimization/100810
> >   * tree-ssa-loop-ivopts.cc (struct iv_cand): Add involves_undefs flag.
> >   (find_ssa_undef): New function.
> >   (add_candidate_1): Avoid adding derived candidates with
> >   undefined SSA names and mark the original ones.
> >   (determine_group_iv_cost_generic): Reject rewriting
> >   uses with a different IV when that involves undefined SSA names.
> >
> >   * gcc.dg/torture/pr100810.c: New testcase.
> > ---
> >  gcc/testsuite/gcc.dg/torture/pr100810.c | 34 +
> >  gcc/tree-ssa-loop-ivopts.cc | 31 ++
> >  2 files changed, 65 insertions(+)
> >  create mode 100644 gcc/testsuite/gcc.dg/torture/pr100810.c
> >
> > diff --git a/gcc/testsuite/gcc.dg/torture/pr100810.c 
> > b/gcc/testsuite/gcc.dg/torture/pr100810.c
> > new file mode 100644
> > index 000..63566f530f7
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/torture/pr100810.c
> > @@ -0,0 +1,34 @@
> > +/* { dg-do run } */
> > +
> > +int a, b = 1, c = 1, e, f = 1, g, h, j;
> > +volatile int d;
> > +static void k()
> > +{
> > +  int i;
> > +  h = b;
> > +  if (c && a >= 0) {
> > +  while (a) {
> > +   i++;
> > +   h--;
> > +  }
> > +  if (g)
> > + for (h = 0; h < 2; h++)
> > +   ;
> > +  if (!b)
> > + i &&d;
> > +  }
> > +}
> > +static void l()
> > +{
> > +  for (; j < 1; j++)
> > +if (!e && c && f)
> > +  k();
> > +}
> > +int main()
> > +{
> > +  if (f)
> > +l();
> > +  if (h != 1)
> > +__builtin_abort();
> > +  return 0;
> > +}
> > diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
> > index 935d2d4d8f3..b0305c494cd 100644
> > --- a/gcc/tree-ssa-loop-ivopts.cc
> > +++ b/gcc/tree-ssa-loop-ivopts.cc
> > @@ -452,6 +452,7 @@ struct iv_cand
> >unsigned id;   /* The number of the candidate.  */
> >bool important;/* Whether this is an "important" candidate, i.e. such
> >  that it should be considered by all uses.  */
> > +  bool involves_undefs; /* Whether the IV involves undefined values.  */
> >ENUM_BITFIELD(iv_position) pos : 8;/* Where it is computed.  */
> >gimple *incremented_at;/* For original biv, the statement where it is
> >  incremented.  */
> > @@ -3068,6 +3069,19 @@ get_loop_invariant_expr (struct ivopts_data *data, 
> > tree inv_expr)
> >return *slot;
> >  }
> >
> > +/* Find the first undefined SSA name in *TP.  */
> > +
> > +static tree
> > +find_ssa_undef (tree *tp, int *walk_subtrees, void *)
> > +{
> > +  if (TREE_CODE (*tp) == SSA_NAME
> > +  && ssa_undefined_value_p (*tp, false))
> > +return *tp;
> > +  if (!EXPR_P (*tp))
> > +*walk_subtrees = 0;
> > +  return NULL;
> > +}
> > +
> >  /* Adds a candidate BASE + STEP * i.  Important field is set to IMPORTANT 
> > and
> > position to POS.  If USE is not NULL, the candidate is set as related to
> > it.  If both BASE and STEP are NULL, we add a pseudocandidate for the
> > @@ -3095,6 +3109,17 @@ add_candidate_1 (struct ivopts_data *data, tree 
> > base, tree step, bool important,
> >if (flag_keep_gc_roots_live && POINTER_TYPE_P (TREE_TYPE (base)))
> >  return NULL;
> >
> > +  /* If BASE contains undefined SSA names make sure we only record
> > + the original IV.  */
> > +  bool involves_undefs = false;
> > +  if (walk_tree (&base, find_ssa_undef, NULL, NULL))
> > +{
> > +  if (pos != IP_ORIGINAL)
> > + return NULL;
> > +  important = false;
> > +  involves_undefs = true;
> > +}
> > +
> >/* For non-original variables, make sure their values are computed in a 
> > type
> >   that does not invoke undefined behavior on overflows (since in 
> > general,
> >   we cannot prove that these induction 

[PATCH] tree-optimization/105368 - avoid overflow in powi_cost

2022-04-25 Thread Richard Biener via Gcc-patches
The following avoids undefined signed overflow when computing
the absolute of the exponent in powi_cost.

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

2022-04-25  Richard Biener  

PR tree-optimization/105368
* tree-ssa-math-opts.cc (powi_cost): Use absu_hwi.
---
 gcc/tree-ssa-math-opts.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index 102b7a2cc99..7555793948e 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -1462,7 +1462,7 @@ powi_cost (HOST_WIDE_INT n)
 return 0;
 
   /* Ignore the reciprocal when calculating the cost.  */
-  val = (n < 0) ? -n : n;
+  val = absu_hwi (n);
 
   /* Initialize the exponent cache.  */
   memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
-- 
2.34.1


[PATCH] middle-end/104492 - avoid all equality compare dangling pointer diags

2022-04-25 Thread Richard Biener via Gcc-patches
The following extends the equality compare dangling pointer diagnostics
suppression for uses following free or realloc to also cover those
following invalidation of auto variables via CLOBBERs.  That avoids
diagnosing idioms like

  return std::find(std::begin(candidates), std::end(candidates), s)
   != std::end(candidates);

for auto candidates which are prone to forwarding of the final
comparison across the storage invalidation as then seen by the
late run access warning pass.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

OK for trunk?

Thanks,
Richard.

2022-04-25  Richard Biener  

PR middle-end/104492
* gimple-ssa-warn-access.cc
(pass_waccess::warn_invalid_pointer): Exclude equality compare
diagnostics for all kind of invalidations.

* c-c++-common/Wdangling-pointer.c: Adjust for changed
suppression.
* c-c++-common/Wdangling-pointer-2.c: Likewise.
---
 gcc/gimple-ssa-warn-access.cc| 14 +-
 gcc/testsuite/c-c++-common/Wdangling-pointer-2.c |  4 ++--
 gcc/testsuite/c-c++-common/Wdangling-pointer.c   |  4 ++--
 3 files changed, 9 insertions(+), 13 deletions(-)

diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc
index 879dbcc1e52..6c404f18db7 100644
--- a/gcc/gimple-ssa-warn-access.cc
+++ b/gcc/gimple-ssa-warn-access.cc
@@ -3896,13 +3896,13 @@ pass_waccess::warn_invalid_pointer (tree ref, gimple 
*use_stmt,
return;
 }
 
+  if ((equality && warn_use_after_free < 3)
+  || (maybe && warn_use_after_free < 2)
+  || warning_suppressed_p (use_stmt, OPT_Wuse_after_free))
+return;
+
   if (is_gimple_call (inval_stmt))
 {
-  if ((equality && warn_use_after_free < 3)
- || (maybe && warn_use_after_free < 2)
- || warning_suppressed_p (use_stmt, OPT_Wuse_after_free))
-   return;
-
   const tree inval_decl = gimple_call_fndecl (inval_stmt);
 
   if ((ref && warning_at (use_loc, OPT_Wuse_after_free,
@@ -3923,10 +3923,6 @@ pass_waccess::warn_invalid_pointer (tree ref, gimple 
*use_stmt,
   return;
 }
 
-  if ((maybe && warn_dangling_pointer < 2)
-  || warning_suppressed_p (use_stmt, OPT_Wdangling_pointer_))
-return;
-
   if (DECL_NAME (var))
 {
   if ((ref
diff --git a/gcc/testsuite/c-c++-common/Wdangling-pointer-2.c 
b/gcc/testsuite/c-c++-common/Wdangling-pointer-2.c
index 20f11b227d6..11c939cb086 100644
--- a/gcc/testsuite/c-c++-common/Wdangling-pointer-2.c
+++ b/gcc/testsuite/c-c++-common/Wdangling-pointer-2.c
@@ -356,7 +356,7 @@ NOIPA void warn_cond_if_else (int i)
 }
   else
{
- int b[] = { 3, 4 };  // { dg-message "'b' declared" "pr??" { 
xfail *-*-* } }
+ int b[] = { 3, 4 };  // { dg-message "'b' declared" }
  sink (b);
  p = b;
}
@@ -365,7 +365,7 @@ NOIPA void warn_cond_if_else (int i)
  because after the first diagnostic the code suppresses subsequent
  ones for the same use.  This needs to be fixed.  */
   sink (p);   // { dg-warning "dangling pointer 'p' to 'a' may 
be used" }
-  // { dg-warning "dangling pointer 'p' to 'b' may 
be used" "pr??" { xfail *-*-* } .-1 }
+  // { dg-warning "dangling pointer 'p' to 'b' may 
be used" "" { target *-*-* } .-1 }
 }
 
 
diff --git a/gcc/testsuite/c-c++-common/Wdangling-pointer.c 
b/gcc/testsuite/c-c++-common/Wdangling-pointer.c
index 0a18c3c8249..09e4036a4dd 100644
--- a/gcc/testsuite/c-c++-common/Wdangling-pointer.c
+++ b/gcc/testsuite/c-c++-common/Wdangling-pointer.c
@@ -370,7 +370,7 @@ void warn_cond_if_else (int i)
 }
   else
{
- int b[] = { 3, 4 };  // { dg-message "'b' declared" "note" { xfail 
*-*-* } }
+ int b[] = { 3, 4 };  // { dg-message "'b' declared" "note" }
  sink (b);
  p = b;
}
@@ -379,7 +379,7 @@ void warn_cond_if_else (int i)
  because after the first diagnostic the code suppresses subsequent
  ones for the same use.  This needs to be fixed.  */
   sink (p);   // { dg-warning "dangling pointer 'p' to 'a' may 
be used" }
-  // { dg-warning "dangling pointer 'p' to 'b' may 
be used" "pr??" { xfail *-*-* } .-1 }
+  // { dg-warning "dangling pointer 'p' to 'b' may 
be used" "" { target *-*-* } .-1 }
 }
 
 
-- 
2.34.1


[x86 PATCH] PR target/92578: Peephole2s to tweak cmove register allocation.

2022-04-25 Thread Roger Sayle

This patch addresses a (minor) missed-optimization regression revealed
by Richard Biener's example/variant in comment #1 of PR target/92578.

int foo(int moves, int movecnt, int komove) {
int newcnt = movecnt;
if (moves == komove)
newcnt -= 2;
return newcnt;
}

Comparing code generation on godbolt.org shows an interesting evolution
over time, as changes in register allocation affect the cmove sequence.

GCC 4.1.2 (4 instructions, suboptimal mov after cmov).
leal-2(%rsi), %eax
cmpl%edx, %edi
cmove   %eax, %esi
movl%esi, %eax

GCC 4.4-4.7 (3 instructions, optimal)
leal-2(%rsi), %eax
cmpl%edx, %edi
cmovne  %esi, %eax

GCC 5-7 (4 instructions, suboptimal mov before cmov)
leal-2(%rsi), %ecx
movl%esi, %eax
cmpl%edx, %edi
cmove   %ecx, %eax

GCC 8 (4 instructions, suboptimal mov before cmov, reordered)
movl%esi, %eax
leal-2(%rsi), %ecx
cmpl%edx, %edi
cmove   %ecx, %eax

GCC 9-trunk (5 instructions, two suboptimal movs before cmov)
movl%edx, %ecx
movl%esi, %eax
leal-2(%rsi), %edx
cmpl%ecx, %edi
cmove   %edx, %eax

The challenge is that x86's two operand conditional moves, that require
the destination to be one of the (register) sources, are tricky for reload,
whose heuristics unify pseudos early (greedily?).  In this case, we have
the equivalent of "pseudo1 = cond ? pseudo2 : expression", and we'd like
to see "pseudo1 = expression; pseudo1 = cond ? pseudo1 : pseudo2", but
alas reload (currently and quite reasonably) prefers to place pseudo1 and
pseudo2 in the same hard register if possible.  Hence the solution is to
fixup/tweak the register allocation during peephole2, as previously with
https://gcc.gnu.org/pipermail/gcc-patches/2021-July/575998.html

Instead of a single peephole2 to catch just the current idiom (last above),
I've added the four peephole2s that would catch each of the (historical)
suboptimal variants above and transform them into the ideal 3 insn form.
Instrumenting the compiler shows, for example, that the (earliest) movl
after cmov triggers over 50 times during stage2 of a GCC bootstrap.


This patch has been tested on x86_64-pc-linux-gnu with make bootstrap
and make -k check, both with and without --target_board=unix{-m32}, with
no new failures.  Ok for mainline?  Or if this regression isn't serious
enough for stage4 (or these patterns considered too risky), for stage1
when it reopens?  I suspect the poor interaction between cmove usage
and register allocation is one source of confusion when comparing code
generation with vs. without cmove (the other major source of confusion
being that well-predicted branches are free, but that prediction-quality
is poorly predictable).


2022-04-25  Roger Sayle  

gcc/ChangeLog
PR target/92578
* config/i386/i386.md (peephole2): Eliminate register-to-register
moves by inverting the condition of a conditional move.

gcc/testsuite/ChangeLog
PR target/92578
* gcc.target/i386/pr92758.c: New test case.


Thanks in advance,
Roger
--

diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index c74edd1..db6034a 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -20751,6 +20751,158 @@
   operands[9] = replace_rtx (operands[6], operands[0], operands[1], true);
 })
 
+;; Eliminate a reg-reg mov by inverting the condition of a cmov (#3).
+;; cmov r0,r1; mov r1,r0 -> cmov r1,r0
+(define_peephole2
+ [(set (match_operand:SWI248 0 "general_reg_operand")
+   (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
+[(reg FLAGS_REG) (const_int 0)])
+   (match_operand:SWI248 2 "general_reg_operand")
+   (match_operand:SWI248 3 "general_reg_operand")))
+  (set (match_operand:SWI248 4 "general_reg_operand")
+   (match_dup 0))]
+  "TARGET_CMOVE
+   && ((REGNO (operands[0]) == REGNO (operands[2])
+   && REGNO (operands[3]) == REGNO (operands[4]))
+   || (REGNO (operands[0]) == REGNO (operands[3])
+  && REGNO (operands[2]) == REGNO (operands[4])))
+   && peep2_reg_dead_p (2, operands[0])"
+  [(set (match_dup 4) (if_then_else:SWI248 (match_dup 1)
+  (match_dup 2)
+  (match_dup 3)))])
+
+;; Eliminate a reg-reg mov by inverting the condition of a cmov (#4).
+;; mov r1,r0; mov x,r2; cmp; cmov r2,r0 -> mov x,r0; cmp; cmov r1,r0
+(define_peephole2
+ [(set (match_operand:SWI248 0 "general_reg_operand")
+   (match_operand:SWI248 1 "general_reg_operand"))
+  (set (match_operand:SWI248 2 "general_reg_operand")
+   (match_operand:SWI248 3))
+  (set (match_operand 4 "flags_reg_operand") (match_operand 5))
+  (set (match_dup 0)
+   (if_then_else:SWI248 (match_operator 6 "ix86_comparison_operator"
+[(match_du

[pushed] testsuite: add additional option to force DSE execution [PR103662]

2022-04-25 Thread Mikael Morin
I have just pushed the attached fix for two UNRESOLVED checks at 
-O0 that I hadn’t seen.From 6cc26f3037a18b9a958b4ac2a1363149a7fccd39 Mon Sep 17 00:00:00 2001
From: Mikael Morin 
Date: Mon, 25 Apr 2022 13:14:20 +0200
Subject: [pushed] =?UTF-8?q?testsuite:=C2=A0add=20additional=20option=20to?=
 =?UTF-8?q?=20force=20DSE=20execution=20[PR103662]?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This fixes a dump tree match check that is UNRESOLVED with the -O0
optimization option, as the optimization pass corresponding to the
dump file is not run at -O0, and the dump is not generated.

	PR fortran/103662

gcc/testsuite/ChangeLog:

	* gfortran.dg/unlimited_polymorphic_3.f03: Force execution of
	the DSE optimization pass.
---
 gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03 b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03
index 780d68cdd87..4104de6ac68 100644
--- a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03
+++ b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03
@@ -1,5 +1,5 @@
 ! { dg-do run }
-! { dg-additional-options "-fdump-tree-dse-details" }
+! { dg-additional-options "-ftree-dse -fdump-tree-dse-details" }
 !
 ! Check that pointer assignments allowed by F2003:C717
 ! work and check null initialization of CLASS(*) pointers.
-- 
2.35.1



Re: [pushed] testsuite: add additional option to force DSE execution [PR103662]

2022-04-25 Thread Jakub Jelinek via Gcc-patches
On Mon, Apr 25, 2022 at 01:38:25PM +0200, Mikael Morin wrote:
> I have just pushed the attached fix for two UNRESOLVED checks at -O0 that I
> hadn’t seen.

I don't like forcing of DSE in -O0 compilation, wouldn't it be better
to just not check the dse dump at -O0 like in the following patch?

Even better would be to check that the z._data = stores are both present
in *.optimized dump, but that doesn't really work at -O2 or above because
we inline the functions and optimize it completely away (both the stores
and corresponding reads).

The first hunk is needed so that __OPTIMIZE__ effective target works in
Fortran testsuite, otherwise one gets a pedantic error and __OPTIMIZE__
is considered not to match at all.

2022-04-25  Jakub Jelinek  

PR fortran/103662
* lib/target-supports.exp (check_effective_target___OPTIMIZE__): Add
a var definition to avoid pedwarn about empty translation unit.
* gfortran.dg/unlimited_polymorphic_3.f03: Remove -ftree-dse from
dg-additional-options, guard scan-tree-dump-not directives on
__OPTIMIZE__ target.

--- gcc/testsuite/lib/target-supports.exp.jj2022-04-22 13:36:56.150960826 
+0200
+++ gcc/testsuite/lib/target-supports.exp   2022-04-25 14:06:21.620537483 
+0200
@@ -11770,6 +11770,7 @@ proc check_effective_target___OPTIMIZE__
#ifndef __OPTIMIZE__
# error nein
#endif
+   int optimize;
 } [current_compiler_flags]]
 }
 
--- gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03.jj2022-04-25 
13:54:38.320309119 +0200
+++ gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03   2022-04-25 
14:04:01.346486431 +0200
@@ -1,5 +1,5 @@
 ! { dg-do run }
-! { dg-additional-options "-ftree-dse -fdump-tree-dse-details" }
+! { dg-additional-options "-fdump-tree-dse-details" }
 !
 ! Check that pointer assignments allowed by F2003:C717
 ! work and check null initialization of CLASS(*) pointers.
@@ -71,5 +71,5 @@ end subroutine foo_sq
 ! We used to produce multiple independant types for the unlimited polymorphic
 ! descriptors (types for class(*)) which caused stores to them to be seen as
 ! useless.
-! { dg-final { scan-tree-dump-not "Deleted dead store: z._data = &w" "dse1" } }
-! { dg-final { scan-tree-dump-not "Deleted dead store: z._data = &x" "dse1" } }
+! { dg-final { scan-tree-dump-not "Deleted dead store: z._data = &w" "dse1" { 
target __OPTIMIZE__ } } }
+! { dg-final { scan-tree-dump-not "Deleted dead store: z._data = &x" "dse1" { 
target __OPTIMIZE__ } } }


Jakub



Re: [PATCH] libstdc++: Add pretty printer for std::initializer_list

2022-04-25 Thread Jonathan Wakely via Gcc-patches
On Sun, 24 Apr 2022 at 16:51, Philipp Fent via Libstdc++
 wrote:
>
> Re-using the std::span printer, this now shows the contents of the
> initializer list instead of the pointer and length members.

Nice, I've pushed this to trunk. Thanks!


>
> Signed-off-by: Philipp Fent 
> ---
>  libstdc++-v3/python/libstdcxx/v6/printers.py  | 23 +--
>  .../libstdc++-prettyprinters/cxx11.cc |  6 +
>  2 files changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py 
> b/libstdc++-v3/python/libstdcxx/v6/printers.py
> index 6d8b765f2..48798b6c1 100644
> --- a/libstdc++-v3/python/libstdcxx/v6/printers.py
> +++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
> @@ -1657,7 +1657,7 @@ class StdRegexStatePrinter:
>  class StdSpanPrinter:
>  "Print a std::span"
>
> -class _iterator(Iterator):
> +class iterator(Iterator):
>  def __init__(self, begin, size):
>  self.count = 0
>  self.begin = begin
> @@ -1686,7 +1686,24 @@ class StdSpanPrinter:
>  return '%s of length %d' % (self.typename, self.size)
>
>  def children(self):
> -return self._iterator(self.val['_M_ptr'], self.size)
> +return self.iterator(self.val['_M_ptr'], self.size)
> +
> +def display_hint(self):
> +return 'array'
> +
> +class StdInitializerListPrinter:
> +"Print a std::initializer_list"
> +
> +def __init__(self, typename, val):
> +self.typename = typename
> +self.val = val
> +self.size = val['_M_len']
> +
> +def to_string(self):
> +return '%s of length %d' % (self.typename, self.size)
> +
> +def children(self):
> +return StdSpanPrinter.iterator(self.val['_M_array'], self.size)
>
>  def display_hint(self):
>  return 'array'
> @@ -2156,6 +2173,8 @@ def build_libstdcxx_dictionary ():
>  libstdcxx_printer.add_version('std::tr1::', 'unordered_multiset',
>Tr1UnorderedSetPrinter)
>
> +libstdcxx_printer.add_version('std::', 'initializer_list', 
> StdInitializerListPrinter)
> +
>  # std::regex components
>  libstdcxx_printer.add_version('std::__detail::', '_State',
>StdRegexStatePrinter)
> diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc 
> b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
> index 4262ca88b..621d13bd0 100644
> --- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
> +++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
> @@ -25,6 +25,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include "../util/testsuite_allocator.h" // NullablePointer
>
>  typedef std::tuple ExTuple;
> @@ -191,6 +192,11 @@ main()
>std::error_code ecfut0 = std::make_error_code(std::future_errc{});
>// { dg-final { note-test ecfut0 {std::error_code = {"future": 0}} } }
>
> +  std::initializer_list emptyIl = {};
> +  // { dg-final { note-test emptyIl {std::initializer_list of length 0} } }
> +  std::initializer_list il = {3, 4};
> +  // { dg-final { note-test il {std::initializer_list of length 2 = {3, 4}} 
> } }
> +
>placeholder(""); // Mark SPOT
>use(efl);
>use(fl);
> --
> 2.36.0
>



Re: [pushed] testsuite: add additional option to force DSE execution [PR103662]

2022-04-25 Thread Mikael Morin

Le 25/04/2022 à 14:12, Jakub Jelinek a écrit :

On Mon, Apr 25, 2022 at 01:38:25PM +0200, Mikael Morin wrote:

I have just pushed the attached fix for two UNRESOLVED checks at -O0 that I
hadn’t seen.


I don't like forcing of DSE in -O0 compilation, wouldn't it be better
to just not check the dse dump at -O0 like in the following patch?

Certainly better.  I actually looked for something alike already 
existing before trying to write a conditional in the dg-final code and 
finally deciding to go the easy way.



Even better would be to check that the z._data = stores are both present
in *.optimized dump, but that doesn't really work at -O2 or above because
we inline the functions and optimize it completely away (both the stores
and corresponding reads).


Yes, and global optimization is already checked by test execution anyway.


The first hunk is needed so that __OPTIMIZE__ effective target works in
Fortran testsuite, otherwise one gets a pedantic error and __OPTIMIZE__
is considered not to match at all.


Maybe worth putting as code comment.

OK from my side, thanks.



[OG11-committed][stage1-patch] Fortran: Fix finalization resolution with deep copy (was: [Patch][Stage 1] Fortran/OpenMP: Support mapping of DT with allocatable components)

2022-04-25 Thread Tobias Burnus

Found another issue – applied to OG11 as attached. Will include it in
the mainline patch once Stage1.

(However, I intent to split the original patch (+ follow ups) into
smaller pieces for mainline incorporation.)

Tobias

On 02.03.22 23:20, Tobias Burnus wrote:

Some testing found an issue in class.cc (in the new _callback
function) – updated patch attached (long version + interdiff).

Tobias

(PS: OG11 - original patch was committed as
https://gcc.gnu.org/g:98961d3a0ccb02d7d54d2d4dd07cca75473d685a ;
follow-up version to be committed in a moment)

On 01.03.22 16:34, Tobias Burnus wrote:

Hi all,

this patch adds support for mapping something like
  type t
type(t2), allocatable :: a, b(:)
integer, allocatable :: c, c(:)
  end type t
  type(t), allocatable :: var, var2(:,:)

  !$omp target enter data map(var, var)

which does a deep walk of the components at runtime.

On the ME side, the static addr/size/kinds arrays are
replaced (only if need) by allocatable arrays – which
are then filled by trans-openmp.c.

All deep-mapping handling happens via the hooks called
late in omp-low.c such that removing mappings or implicitly
added one are handled.

In principle, there is also code to handle polymorphic
variables (new callback function in vtable + two on-the-fly
generated functions to be used for walking the vtable).

Issues: None known, but I am sure with experimenting,
more can be found - especially with arrays/array sections
and polymorphism, I expect issues. I did find some on the
way and fixed them - but (see PR refs in testcase -7.f90),
I also found unrelated bugs, which I did not fix ;-)

Comments? OK for mainline (GCC 13)?

Tobias

PS: I will commit this patch to OG11 for further testing.
PPS: Previously discussed at
https://gcc.gnu.org/pipermail/gcc-patches/2021-December/586237.html

-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
commit c6daf2090d48bc794c6809a5d98e8d9a583346bd
Author: Tobias Burnus 
Date:   Mon Apr 25 15:12:01 2022 +0200

Fortran: Fix finalization resolution with deep copy

Follow-up patch to
"Fortran/OpenMP: Support mapping of DT with allocatable components"
https://gcc.gnu.org/pipermail/gcc-patches/2022-March/591144.html

gcc/fortran/ChangeLog:

* resolve.c (gfc_resolve_finalizers): Also resolve allocatable comps.

gcc/testsuite/ChangeLog:

* gfortran.dg/finalize_38.f90: New test.
---
 gcc/fortran/resolve.c |  11 ++-
 gcc/testsuite/gfortran.dg/finalize_38.f90 | 135 ++
 2 files changed, 143 insertions(+), 3 deletions(-)

diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 59faa4c119d..10c89de0eaa 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -13578,11 +13578,16 @@ gfc_resolve_finalizers (gfc_symbol* derived, bool *finalizable)
   if (parent)
 gfc_resolve_finalizers (parent, finalizable);
 
-  /* Ensure that derived-type components have a their finalizers resolved.  */
+  /* Ensure that derived-type components have a their finalizers resolved;
+ handle allocatables but avoid issues with (in)direct allocatable types. */
   bool has_final = derived->f2k_derived && derived->f2k_derived->finalizers;
   for (c = derived->components; c; c = c->next)
-if (c->ts.type == BT_DERIVED
-	&& !c->attr.pointer && !c->attr.proc_pointer && !c->attr.allocatable)
+if (c->ts.type == BT_DERIVED && !c->attr.pointer && !c->attr.proc_pointer
+	&& (!c->attr.allocatable
+	|| (c->ts.u.derived != derived
+		&& c->ts.u.derived->f2k_derived
+		&& c->ts.u.derived->f2k_derived->finalizers
+		&& !c->ts.u.derived->f2k_derived->finalizers->proc_tree)))
   {
 	bool has_final2 = false;
 	if (!gfc_resolve_finalizers (c->ts.u.derived, &has_final2))
diff --git a/gcc/testsuite/gfortran.dg/finalize_38.f90 b/gcc/testsuite/gfortran.dg/finalize_38.f90
new file mode 100644
index 000..442e1753311
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/finalize_38.f90
@@ -0,0 +1,135 @@
+! { dg-do compile }
+!
+! Check finalization
+!
+module Real_2D__Form
+
+  implicit none
+  private
+  
+  integer, parameter :: &
+KDR = kind ( 1.0d0 ), &
+KDI = kind ( 1 ), &
+KDL = kind ( .true. )
+
+  type, public :: Real_2D_Form
+real ( KDR ), dimension ( :, : ), allocatable :: &
+  Value
+  contains
+procedure, private, pass :: &
+  Initialize_R_2D
+procedure, private, pass :: &
+  Initialize_R_2D_FromValue
+procedure, private, pass :: &
+  Initialize_R_2D_Copy
+generic :: &
+  Initialize &
+=> Initialize_R_2D, Initialize_R_2D_FromValue, Initialize_R_2D_Copy
+final :: &
+  Finalize_R_2D
+  end type Real_2D_Form
+  
+  type, public :: Real_2D_2D_Form
+type ( Real_2D_Form ), dimension ( :

Re: [PATCH] tree-optimization/105276 - Retain existing range knowledge when prefilling statements.

2022-04-25 Thread Andrew MacLeod via Gcc-patches

On 4/22/22 01:51, Richard Biener wrote:

On Thu, Apr 21, 2022 at 5:59 PM Andrew MacLeod  wrote:

When range_of_stmt was adjusted to avoid large recursion depth, I added
code to precalculate the dependencies without recursion.

This patch adjusted that pre-fill code to intersect the current known
range with the newly calculated one before setting the global range.
this Is what range_of_stmt does, and was missed.

Its running thru testing now, but I expect no issues with either
bootstrap nor testsuite regressions.

Do you want me to check this when testing is complete, or hold off?

OK if testing looks good.

Richard.


passed everything fine.  committed.

Andrew.




Re: [PATCH] c++: partial ordering with dependent NTTP type [PR105289]

2022-04-25 Thread Jason Merrill via Gcc-patches

On 4/22/22 15:27, Patrick Palka wrote:

On Fri, 22 Apr 2022, Patrick Palka wrote:


Here ever since r11-6483-ge2e2f3f2c9400f we're rejecting and crashing
(respectively) on two testcases that we used to accept in C++17 mode.
Both testcases declare partial specializations for which the primary
template contains an NTTP with dependent type, but the correctness of
these partial specializations is unclear according to PR86193.

This patch restores the previous C++17 behavior for such partial
specializations by restricting the r11-6483 change to just ordinary
deduction as opposed to deduction for sake of partial ordering.


Note that if we're okay with rejecting such partial specializations even
in C++17 mode (and thus deeming PR105289 to be ICE-on-invalid instead of
ICE-on-valid), then the fix for the reported ICE is just:

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index dde62ee052d..6d65f6ad3cf 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -24299,7 +24299,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
  /* Now check whether the type of this parameter is still
 dependent, and give up if so.  */
  ++processing_template_decl;
- tparm = tsubst (tparm, targs, tf_none, NULL_TREE);
+ tparm = tsubst (TREE_TYPE (parm), targs, tf_none, NULL_TREE);
  --processing_template_decl;
  if (uses_template_parms (tparm))
return unify_success (explain_p);

i.e. we need to substitute into the original NTTP type, not into the
already substituted NTTP type.


I'm happy rejecting partial-specialization12.C on that basis.  11 is 
interesting because int is a non-dependent type; it might be worth 
adding that testcase to the DR455 discussion.


I think let's go with this patch and bump down the "partial 
specialization isn't more specialized" diagnostic from permerror to 
on-by-default pedwarn.



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

PR c++/105289
PR c++/86193

gcc/cp/ChangeLog:

* pt.cc (unify) : Restrict the
r11-6483 change to just ordinary deduction for function
templates.  When substituting into the NTTP type the second
time, use the original type not the substituted type.  Remove
now unnecessary level check.

gcc/testsuite/ChangeLog:

* g++.dg/template/partial5.C: Revert r11-6483 change.
* g++.dg/template/partial-specialization11.C: New test.
* g++.dg/template/partial-specialization12.C: New test.
---
  gcc/cp/pt.cc  | 25 ---
  .../template/partial-specialization11.C   | 10 
  .../template/partial-specialization12.C   | 12 +
  gcc/testsuite/g++.dg/template/partial5.C  |  2 +-
  4 files changed, 39 insertions(+), 10 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization11.C
  create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization12.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index dde62ee052d..52bd130b7e7 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -24287,8 +24287,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
  /* We haven't deduced the type of this parameter yet.  */
  if (cxx_dialect >= cxx17
  /* We deduce from array bounds in try_array_deduction.  */
- && !(strict & UNIFY_ALLOW_INTEGER)
- && TEMPLATE_PARM_LEVEL (parm) <= TMPL_ARGS_DEPTH (targs))
+ && !(strict & UNIFY_ALLOW_INTEGER))
{
  /* Deduce it from the non-type argument.  As above, ignore
 top-level quals here too.  */
@@ -24296,13 +24295,21 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
  RECUR_AND_CHECK_FAILURE (tparms, targs,
   tparm, atype,
   UNIFY_ALLOW_NONE, explain_p);
- /* Now check whether the type of this parameter is still
-dependent, and give up if so.  */
- ++processing_template_decl;
- tparm = tsubst (tparm, targs, tf_none, NULL_TREE);
- --processing_template_decl;
- if (uses_template_parms (tparm))
-   return unify_success (explain_p);
+ if (!processing_template_decl
+ && TPARMS_PRIMARY_TEMPLATE (tparms)
+ && DECL_FUNCTION_TEMPLATE_P (TPARMS_PRIMARY_TEMPLATE
+  (tparms)))
+   {
+ /* If the NTTP's type uses still-undeduced template
+parameters, then don't unify it now.  This gives
+type_unification_real a chance to retry deduction
+with default template arguments substituted in.  */
+ ++processing_template_decl;
+ tparm = tsubst (TREE_TYPE (parm), targs, tf_

Re: [PATCH] c++: __builtin_shufflevector with value-dep expr [PR105353]

2022-04-25 Thread Jason Merrill via Gcc-patches

On 4/22/22 19:57, Marek Polacek wrote:

Here we issue an error from c_build_shufflevector while parsing a template
because it got a TEMPLATE_PARM_INDEX, but this function expects INTEGER_CSTs
(except the first two arguments).  It checks if any of the arguments are
type-dependent, if so, we leave the processing for later, but it should
also check value-dependency for the 3rd+ arguments, so as to avoid the
problem above.

This is not a regression -- __builtin_shufflevector was introduced in
GCC 12, but it looks safe enough.

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


OK.


PR c++/105353

gcc/cp/ChangeLog:

* typeck.cc (build_x_shufflevector): Use
instantiation_dependent_expression_p except for the first two
arguments.

gcc/testsuite/ChangeLog:

* g++.dg/ext/builtin-shufflevector-3.C: New test.
---
  gcc/cp/typeck.cc  |  4 +++-
  .../g++.dg/ext/builtin-shufflevector-3.C  | 23 +++
  2 files changed, 26 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/ext/builtin-shufflevector-3.C

diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 26a7cb4b50d..0da6f2485d0 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -6315,7 +6315,9 @@ build_x_shufflevector (location_t loc, vec 
*args,
if (processing_template_decl)
  {
for (unsigned i = 0; i < args->length (); ++i)
-   if (type_dependent_expression_p ((*args)[i]))
+   if (i <= 1
+   ? type_dependent_expression_p ((*args)[i])
+   : instantiation_dependent_expression_p ((*args)[i]))
  {
tree exp = build_min_nt_call_vec (NULL, args);
CALL_EXPR_IFN (exp) = IFN_SHUFFLEVECTOR;
diff --git a/gcc/testsuite/g++.dg/ext/builtin-shufflevector-3.C 
b/gcc/testsuite/g++.dg/ext/builtin-shufflevector-3.C
new file mode 100644
index 000..0f3cbbee563
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/builtin-shufflevector-3.C
@@ -0,0 +1,23 @@
+// PR c++/105353
+// { dg-do compile { target c++17 } }
+// { dg-additional-options "-Wno-psabi" }
+
+typedef unsigned char Simd128U8VectT __attribute__((__vector_size__(16)));
+
+template
+static inline Simd128U8VectT ShufFunc(Simd128U8VectT vect) noexcept {
+if constexpr(unsigned(ShuffleIndex) >= 16)
+return Simd128U8VectT { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
};
+else if constexpr(ShuffleIndex == 0)
+return vect;
+else
+return __builtin_shufflevector(vect, vect, ShuffleIndex, ShuffleIndex 
+ 1,
+ShuffleIndex + 2, ShuffleIndex + 3, ShuffleIndex + 4, ShuffleIndex 
+ 5,
+ShuffleIndex + 6, ShuffleIndex + 7, ShuffleIndex + 8, ShuffleIndex 
+ 9,
+ShuffleIndex + 10, ShuffleIndex + 11, ShuffleIndex + 12, 
ShuffleIndex + 13,
+ShuffleIndex + 14, ShuffleIndex + 15);
+}
+
+auto func1(Simd128U8VectT vect) noexcept {
+return ShufFunc<5>(vect);
+}

base-commit: 7c21556daf385fe9ece37319f574776dd7d8ab1c




Re: [PATCH] c++: crash with requires-expr and -Wsequence-point [PR105304]

2022-04-25 Thread Jason Merrill via Gcc-patches

On 4/22/22 14:36, Patrick Palka wrote:

Here we're crashing from verify_sequence_points for this requires-expr
condition because it contains a templated CAST_EXPR with empty operand,
and verify_tree doesn't ignore this empty operand only because the
manual tail recursion that it perform for unary expression trees skips
the NULL test.

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


OK.


PR c++/105304

gcc/c-family/ChangeLog:

* c-common.cc (verify_tree) [restart]: Move up to before the
NULL test.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/concepts-requires30.C: New test.
---
  gcc/c-family/c-common.cc |  2 +-
  gcc/testsuite/g++.dg/cpp2a/concepts-requires30.C | 10 ++
  2 files changed, 11 insertions(+), 1 deletion(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-requires30.C

diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc
index 70f55f3a346..bb0544eeaea 100644
--- a/gcc/c-family/c-common.cc
+++ b/gcc/c-family/c-common.cc
@@ -2009,12 +2009,12 @@ verify_tree (tree x, struct tlist **pbefore_sp, struct 
tlist **pno_sp,
enum tree_code code;
enum tree_code_class cl;
  
+ restart:

/* X may be NULL if it is the operand of an empty statement expression
   ({ }).  */
if (x == NULL)
  return;
  
- restart:

code = TREE_CODE (x);
cl = TREE_CODE_CLASS (code);
  
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-requires30.C b/gcc/testsuite/g++.dg/cpp2a/concepts-requires30.C

new file mode 100644
index 000..f500af3f616
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-requires30.C
@@ -0,0 +1,10 @@
+// PR c++/105304
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-Wall -Wsequence-point" }
+
+struct A { };
+
+int main() {
+  if (requires { A(); })
+;
+}




[RFA] gcc.misc-tests/outputs.exp: Use link test to check for -gsplit-dwarf support

2022-04-25 Thread Joel Brobecker via Gcc-patches
Hello,

We have noticed that, when running the GCC testsuite on AArch64
RTEMS 6, we have about 150 tests failing due to a link failure.
When investigating, we found that all the tests were failing
due to the use of -gsplit-dwarf.

On this platform, using -gsplit-dwarf currently causes an error
during the link:

| /[...]/ld: a.out section `.unexpected_sections' will not fit
|in region `UNEXPECTED_SECTIONS'
| /[...]/ld: region `UNEXPECTED_SECTIONS' overflowed by 56 bytes

The error is a bit cryptic, but the source of the issue is that
the linker does not currently support the sections generated
by -gsplit-dwarf (.debug_gnu_pubnames, .debug_gnu_pubtypes).
This means that the -gsplit-dwarf feature itself really isn't
supported on this platform, at least for the moment.

This commit enhances the -gsplit-dwarf support check to be
a compile-and-link check, rather than just a compile check.
This allows it to properly detect that this feature isn't
supported on platforms such as AArch64 RTEMS where the compilation
works, but not the link.

Tested on aarch64-rtems, where a little over 150 tests are now
passing, instead of failing, as well as on x86_64-linux, where
the results are identical, and where the .log file was also manually
inspected to make sure that the use of the -gsplit-dwarf option
was preserved.

gcc/testsuite/ChangeLog:

* gcc.misc-tests/outputs.exp: Make the -gsplit-dwarf test
a compile-and-link test rather than a compile-only test.

OK to push on master?

Thank you,
-- 
Joel

---
 gcc/testsuite/gcc.misc-tests/outputs.exp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.misc-tests/outputs.exp 
b/gcc/testsuite/gcc.misc-tests/outputs.exp
index bc1fbe4eb7f..afae735e92d 100644
--- a/gcc/testsuite/gcc.misc-tests/outputs.exp
+++ b/gcc/testsuite/gcc.misc-tests/outputs.exp
@@ -36,8 +36,8 @@ gcc_parallel_test_enable 0
 # having to deal with .dSYM directories, as long as -gsplit-dwarf is
 # not supported on platforms that use .dSYM directories.
 set gsplit_dwarf "-g -gsplit-dwarf"
-if ![check_no_compiler_messages gsplitdwarf object {
-void foo (void) { }
+if ![check_no_compiler_messages gsplitdwarf executable {
+int main (void) { return 0; }
 } "$gsplit_dwarf"] {
 set gsplit_dwarf ""
 }
-- 
2.32.0



[committed] libstdc++: Add deduction guides for std::packaged_task [PR105375]

2022-04-25 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8 --

This change was LWG 3117.

The test is copied from 20_util/function/cons/deduction.cc

libstdc++-v3/ChangeLog:

PR libstdc++/105375
* include/std/future (packaged_task): Add deduction guides.
* testsuite/30_threads/packaged_task/cons/deduction.cc: New test.
---
 libstdc++-v3/include/std/future   | 11 +++
 .../packaged_task/cons/deduction.cc   | 85 +++
 2 files changed, 96 insertions(+)
 create mode 100644 
libstdc++-v3/testsuite/30_threads/packaged_task/cons/deduction.cc

diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future
index cba40dc0883..a9268cade91 100644
--- a/libstdc++-v3/include/std/future
+++ b/libstdc++-v3/include/std/future
@@ -1622,6 +1622,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 };
 
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 3117. Missing packaged_task deduction guides
+#if __cpp_deduction_guides >= 201606
+  template
+packaged_task(_Res(*)(_ArgTypes...)) -> packaged_task<_Res(_ArgTypes...)>;
+
+  template::type>
+packaged_task(_Fun) -> packaged_task<_Signature>;
+#endif
+
   /// swap
   template
 inline void
diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/deduction.cc 
b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/deduction.cc
new file mode 100644
index 000..0eb69763ab9
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/deduction.cc
@@ -0,0 +1,85 @@
+// // Copyright (C) 2017-2022 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// .
+
+// { dg-do compile { target c++17 } }
+
+#include 
+
+template struct require_same;
+template struct require_same { using type = void; };
+
+template
+  typename require_same::type
+  check_type(U&) { }
+
+void f0v();
+void f0vn() noexcept;
+int f0i();
+int f0in() noexcept;
+long f1l(int&);
+long f1ln(double*) noexcept;
+
+void
+test01()
+{
+  std::packaged_task task1{f0v};
+  check_type>(task1);
+
+  std::packaged_task task2{f0vn};
+  check_type>(task2);
+
+  std::packaged_task task3{f0i};
+  check_type>(task3);
+
+  std::packaged_task task4{f0in};
+  check_type>(task4);
+
+  std::packaged_task task5{f1l};
+  check_type>(task5);
+
+  std::packaged_task task6{f1ln};
+  check_type>(task6);
+
+  std::packaged_task task5a{std::move(task5)};
+  check_type>(task5a);
+
+  std::packaged_task task6a{std::move(task6)};
+  check_type>(task6a);
+}
+
+struct X {
+  int operator()(const short&, void*);
+};
+
+struct Y {
+  void operator()(int) const & noexcept;
+};
+
+void
+test02()
+{
+  X x;
+  std::packaged_task task1{x};
+  check_type>(task1);
+
+  Y y;
+  std::packaged_task task2{y};
+  check_type>(task2);
+
+  std::packaged_task task3{[&x](float) -> X& { return x; }};
+  check_type>(task3);
+}
-- 
2.34.1



[committed] libstdc++: Implement constexpr std::unique_ptr for C++23 (P2273R3)

2022-04-25 Thread Jonathan Wakely via Gcc-patches
Tested powerpc64le-linux, pushed to trunk.

-- >8 --

libstdc++-v3/ChangeLog:

* include/bits/ptr_traits.h (__cpp_lib_constexpr_memory): Define
conditionally.
* include/bits/unique_ptr.h (__cpp_lib_constexpr_memory):
Define for C++23.
(default_delete, default_delete, __uniq_ptr_impl)
(unique_ptr, unique_ptr): Add constexpr to all member
functions.
* include/std/version (__cpp_lib_constexpr_memory): Define new
value for C++23.
* testsuite/20_util/unique_ptr/assign/constexpr.cc: New test.
* testsuite/20_util/unique_ptr/comparison/constexpr.cc: New test.
* testsuite/20_util/unique_ptr/cons/constexpr_c++20.cc: New test.
* testsuite/20_util/unique_ptr/creation/constexpr.cc: New test.
* testsuite/20_util/unique_ptr/modifiers/constexpr.cc: New test.
* testsuite/20_util/unique_ptr/specialized_algorithms/constexpr.cc:
New test.
---
 libstdc++-v3/include/bits/ptr_traits.h|   5 +-
 libstdc++-v3/include/bits/unique_ptr.h| 124 +++---
 libstdc++-v3/include/std/version  |   4 +
 .../20_util/unique_ptr/assign/constexpr.cc|  48 +++
 .../unique_ptr/comparison/constexpr.cc|  73 +++
 .../unique_ptr/cons/constexpr_c++20.cc|  85 
 .../20_util/unique_ptr/creation/constexpr.cc  |  34 +
 .../20_util/unique_ptr/modifiers/constexpr.cc |  68 ++
 .../specialized_algorithms/constexpr.cc   |  46 +++
 9 files changed, 466 insertions(+), 21 deletions(-)
 create mode 100644 
libstdc++-v3/testsuite/20_util/unique_ptr/assign/constexpr.cc
 create mode 100644 
libstdc++-v3/testsuite/20_util/unique_ptr/comparison/constexpr.cc
 create mode 100644 
libstdc++-v3/testsuite/20_util/unique_ptr/cons/constexpr_c++20.cc
 create mode 100644 
libstdc++-v3/testsuite/20_util/unique_ptr/creation/constexpr.cc
 create mode 100644 
libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/constexpr.cc
 create mode 100644 
libstdc++-v3/testsuite/20_util/unique_ptr/specialized_algorithms/constexpr.cc

diff --git a/libstdc++-v3/include/bits/ptr_traits.h 
b/libstdc++-v3/include/bits/ptr_traits.h
index c85e6d44ded..047efa5cf28 100644
--- a/libstdc++-v3/include/bits/ptr_traits.h
+++ b/libstdc++-v3/include/bits/ptr_traits.h
@@ -36,7 +36,10 @@
 
 #if __cplusplus > 201703L
 #include 
-#define __cpp_lib_constexpr_memory 201811L
+# ifndef __cpp_lib_constexpr_memory
+// Defined to a newer value in bits/unique_ptr.h for C++23
+#  define __cpp_lib_constexpr_memory 201811L
+# endif
 namespace __gnu_debug { struct _Safe_iterator_base; }
 #endif
 
diff --git a/libstdc++-v3/include/bits/unique_ptr.h 
b/libstdc++-v3/include/bits/unique_ptr.h
index 8f4430f61f5..ad60fada59b 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -41,6 +41,14 @@
 # include 
 #endif
 
+#if __cplusplus > 202002L && __cpp_constexpr_dynamic_alloc
+# if __cpp_lib_constexpr_memory < 202202L
+// Defined with older value in bits/ptr_traits.h for C++20
+#  undef __cpp_lib_constexpr_memory
+#  define __cpp_lib_constexpr_memory 202202L
+# endif
+#endif
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -72,9 +80,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
   template>>
+   _GLIBCXX23_CONSTEXPR
 default_delete(const default_delete<_Up>&) noexcept { }
 
   /// Calls `delete __ptr`
+  _GLIBCXX23_CONSTEXPR
   void
   operator()(_Tp* __ptr) const
   {
@@ -108,10 +118,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
   template>>
+   _GLIBCXX23_CONSTEXPR
 default_delete(const default_delete<_Up[]>&) noexcept { }
 
   /// Calls `delete[] __ptr`
   template
+   _GLIBCXX23_CONSTEXPR
typename enable_if::value>::type
operator()(_Up* __ptr) const
{
@@ -152,16 +164,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 " or an lvalue reference type" );
 
   __uniq_ptr_impl() = default;
+  _GLIBCXX23_CONSTEXPR
   __uniq_ptr_impl(pointer __p) : _M_t() { _M_ptr() = __p; }
 
   template
-  __uniq_ptr_impl(pointer __p, _Del&& __d)
+   _GLIBCXX23_CONSTEXPR
+   __uniq_ptr_impl(pointer __p, _Del&& __d)
: _M_t(__p, std::forward<_Del>(__d)) { }
 
+  _GLIBCXX23_CONSTEXPR
   __uniq_ptr_impl(__uniq_ptr_impl&& __u) noexcept
   : _M_t(std::move(__u._M_t))
   { __u._M_ptr() = nullptr; }
 
+  _GLIBCXX23_CONSTEXPR
   __uniq_ptr_impl& operator=(__uniq_ptr_impl&& __u) noexcept
   {
reset(__u.release());
@@ -169,11 +185,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
   }
 
+  _GLIBCXX23_CONSTEXPR
   pointer&   _M_ptr() noexcept { return std::get<0>(_M_t); }
+  _GLIBCXX23_CONSTEXPR
   pointer_M_ptr() const noexcept { return std::get<0>(_M_t); }
+  _GLIBCXX23_CONSTEXPR
   _Dp&   _M_deleter() noexcept { return std::get<1>(_M_t); 

[wwwdocs] Document support for C++23 constexpr std::unique_ptr

2022-04-25 Thread Jonathan Wakely via Gcc-patches
Pushed to wwwdocs.

---
 htdocs/gcc-12/changes.html | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/htdocs/gcc-12/changes.html b/htdocs/gcc-12/changes.html
index 4f904bfd..78b7b05f 100644
--- a/htdocs/gcc-12/changes.html
+++ b/htdocs/gcc-12/changes.html
@@ -467,11 +467,13 @@ function Multiply (S1, S2 : Sign) return Sign is
   Monadic operations for std::optional.
   std::move_only_function
   
-  std::invoke_r
   std::basic_string::resize_and_overwrite
+  std::unique_ptr
+  can be used in constexpr functions.
   
   (not built by default, requires linking to an extra library).
   
+  std::invoke_r
   constexpr std::type_info::operator==
   
 
-- 
2.34.1



Re: [PATCH] c++: partial ordering with dependent NTTP type [PR105289]

2022-04-25 Thread Patrick Palka via Gcc-patches
On Mon, 25 Apr 2022, Jason Merrill wrote:

> On 4/22/22 15:27, Patrick Palka wrote:
> > On Fri, 22 Apr 2022, Patrick Palka wrote:
> > 
> > > Here ever since r11-6483-ge2e2f3f2c9400f we're rejecting and crashing
> > > (respectively) on two testcases that we used to accept in C++17 mode.
> > > Both testcases declare partial specializations for which the primary
> > > template contains an NTTP with dependent type, but the correctness of
> > > these partial specializations is unclear according to PR86193.
> > > 
> > > This patch restores the previous C++17 behavior for such partial
> > > specializations by restricting the r11-6483 change to just ordinary
> > > deduction as opposed to deduction for sake of partial ordering.
> > 
> > Note that if we're okay with rejecting such partial specializations even
> > in C++17 mode (and thus deeming PR105289 to be ICE-on-invalid instead of
> > ICE-on-valid), then the fix for the reported ICE is just:
> > 
> > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> > index dde62ee052d..6d65f6ad3cf 100644
> > --- a/gcc/cp/pt.cc
> > +++ b/gcc/cp/pt.cc
> > @@ -24299,7 +24299,7 @@ unify (tree tparms, tree targs, tree parm, tree arg,
> > int strict,
> >   /* Now check whether the type of this parameter is still
> >  dependent, and give up if so.  */
> >   ++processing_template_decl;
> > - tparm = tsubst (tparm, targs, tf_none, NULL_TREE);
> > + tparm = tsubst (TREE_TYPE (parm), targs, tf_none, NULL_TREE);
> >   --processing_template_decl;
> >   if (uses_template_parms (tparm))
> > return unify_success (explain_p);
> > 
> > i.e. we need to substitute into the original NTTP type, not into the
> > already substituted NTTP type.
> 
> I'm happy rejecting partial-specialization12.C on that basis.  11 is
> interesting because int is a non-dependent type; it might be worth adding that
> testcase to the DR455 discussion.
> 
> I think let's go with this patch and bump down the "partial specialization
> isn't more specialized" diagnostic from permerror to on-by-default pedwarn.

Ah, sounds good to me. like so?

-- >8 --

Subject: [PATCH] c++: partial ordering with dependent NTTP type [PR105289]

Here ever since r11-6483-ge2e2f3f2c9400f we're rejecting and crashing
on (respectively) two testcases that we used to accept in C++17 mode
since r8-1437-g3da557ec145823.  Both testcases declare a partial
specialization for which the primary template contains an NTTP with
dependent type, but the validity of these partial specializations is
unclear and is the subject of PR86193 / CWG 455.

This patch just fixes the reported ICE in the second testcase.  The bug
was that when checking whether the type of an NTTP uses still-undeduced
parameters, we'd substitute into the previously substituted NTTP type
instead of into the original NTTP type.

And given that the treatment of such partial specializations seems to
be underspecified in the standard, this patch downgrades the general
"not more specialized" diagnostic from a permerror to a pedwarn.

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

PR c++/105289
PR c++/86193

gcc/cp/ChangeLog:

* pt.cc (process_partial_specialization): Downgrade "partial
specialization isn't more specialized" diagnostic from permerror
to an on-by-default pedwarn.
(unify) : When substituting into the
NTTP type a second time, use the original type not the
substituted type.

gcc/testsuite/ChangeLog:

* g++.dg/template/partial-specialization11.C: New test.
* g++.dg/template/partial-specialization12.C: New test.
---
 gcc/cp/pt.cc|  7 ---
 .../g++.dg/template/partial-specialization11.C  | 11 +++
 .../g++.dg/template/partial-specialization12.C  | 13 +
 3 files changed, 28 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization11.C
 create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization12.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index dde62ee052d..7dd9e6788f4 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -5227,8 +5227,9 @@ process_partial_specialization (tree decl)
   && !get_partial_spec_bindings (maintmpl, maintmpl, specargs))
 {
   auto_diagnostic_group d;
-  if (permerror (input_location, "partial specialization %qD is not "
-"more specialized than", decl))
+  if (pedwarn (input_location, 0,
+  "partial specialization %qD is not more specialized than",
+  decl))
inform (DECL_SOURCE_LOCATION (maintmpl), "primary template %qD",
maintmpl);
 }
@@ -24299,7 +24300,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
  /* Now check whether the type of this parameter is still
 dependent, and give up if so.  */
  ++proc

Re: [pushed] testsuite: add additional option to force DSE execution [PR103662]

2022-04-25 Thread Bernhard Reutner-Fischer via Gcc-patches
On 25 April 2022 14:12:30 CEST, Jakub Jelinek via Fortran  
wrote:
>On Mon, Apr 25, 2022 at 01:38:25PM +0200, Mikael Morin wrote:
>> I have just pushed the attached fix for two UNRESOLVED checks at -O0 that I
>> hadn’t seen.
>
>I don't like forcing of DSE in -O0 compilation, wouldn't it be better
>to just not check the dse dump at -O0 like in the following patch?

As Mikael already said, that's preferable indeed.

>
>Even better would be to check that the z._data = stores are both present
>in *.optimized dump, but that doesn't really work at -O2 or above because
>we inline the functions and optimize it completely away (both the stores
>and corresponding reads).
>
>The first hunk is needed so that __OPTIMIZE__ effective target works in
>Fortran testsuite, otherwise one gets a pedantic error and __OPTIMIZE__
>is considered not to match at all.
>
>2022-04-25  Jakub Jelinek  
>
>   PR fortran/103662
>   * lib/target-supports.exp (check_effective_target___OPTIMIZE__): Add
>   a var definition to avoid pedwarn about empty translation unit.
>   * gfortran.dg/unlimited_polymorphic_3.f03: Remove -ftree-dse from
>   dg-additional-options, guard scan-tree-dump-not directives on
>   __OPTIMIZE__ target.
>
>--- gcc/testsuite/lib/target-supports.exp.jj   2022-04-22 13:36:56.150960826 
>+0200
>+++ gcc/testsuite/lib/target-supports.exp  2022-04-25 14:06:21.620537483 
>+0200
>@@ -11770,6 +11770,7 @@ proc check_effective_target___OPTIMIZE__
>   #ifndef __OPTIMIZE__
>   # error nein

Hmz. I _think_ that was /me and reading it again now, we should should not 
bluntly say nein but more something like
unwilling to ignore __OPTIMIZE__, dude

or anything more descriptive and universally understandably I assume.

>   #endif
>+  int optimize;

a plain ; won't cut it. int dummy, maybe though. There is probably a lot more 
of these, aren't there?

thanks,

> } [current_compiler_flags]]
> }
> 
>--- gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03.jj   2022-04-25 
>13:54:38.320309119 +0200
>+++ gcc/testsuite/gfortran.dg/unlimited_polymorphic_3.f03  2022-04-25 
>14:04:01.346486431 +0200
>@@ -1,5 +1,5 @@
> ! { dg-do run }
>-! { dg-additional-options "-ftree-dse -fdump-tree-dse-details" }
>+! { dg-additional-options "-fdump-tree-dse-details" }
> !
> ! Check that pointer assignments allowed by F2003:C717
> ! work and check null initialization of CLASS(*) pointers.
>@@ -71,5 +71,5 @@ end subroutine foo_sq
> ! We used to produce multiple independant types for the unlimited polymorphic
> ! descriptors (types for class(*)) which caused stores to them to be seen as
> ! useless.
>-! { dg-final { scan-tree-dump-not "Deleted dead store: z._data = &w" "dse1" } 
>}
>-! { dg-final { scan-tree-dump-not "Deleted dead store: z._data = &x" "dse1" } 
>}
>+! { dg-final { scan-tree-dump-not "Deleted dead store: z._data = &w" "dse1" { 
>target __OPTIMIZE__ } } }
>+! { dg-final { scan-tree-dump-not "Deleted dead store: z._data = &x" "dse1" { 
>target __OPTIMIZE__ } } }
>
>
>   Jakub
>



Re: [PATCH] fortran: Fix up gfc_trans_oacc_construct [PR104717]

2022-04-25 Thread Thomas Schwinge
Hi!

On 2022-04-20T19:06:17+0200, Jakub Jelinek  wrote:
> So that move_sese_region_to_fn works properly, OpenMP/OpenACC constructs
> for which that function is invoked need an extra artificial BIND_EXPR
> around their body so that we move all variables of the bodies.
>
> The C/C++ FEs do that both for OpenMP constructs like OMP_PARALLEL, OMP_TASK
> or OMP_TARGET and for OpenACC constructs that behave similarly to
> OMP_TARGET, but the Fortran FE only does that for OpenMP constructs.
>
> The following patch does that for OpenACC constructs too.
> This fixes ICE on the attached testcase.

ACK, thanks.

I do see that over the past years, there have been a number of similar
fixes been applied for other OMP constructs -- maybe that interface
should generally be made more obvious and fool-proof?

> Unfortunately, it also regresses
> FAIL: gfortran.dg/goacc/privatization-1-compute-loop.f90   -O  (test for 
> excess errors)
> FAIL: libgomp.oacc-fortran/privatized-ref-2.f90 -DACC_DEVICE_TYPE_host=1 
> -DACC_MEM_SHARED=1 -foffload=disable  -O0  (test for excess errors)
> FAIL: libgomp.oacc-fortran/privatized-ref-2.f90 -DACC_DEVICE_TYPE_host=1 
> -DACC_MEM_SHARED=1 -foffload=disable  -O1  (test for excess errors)
> FAIL: libgomp.oacc-fortran/privatized-ref-2.f90 -DACC_DEVICE_TYPE_host=1 
> -DACC_MEM_SHARED=1 -foffload=disable  -O2  (test for excess errors)
> FAIL: libgomp.oacc-fortran/privatized-ref-2.f90 -DACC_DEVICE_TYPE_host=1 
> -DACC_MEM_SHARED=1 -foffload=disable  -O3 -fomit-frame-pointer -funroll-loops 
> -fpeel-loops -ftracer -finline-functions  (test for excess errors)
> FAIL: libgomp.oacc-fortran/privatized-ref-2.f90 -DACC_DEVICE_TYPE_host=1 
> -DACC_MEM_SHARED=1 -foffload=disable  -O3 -g  (test for excess errors)
> FAIL: libgomp.oacc-fortran/privatized-ref-2.f90 -DACC_DEVICE_TYPE_host=1 
> -DACC_MEM_SHARED=1 -foffload=disable  -Os  (test for excess errors)
> Those emits emit tons of various messages and now there are some extra ones,

I've fixed these up.

> the previous as well as new ones are mostly on artificial variables created
> by the compiler, so I wonder if we should emit those at all.

Yes, I did wonder about that, too.  (This affects a lot of test cases.)

> Anyway, here it is the patch, appart from those regressions passed
> bootstrap/regtested on powerpc64le-linux.
>
> 2022-04-20  Jakub Jelinek  
>
>   PR fortran/104717
>   * trans-openmp.cc (gfc_trans_oacc_construct): Wrap construct body
>   in an extra BIND_EXPR.
>
>   * gfortran.dg/goacc/pr104717.f90: New test.
>
> --- gcc/fortran/trans-openmp.cc.jj2022-04-06 09:59:32.729654664 +0200
> +++ gcc/fortran/trans-openmp.cc   2022-04-20 12:48:19.773402677 +0200
> @@ -,7 +,9 @@ gfc_trans_oacc_construct (gfc_code *code
>gfc_start_block (&block);
>oacc_clauses = gfc_trans_omp_clauses (&block, code->ext.omp_clauses,
>   code->loc, false, true);
> +  pushlevel ();
>stmt = gfc_trans_omp_code (code->block->next, true);
> +  stmt = build3_v (BIND_EXPR, NULL, stmt, poplevel (1, 0));
>stmt = build2_loc (gfc_get_location (&code->loc), construct_code,
>void_type_node, stmt, oacc_clauses);
>gfc_add_expr_to_block (&block, stmt);
> --- gcc/testsuite/gfortran.dg/goacc/pr104717.f90.jj   2022-04-20 
> 12:53:54.002748265 +0200
> +++ gcc/testsuite/gfortran.dg/goacc/pr104717.f90  2022-04-20 
> 12:53:12.811321862 +0200
> @@ -0,0 +1,22 @@
> +! PR fortran/104717
> +! { dg-do compile }
> +! { dg-options "-O1 -fopenacc -fstack-arrays" }

As the ICE was "during IPA pass: pta", I've added an explicit '-fipa-pta'
here.

> +
> +program main
> +  implicit none (type, external)
> +  integer :: j
> +  integer, allocatable :: A(:)
> +
> +  A = [(3*j, j=1, 10)]
> +  call foo (A, size(A))
> +  deallocate (A)
> +contains
> +  subroutine foo (array, nn)
> +integer :: i, nn
> +integer :: array(nn)
> +
> +!$acc parallel copyout(array)
> +array = [(-i, i = 1, nn)]
> +!$acc end parallel
> +  end subroutine foo
> +end

Pushed to master branch commit b2202431910e30d8505c94d1cb9341cac7080d10
"fortran: Fix up gfc_trans_oacc_construct [PR104717]", see attached.


Grüße
 Thomas


-
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955
>From b2202431910e30d8505c94d1cb9341cac7080d10 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek 
Date: Wed, 20 Apr 2022 19:06:17 +0200
Subject: [PATCH] fortran: Fix up gfc_trans_oacc_construct [PR104717]

So that move_sese_region_to_fn works properly, OpenMP/OpenACC constructs
for which that function is invoked need an extra artificial BIND_EXPR
around their body so that we move all variables of the bodies.

The C/C++ FEs do that both for OpenMP constructs like OMP_PARALLEL, OMP_TASK
or OMP_TARGET and for OpenACC constructs that behave

Re: [PATCH, testsuite]: Cleanup dumps

2022-04-25 Thread Bernhard Reutner-Fischer via Gcc-patches
On Fri, 29 May 2015 10:44:02 +0200
Bernhard Reutner-Fischer  wrote:

> On 29 May 2015 at 10:21, Bernhard Reutner-Fischer  
> wrote:
> > On 31 January 2015 at 22:10, Bernhard Reutner-Fischer
> >  wrote:  
> >> On January 31, 2015 9:17:57 PM GMT+01:00, Mike Stump 
> >>  wrote:  
> 
> >>>If you want to wait until stage 1, that’s fine too.  
> >>
> >> I'd only want that to go in in stage 1.  
> >
> > I have applied this now as r223858.
> > Please CC me on fallout.  
> 
> 
> To recap:
> 
> The idea is to automatically delete dump-files in the testsuite
> instead of annotating alot of testcases in their dg-final.
> 
> To quote sourcebuild.texi, "Clean up generated test files":
> --- 8< ---
> Usually the test-framework removes files that were generated during
> testing. If a testcase, for example, uses any dumping mechanism to
> inspect a passes dump file, the testsuite recognized the dumping option
> passed to the tool and schedules a final cleanup to remove these files.
> --- 8< ---
> 
> The following TCL procs were deleted from the test framework and
> CANNOT be used anymore in dg-final:
> - cleanup-ipa-dump
> - cleanup-rtl-dump
> - cleanup-tree-dump
> - cleanup-saved-temps
> 
> These dump-files are now automatically deleted in the testsuite, via a
> schedule-cleanups in some basic .exp helpers.
> 
> Just delete any // dg-final { cleanup-see-above-list }
> from your new testcases.
> 
> 
> The .plan is to gradually do the same for the remaining dumps like
> stack etc. See remaining parts in sourcebuild.texi and this comment in
> schedule-cleanups:
> +# TODO
> +# -fprofile-generate -> cleanup-coverage-files()
> +# -fstack-usage -> cleanup-stack-usage()
> 
> Mike, just so i do not forget:
> 
> I have retained the cleanup-saved-temps proc for now since it's used in 
> lto.exp.
> I want to rename it later on to prevent people from using it in their
> dg-final since this is now done automatically.
> 
> cheers,

Hi!
Some time later now. We're in gcc-12 stage 4.
The automatic cleanup handling was quite successful i think. I.e. folks
did not have to waste any noteworthy time on manual cleanup hunting ever
since then AFAIK.

So..
Iff you find leftovers in the testsuite in gcc-12 or 11 onwards from
running tests, then please let us know.

And if you are willing to delve into removing the tcl leftovers from
way back, or if you have time to apply some more TLC to the cleanup
handling itself or if you see opportunity to cleanup the cleanup
handling itself, then please do so. IIRC there are a few bits left that
one could handle automatically, if deemed generally useful and if you
have spare time.

PS:
$ git grep dg-final gcc/testsuite/ | egrep -v "(ChangeLog| scan-)" | sed -e 
's/.*dg-final //' -e 's/\s*{\s*//' -e 's/}/ /g' | awk '{print $1}' | sort | 
uniq -c | sort -nr -k1
   2697 check-function-bodies
486 gdb-test
 62 run-gcov
 34 scan-assembler-times
 25 cleanup-ada-spec
 23 simulate-thread
 22 object-size
...
PS:
gcc/testsuite/lib/scanasm.exp: object-size is under-used.
We should have way more size tests.
And we should have size tests that aim to regain the regressions that
came with the SSA merge ;)

thanks,


Re: [PATCH] c++: partial ordering with dependent NTTP type [PR105289]

2022-04-25 Thread Jason Merrill via Gcc-patches

On 4/25/22 14:10, Patrick Palka wrote:

On Mon, 25 Apr 2022, Jason Merrill wrote:


On 4/22/22 15:27, Patrick Palka wrote:

On Fri, 22 Apr 2022, Patrick Palka wrote:


Here ever since r11-6483-ge2e2f3f2c9400f we're rejecting and crashing
(respectively) on two testcases that we used to accept in C++17 mode.
Both testcases declare partial specializations for which the primary
template contains an NTTP with dependent type, but the correctness of
these partial specializations is unclear according to PR86193.

This patch restores the previous C++17 behavior for such partial
specializations by restricting the r11-6483 change to just ordinary
deduction as opposed to deduction for sake of partial ordering.


Note that if we're okay with rejecting such partial specializations even
in C++17 mode (and thus deeming PR105289 to be ICE-on-invalid instead of
ICE-on-valid), then the fix for the reported ICE is just:

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index dde62ee052d..6d65f6ad3cf 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -24299,7 +24299,7 @@ unify (tree tparms, tree targs, tree parm, tree arg,
int strict,
  /* Now check whether the type of this parameter is still
 dependent, and give up if so.  */
  ++processing_template_decl;
- tparm = tsubst (tparm, targs, tf_none, NULL_TREE);
+ tparm = tsubst (TREE_TYPE (parm), targs, tf_none, NULL_TREE);
  --processing_template_decl;
  if (uses_template_parms (tparm))
return unify_success (explain_p);

i.e. we need to substitute into the original NTTP type, not into the
already substituted NTTP type.


I'm happy rejecting partial-specialization12.C on that basis.  11 is
interesting because int is a non-dependent type; it might be worth adding that
testcase to the DR455 discussion.

I think let's go with this patch and bump down the "partial specialization
isn't more specialized" diagnostic from permerror to on-by-default pedwarn.


Ah, sounds good to me. like so?

-- >8 --

Subject: [PATCH] c++: partial ordering with dependent NTTP type [PR105289]

Here ever since r11-6483-ge2e2f3f2c9400f we're rejecting and crashing
on (respectively) two testcases that we used to accept in C++17 mode
since r8-1437-g3da557ec145823.  Both testcases declare a partial
specialization for which the primary template contains an NTTP with
dependent type, but the validity of these partial specializations is
unclear and is the subject of PR86193 / CWG 455.

This patch just fixes the reported ICE in the second testcase.  The bug
was that when checking whether the type of an NTTP uses still-undeduced
parameters, we'd substitute into the previously substituted NTTP type
instead of into the original NTTP type.

And given that the treatment of such partial specializations seems to
be underspecified in the standard, this patch downgrades the general
"not more specialized" diagnostic from a permerror to a pedwarn.

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


OK.


PR c++/105289
PR c++/86193

gcc/cp/ChangeLog:

* pt.cc (process_partial_specialization): Downgrade "partial
specialization isn't more specialized" diagnostic from permerror
to an on-by-default pedwarn.
(unify) : When substituting into the
NTTP type a second time, use the original type not the
substituted type.

gcc/testsuite/ChangeLog:

* g++.dg/template/partial-specialization11.C: New test.
* g++.dg/template/partial-specialization12.C: New test.
---
  gcc/cp/pt.cc|  7 ---
  .../g++.dg/template/partial-specialization11.C  | 11 +++
  .../g++.dg/template/partial-specialization12.C  | 13 +
  3 files changed, 28 insertions(+), 3 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization11.C
  create mode 100644 gcc/testsuite/g++.dg/template/partial-specialization12.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index dde62ee052d..7dd9e6788f4 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -5227,8 +5227,9 @@ process_partial_specialization (tree decl)
   && !get_partial_spec_bindings (maintmpl, maintmpl, specargs))
  {
auto_diagnostic_group d;
-  if (permerror (input_location, "partial specialization %qD is not "
-"more specialized than", decl))
+  if (pedwarn (input_location, 0,
+  "partial specialization %qD is not more specialized than",
+  decl))
inform (DECL_SOURCE_LOCATION (maintmpl), "primary template %qD",
maintmpl);
  }
@@ -24299,7 +24300,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, 
int strict,
  /* Now check whether the type of this parameter is still
 dependent, and give up if so.  */
  ++processing_template_decl;
- tparm = tsubst (tparm, targs, tf_no

Re: [AArch64] PR105162: emit barrier for __sync and __atomic builtins on CPUs without LSE

2022-04-25 Thread Pop, Sebastian via Gcc-patches
Hi Wilco,

Thanks for your review.
Please find attached the patch amended following your recommendations.
The number of new functions for _sync is reduced by 3x.
I tested the patch on Graviton2 aarch64-linux.
I also checked by hand that the outline functions in libgcc look similar to 
what GCC produces for the inline version.

Thanks,
Sebastian

From: Wilco Dijkstra 
Sent: Tuesday, April 19, 2022 7:51 AM
To: Pop, Sebastian; gcc-patches@gcc.gnu.org
Cc: Kyrylo Tkachov
Subject: RE: [EXTERNAL] [AArch64] PR105162: emit barrier for __sync and 
__atomic builtins on CPUs without LSE

CAUTION: This email originated from outside of the organization. Do not click 
links or open attachments unless you can confirm the sender and know the 
content is safe.



Hi Sebastian,

> Wilco pointed out in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105162#c7​ 
> that
> "Only __sync needs the extra full barrier, but __atomic does not."
> The attached patch does that by adding out-of-line functions for 
> MEMMODEL_SYNC_*.
> Those new functions contain a barrier on the path without LSE instructions.

Yes, adding _sync versions of the outline functions is the correct approach. 
However
there is no need to have separate _acq/_rel/_seq variants for every function 
since all
but one are _seq. Also we should ensure we generate the same sequence as the 
inlined
versions so that they are consistent. This means ensuring the LDXR macro 
ignores the
'A' for the _sync variants and the swp function switches to acquire semantics.

Cheers,
Wilco
From 4e90111e507a611d3daa0f71fc17c6d5cc3e203e Mon Sep 17 00:00:00 2001
From: Sebastian Pop 
Date: Mon, 18 Apr 2022 15:13:20 +
Subject: [PATCH] [AArch64] add barriers to ool __sync builtins

---
 gcc/config/aarch64/aarch64-protos.h   |  2 +-
 gcc/config/aarch64/aarch64.cc | 12 --
 .../gcc.target/aarch64/sync-comp-swap-ool.c   |  6 +++
 .../gcc.target/aarch64/sync-op-acquire-ool.c  |  6 +++
 .../gcc.target/aarch64/sync-op-full-ool.c |  9 
 .../gcc.target/aarch64/target_attr_20.c   |  2 +-
 .../gcc.target/aarch64/target_attr_21.c   |  2 +-
 libgcc/config/aarch64/lse.S   | 42 +--
 libgcc/config/aarch64/t-lse   |  8 ++--
 9 files changed, 75 insertions(+), 14 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sync-comp-swap-ool.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sync-op-acquire-ool.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/sync-op-full-ool.c

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 46bade28ed6..3ad5e77a1af 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -1051,7 +1051,7 @@ bool aarch64_high_bits_all_ones_p (HOST_WIDE_INT);
 
 struct atomic_ool_names
 {
-const char *str[5][4];
+const char *str[5][5];
 };
 
 rtx aarch64_atomic_ool_func(machine_mode mode, rtx model_rtx,
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 18f80499079..3ad11e84aae 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -22670,14 +22670,14 @@ aarch64_emit_unlikely_jump (rtx insn)
   add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
 }
 
-/* We store the names of the various atomic helpers in a 5x4 array.
+/* We store the names of the various atomic helpers in a 5x5 array.
Return the libcall function given MODE, MODEL and NAMES.  */
 
 rtx
 aarch64_atomic_ool_func(machine_mode mode, rtx model_rtx,
 			const atomic_ool_names *names)
 {
-  memmodel model = memmodel_base (INTVAL (model_rtx));
+  memmodel model = memmodel_from_int (INTVAL (model_rtx));
   int mode_idx, model_idx;
 
   switch (mode)
@@ -22717,6 +22717,11 @@ aarch64_atomic_ool_func(machine_mode mode, rtx model_rtx,
 case MEMMODEL_SEQ_CST:
   model_idx = 3;
   break;
+case MEMMODEL_SYNC_ACQUIRE:
+case MEMMODEL_SYNC_RELEASE:
+case MEMMODEL_SYNC_SEQ_CST:
+  model_idx = 4;
+  break;
 default:
   gcc_unreachable ();
 }
@@ -22729,7 +22734,8 @@ aarch64_atomic_ool_func(machine_mode mode, rtx model_rtx,
   { "__aarch64_" #B #N "_relax", \
 "__aarch64_" #B #N "_acq", \
 "__aarch64_" #B #N "_rel", \
-"__aarch64_" #B #N "_acq_rel" }
+"__aarch64_" #B #N "_acq_rel", \
+"__aarch64_" #B #N "_sync" }
 
 #define DEF4(B)  DEF0(B, 1), DEF0(B, 2), DEF0(B, 4), DEF0(B, 8), \
 		 { NULL, NULL, NULL, NULL }
diff --git a/gcc/testsuite/gcc.target/aarch64/sync-comp-swap-ool.c b/gcc/testsuite/gcc.target/aarch64/sync-comp-swap-ool.c
new file mode 100644
index 000..372f4aa8746
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sync-comp-swap-ool.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-march=armv8-a+nolse -O2 -fno-ipa-icf -moutline-atomics" } */
+
+#include "sync-comp-swap.x"
+
+/* { dg-final { scan-assembler-times "bl.*__aarch64_cas4_sync" 1 } } *

testsuite -Wcomment [was: Re: [RFC/CFT] auto-wipe dump files [was: Re: [committed] Fix up bb-slp-31.c testcase]]

2022-04-25 Thread Bernhard Reutner-Fischer via Gcc-patches
On Wed, 30 Oct 2013 10:41:33 +0100
Bernhard Reutner-Fischer  wrote:

> > Hi!
> >
> > I've noticed that this testcase doesn't clean up after itself.
> > Fixed thusly, committed as obvious to trunk.  
> 
> This was nagging me last weekend.. ;)
> What about automating this?
> 
> Manual part is attached.
> The "Adjust all callers" below is too big to send to the list:
> git grep -l -E "(cleanup-.*-dump|cleanup-saved-temps)" | \
> egrep -v "(ChangeLog|/lib/)" | sed -e "s|[^/]*$||" | sort | uniq | \
> while read d;
> do
>   find $d -type f \
> -exec sed -i -e "/cleanup-[^-]*[-]*dump/d;/cleanup-saved-temps/d" {} +
> done
> 
> 
> Full regstrap on x86_64-unknown-linux-gnu with no regressions with
> trunk@204119 for
> configure \
> --enable-bootstrap \
> --with-system-zlib \
> --without-included-gettext \
> --disable-werror \
> --enable-link-mutex \
> --enable-nls \
> --enable-plugin \
> --enable-__cxa_atexit \
> --enable-debug \
> --enable-checking=yes,rtl \
> --enable-gather-detailed-mem-stats \
> --enable-multilib \
> --enable-multiarch \
> --with-linker-hash-style=both \
> --with-as=$BINU/as \
> --with-ld=$BINU/ld.gold \
> --enable-languages=c,c++,fortran,lto,go,objc,obj-c++ \
> && make -k check -j4
> 
> Ok for trunk?
> Comments?
> 
> Given the "Fix comment delimiter" hunks in the manual patch, i'd suggest
> to add -Wcomment as default flags where possible to catch these early on
> in the future.

I should not dare to ping this proposal just yet again, now, without due
patience. But, maybe, we want to automatically add -Wcomment to the
testsuite unless a testcase mentions "comment" in their flags to catch
such malformed comments with dejagnu directives, next stage 1?

The handling should probably be about like what we did with the
-fno-ident that was added to the testsuite as to not confuse
scan-assembler test due to local branch names which was applied in
eb6ffc66825a8d36cf89881517624ff2df510aa9 ( r9-2792 )
https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=eb6ffc66825a8d36cf89881517624ff2df510aa9
iff maybe this can aid as a guide for someone to fix this for good.

TIA,
> 
> gcc/testsuite/ChangeLog
> 
> 2013-10-12  Bernhard Reutner-Fischer  
> 
>   * lib/gcc-dg.exp (cleanup-ipa-dump, cleanup-rtl-dump,
>   cleanup-tree-dump, cleanup-dump): Remove. Adjust all callers.
>   (schedule-cleanups): New proc.
>   (gcc-dg-test-1): Call it.
>   * lib/profopt.exp (profopt-execute): Likewise.
>   * g++.dg/cdce3.C: Adjust expected line numbers.
>   * gcc.dg/cdce1.c: Likewise.
>   * gcc.dg/cdce2.c: Likewise.
>   * gcc.dg/strlenopt-22.c: Fix comment delimiter.
>   * gcc.dg/strlenopt-24.c: Likewise.
>   * gcc.dg/tree-ssa/vrp26.c: Likewise.
>   * gcc.dg/tree-ssa/vrp28.c: Likewise.
>   * obj-c++.dg/encode-2.mm: Likewise.
> 
> libgomp/ChangeLog
> 
> 2013-10-12  Bernhard Reutner-Fischer  
> 
>   * testsuite/libgomp.graphite/bounds.c: Adjust for
>   cleanup-tree-dump removal.
>   * testsuite/libgomp.graphite/force-parallel-1.c: Likewise.
>   * testsuite/libgomp.graphite/force-parallel-2.c: Likewise.
>   * testsuite/libgomp.graphite/force-parallel-3.c: Likewise.
>   * testsuite/libgomp.graphite/force-parallel-4.c: Likewise.
>   * testsuite/libgomp.graphite/force-parallel-5.c: Likewise.
>   * testsuite/libgomp.graphite/force-parallel-6.c: Likewise.
>   * testsuite/libgomp.graphite/force-parallel-7.c: Likewise.
>   * testsuite/libgomp.graphite/force-parallel-8.c: Likewise.
>   * testsuite/libgomp.graphite/force-parallel-9.c: Likewise.
>   * testsuite/libgomp.graphite/pr41118.c: Likewise.
> 
> 
> gcc/ChangeLog
> 
> 2013-10-12  Bernhard Reutner-Fischer  
> 
>   * config/arm/neon-testgen.ml (emit_epilogue): Remove manual call
>   to cleanup-saved-temps.
> 
> gcc/doc/ChangeLog
> 
> 2013-10-12  Bernhard Reutner-Fischer  
> 
>   * doc/sourcebuild.texi (Clean up generated test files): Expand
>   introduction.
>   (cleanup-ipa-dump, cleanup-rtl-dump, cleanup-tree-dump,
>   cleanup-saved-temps): Remove.



testsuite -fno-file [was: Re: [PATCH] PR52665 do not let .ident confuse assembler scan tests]

2022-04-25 Thread Bernhard Reutner-Fischer via Gcc-patches
On Fri, 2 Feb 2018 14:25:22 +0100
Bernhard Reutner-Fischer  wrote:

> On 19 June 2016 at 22:21, Mike Stump  wrote:
> > On Jun 18, 2016, at 12:31 PM, Bernhard Reutner-Fischer 
> >  wrote:  
> >>
> >> A branch with a name matching scan-assembler pattern triggers
> >> inappropriate FAIL.  
> >  
> >> The patch below adds -fno-ident if a testcase contains one of
> >> scan-assembler, scan-assembler-not or scan-assembler-times.  
> >
> > Kinda gross.  I'd like to consensus build a little, as I don't know that I 
> > have a better solution than the solution you propose to fix the issue.  I'd 
> > love it if one or more of Jacob, Law and Richard can chime in on direction 
> > here.  I'll have to think about this some more and see if I can come up 
> > with something that I like better.
> >
> > If no one has a better solution, I'll approve the proposed solution.  Let's 
> > give people a little time to chime in.  
> 
> Given the overwhelming silence this proposal has received, i take it
> for granted that folks are thrilled and even up until now speechless
> :)
> 
> So how should we proceed with -fno-ident.
> And, btw, -fno-file to inhibit .file directives for the same reason,

AFAICS we still do not pass -fno-file in tests.
Every now and then this still results in unnecessary, silly workarounds
like this one:

> https://gcc.gnu.org/ml/gcc-patches/2017-09/msg01785.html and all our

which we should not have to afford.

> ugly filenames like gcc.target/powerpc/swps-p8-36.c which strive to
> workaround the assembler-scans.
> 
> All those non-automatic hacks like naming swap() tests swps-,
> uglifying scan-patterns (which are not terribly straight forward to
> read anyway even without uglifying them) are error prone and costly.
> IMHO we should make sure time is spent for useful stuff and not be
> wasted to fight our very own testsuite.
> 
> -fno-ident ok for stage1?

We've fixed the ident thing some time ago.

> What about -fno-file? Clever alternative suggestions? Don't care?

We still didn't fix the .file directives in assembler output.

It's about the same as always.
See if the target supports -fno-file and/or -ffile.
If the testcase does NOT specify -fno-file or -ffile ¹)
then pass an appropriate default like -fno-file, otherwise do not add
anything.

¹) The real complication seems to be that there is neither a -fno-file
nor a (let's say) -ffile=foo.c implemented anywhere. And TBH we do
not need it nor want it for the purpose at hand. That suggests
that it would probably be cheaper to run sed on the (remote) output
file -- or do it locally and only then copy it to the remote. The net
effect being that .file directives in the testsuite are gone and can no
longer compromise tests.

thanks,


[committed] analyzer: fix ICEs on complex constants [PR105365, 105366]

2022-04-25 Thread David Malcolm via Gcc-patches
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r12-8254-g6ad3ca0077ec0d5f740cef5fdb743ffb61575941.

gcc/analyzer/ChangeLog:
PR analyzer/105365
PR analyzer/105366
* svalue.cc
(cmp_cst): Rename to...
(cmp_csts_same_type): ...this.  Convert all recursive calls to
calls to...
(cmp_csts_and_types): this new function.
(svalue::cmp_ptr): Update for renaming of cmp_cst

gcc/testsuite/ChangeLog:
PR analyzer/105365
PR analyzer/105366
* gcc.dg/analyzer/pr105365.c: New test.
* gcc.dg/analyzer/pr105366.c: New test.

Signed-off-by: David Malcolm 
---
 gcc/analyzer/svalue.cc   | 30 +---
 gcc/testsuite/gcc.dg/analyzer/pr105365.c | 17 ++
 gcc/testsuite/gcc.dg/analyzer/pr105366.c | 19 +++
 3 files changed, 57 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr105365.c
 create mode 100644 gcc/testsuite/gcc.dg/analyzer/pr105366.c

diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc
index a1403f0fbef..ed289c6fc31 100644
--- a/gcc/analyzer/svalue.cc
+++ b/gcc/analyzer/svalue.cc
@@ -59,6 +59,8 @@ along with GCC; see the file COPYING3.  If not see
 
 namespace ana {
 
+static int cmp_csts_and_types (const_tree cst1, const_tree cst2);
+
 /* class svalue and its various subclasses.  */
 
 /* class svalue.  */
@@ -304,7 +306,7 @@ svalue::implicitly_live_p (const svalue_set *, const 
region_model *) const
of the same type.  */
 
 static int
-cmp_cst (const_tree cst1, const_tree cst2)
+cmp_csts_same_type (const_tree cst1, const_tree cst2)
 {
   gcc_assert (TREE_TYPE (cst1) == TREE_TYPE (cst2));
   gcc_assert (TREE_CODE (cst1) == TREE_CODE (cst2));
@@ -323,9 +325,10 @@ cmp_cst (const_tree cst1, const_tree cst2)
 TREE_REAL_CST_PTR (cst2),
 sizeof (real_value));
 case COMPLEX_CST:
-  if (int cmp_real = cmp_cst (TREE_REALPART (cst1), TREE_REALPART (cst2)))
+  if (int cmp_real = cmp_csts_and_types (TREE_REALPART (cst1),
+TREE_REALPART (cst2)))
return cmp_real;
-  return cmp_cst (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
+  return cmp_csts_and_types (TREE_IMAGPART (cst1), TREE_IMAGPART (cst2));
 case VECTOR_CST:
   if (int cmp_log2_npatterns
= ((int)VECTOR_CST_LOG2_NPATTERNS (cst1)
@@ -340,17 +343,26 @@ cmp_cst (const_tree cst1, const_tree cst2)
{
  const_tree elt1 = VECTOR_CST_ENCODED_ELT (cst1, i);
  const_tree elt2 = VECTOR_CST_ENCODED_ELT (cst2, i);
- int t1 = TYPE_UID (TREE_TYPE (elt1));
- int t2 = TYPE_UID (TREE_TYPE (elt2));
- if (int cmp_type = t1 - t2)
-   return cmp_type;
- if (int el_cmp = cmp_cst (elt1, elt2))
+ if (int el_cmp = cmp_csts_and_types (elt1, elt2))
return el_cmp;
}
   return 0;
 }
 }
 
+/* Comparator for imposing a deterministic order on constants that might
+   not be of the same type.  */
+
+static int
+cmp_csts_and_types (const_tree cst1, const_tree cst2)
+{
+  int t1 = TYPE_UID (TREE_TYPE (cst1));
+  int t2 = TYPE_UID (TREE_TYPE (cst2));
+  if (int cmp_type = t1 - t2)
+return cmp_type;
+  return cmp_csts_same_type (cst1, cst2);
+}
+
 /* Comparator for imposing a deterministic order on svalues.  */
 
 int
@@ -382,7 +394,7 @@ svalue::cmp_ptr (const svalue *sval1, const svalue *sval2)
const constant_svalue *constant_sval2 = (const constant_svalue *)sval2;
const_tree cst1 = constant_sval1->get_constant ();
const_tree cst2 = constant_sval2->get_constant ();
-   return cmp_cst (cst1, cst2);
+   return cmp_csts_same_type (cst1, cst2);
   }
   break;
 case SK_UNKNOWN:
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105365.c 
b/gcc/testsuite/gcc.dg/analyzer/pr105365.c
new file mode 100644
index 000..aa576d08632
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr105365.c
@@ -0,0 +1,17 @@
+/* { dg-require-effective-target int128 } */
+
+typedef _Float32 f32;
+typedef _Complex _Float32 cf32;
+_Float32 g;
+__int128 i;
+
+extern void bar(int);
+
+void
+foo(_Float32 k) {
+  f32 f = 0;
+  f /= (_Complex char)__builtin_llround(g);
+  k /= (cf32)__builtin_copysignf(0, i);
+  bar(f + k);
+  foo(0);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105366.c 
b/gcc/testsuite/gcc.dg/analyzer/pr105366.c
new file mode 100644
index 000..3dba870e4e9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr105366.c
@@ -0,0 +1,19 @@
+/* { dg-require-effective-target int128 } */
+/* { dg-additional-options "-O" } */
+
+extern void bar(int);
+extern void baz(void);
+
+typedef unsigned u32;
+
+void
+foo(u32 u, __int128 i) {
+  baz();
+  _Complex int c = i;
+  c /= (u32)(__UINTPTR_TYPE__)foo;
+  short s = (short)(__UINTPTR_TYPE__)foo;
+  u /= (_Complex short)s;
+  u32 r = u + c;
+  bar(r);
+  foo(0, 0);
+}
-- 
2.26.3



[pushed] c++: generic lambda fn parm pack [PR104624]

2022-04-25 Thread Jason Merrill via Gcc-patches
Parameter packs from the enclosing context can be used unexpanded in a
lambda that is itself part of a pack expansion, but not packs that are part
of the lambda itself.  We already check for capture packs; we also need to
check for function parameter packs of the lambda call operator.

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

PR c++/104624

gcc/cp/ChangeLog:

* pt.cc (check_for_bare_parameter_packs): Check for lambda
function parameter pack.

gcc/testsuite/ChangeLog:

* g++.dg/cpp1y/lambda-generic-variadic22.C: New test.
---
 gcc/cp/pt.cc  |  4 +++-
 .../g++.dg/cpp1y/lambda-generic-variadic22.C  | 15 +++
 2 files changed, 18 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic22.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index dde62ee052d..c05783f505f 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -4341,7 +4341,9 @@ check_for_bare_parameter_packs (tree t, location_t loc /* 
= UNKNOWN_LOCATION */)
 parameter_packs = TREE_CHAIN (parameter_packs))
   {
tree pack = TREE_VALUE (parameter_packs);
-   if (is_capture_proxy (pack))
+   if (is_capture_proxy (pack)
+   || (TREE_CODE (pack) == PARM_DECL
+   && DECL_CONTEXT (DECL_CONTEXT (pack)) == lam))
  break;
   }
 
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic22.C 
b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic22.C
new file mode 100644
index 000..670c598a865
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic22.C
@@ -0,0 +1,15 @@
+// PR c++/104624
+// { dg-do compile { target c++14 } }
+
+template 
+auto f (T)
+{
+  auto a = [](auto ... i)  // { dg-prune-output "incomplete type" }
+  {
+int x[][i] = { 0 };// { dg-error "not expanded" }
+  }();
+}
+void g ()
+{
+  f(0);
+}

base-commit: ab91c10792cd3a1ba1495aa30a34ca17b043bafb
-- 
2.27.0



[PATCH] i386: Improve ix86_expand_int_movcc

2022-04-25 Thread Jakub Jelinek via Gcc-patches
Hi!

When working on PR105338, I've noticed that in some cases we emit
unnecessarily long sequence which has then higher seq_cost than necessary.

E.g. when ix86_expand_int_movcc is called with
operands[0] (reg/v:SI 83 [ i ])
operands[1] (eq (reg/v:SI 83 [ i ]) (const_int 0 [0]))
operands[2] (reg/v:SI 83 [ i ])
operands[3] (const_int -2 [0xfffe])
i.e. r83 = r83 == 0 ? r83 : -2 which with my PR105338 patch is equivalent to
r83 = r83 == 0 ? 0 : -2, we emit:
(insn 24 0 25 (set (reg:CC 17 flags)
(compare:CC (reg/v:SI 83 [ i ])
(const_int 1 [0x1]))) 11 {*cmpsi_1}
 (nil))
(insn 25 24 26 (parallel [
(set (reg:SI 85)
(if_then_else:SI (ltu:SI (reg:CC 17 flags)
(const_int 0 [0]))
(const_int -1 [0x])
(const_int 0 [0])))
(clobber (reg:CC 17 flags))
]) 1192 {*x86_movsicc_0_m1}
 (nil))
(insn 26 25 27 (set (reg:SI 85)
(not:SI (reg:SI 85))) 683 {*one_cmplsi2_1}
 (nil))
(insn 27 26 28 (parallel [
(set (reg:SI 85)
(and:SI (reg:SI 85)
(const_int -2 [0xfffe])))
(clobber (reg:CC 17 flags))
]) 533 {*andsi_1}
 (nil))
(insn 28 27 0 (set (reg/v:SI 83 [ i ])
(reg:SI 85)) 81 {*movsi_internal}
 (nil))
which has seq_cost (seq, true) 24.  But it could have just cost 20
if we didn't decide to use a fresh temporary r85 and used r83 instead
- we could avoid the copy at the end.
The reason for it is in the 2 reg_overlap_mentioned_p calls,
the destination (out) indeed overlaps op0 - it is the same register,
but I don't see why that is a problem, this is in a code path where
we've already called
ix86_expand_carry_flag_compare (code, op0, op1, &compare_op)
earlier, so the fact that we've out overlaps op0 or op1 shouldn't matter
because insn 24 above is already emitted, we should just care if
it overlaps whatever we got from that ix86_expand_carry_flag_compare
call, i.e. compare_op, otherwise we can overwrite out just fine;
we also know at that point that the last 2 operands of ?: are constants.

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

2022-04-26  Jakub Jelinek  

* config/i386/i386-expand.cc (ix86_expand_int_movcc): Create a
temporary only if out overlaps compare_op, not when it overlaps
op0 or op1.

--- gcc/config/i386/i386-expand.cc.jj   2022-04-22 14:18:27.0 +0200
+++ gcc/config/i386/i386-expand.cc  2022-04-22 15:13:47.263829089 +0200
@@ -3224,8 +3224,7 @@ ix86_expand_int_movcc (rtx operands[])
}
  diff = ct - cf;
 
- if (reg_overlap_mentioned_p (out, op0)
- || reg_overlap_mentioned_p (out, op1))
+ if (reg_overlap_mentioned_p (out, compare_op))
tmp = gen_reg_rtx (mode);
 
  if (mode == DImode)

Jakub



[PATCH] i386: Fix up ICE with -mveclibabi={acml,svml} [PR105367]

2022-04-25 Thread Jakub Jelinek via Gcc-patches
Hi!

The following testcase ICEs, because conversion between scalar float types
which have the same mode are useless in GIMPLE, but for mathfn_built_in the
exact type matters (it treats say double and _Float64 or float and _Float32
differently, using different suffixes and for the _Float* sometimes
returning NULL when float/double do have a builtin).

In ix86_veclibabi_{svml,acml} we are using mathfn_built_in just so that
we don't have to translate the combined_fn and SFmode vs. DFmode into
strings ourselfs, and we already earlier punt on anything but SFmode and
DFmode.  So, this patch just uses the double or float types depending
on the modes, rather than the types we actually got and which might be
_Float64 or _Float32 etc.

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

2022-04-26  Jakub Jelinek  

PR target/105367
* config/i386/i386.cc (ix86_veclibabi_svml, ix86_veclibabi_acml): Pass
el_mode == DFmode ? double_type_node : float_type_node instead of
TREE_TYPE (type_in) as first arguments to mathfn_built_in.

* gcc.target/i386/pr105367.c: New test.

--- gcc/config/i386/i386.cc.jj  2022-04-22 13:36:42.558150777 +0200
+++ gcc/config/i386/i386.cc 2022-04-25 12:30:09.862736906 +0200
@@ -18807,7 +18807,8 @@ ix86_veclibabi_svml (combined_fn fn, tre
   return NULL_TREE;
 }
 
-  tree fndecl = mathfn_built_in (TREE_TYPE (type_in), fn);
+  tree fndecl = mathfn_built_in (el_mode == DFmode
+? double_type_node : float_type_node, fn);
   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
 
   if (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LOGF)
@@ -18899,7 +18900,8 @@ ix86_veclibabi_acml (combined_fn fn, tre
   return NULL_TREE;
 }
 
-  tree fndecl = mathfn_built_in (TREE_TYPE (type_in), fn);
+  tree fndecl = mathfn_built_in (el_mode == DFmode
+? double_type_node : float_type_node, fn);
   bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
   sprintf (name + 7, "%s", bname+10);
 
--- gcc/testsuite/gcc.target/i386/pr105367.c.jj 2022-04-25 12:25:16.724809778 
+0200
+++ gcc/testsuite/gcc.target/i386/pr105367.c2022-04-25 12:24:34.004403339 
+0200
@@ -0,0 +1,12 @@
+/* PR target/105367 */
+/* { dg-do compile } */
+/* { dg-options "-Ofast -mveclibabi=acml" } */
+
+_Float64 g;
+
+void
+foo (void)
+{
+  _Float64 f = __builtin_sin (g);
+  g = __builtin_fmax (__builtin_sin (f), f);
+}

Jakub