Fix one issue in OpenMP 'requires' directive diagnostics (was: [Patch][v5] OpenMP: Move omp requires checks to libgomp)

Message ID 87h73t3vh1.fsf@euler.schwinge.homeip.net
State Committed
Headers
Series Fix one issue in OpenMP 'requires' directive diagnostics (was: [Patch][v5] OpenMP: Move omp requires checks to libgomp) |

Commit Message

Thomas Schwinge July 7, 2022, 1:26 p.m. UTC
  Hi!

On 2022-07-01T23:08:16+0200, Tobias Burnus <tobias@codesourcery.com> wrote:
> Updated version attached – I hope I got everything right, but I start to
> get tired, I am not 100% sure.

..., and so the obligatory copy'n'past-o ;-) crept in:

> --- a/gcc/lto-cgraph.cc
> +++ b/gcc/lto-cgraph.cc

> @@ -1773,6 +1804,10 @@ input_offload_tables (bool do_force_output)
>    struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
>    struct lto_file_decl_data *file_data;
>    unsigned int j = 0;
> +  const char *requires_fn = NULL;
> +  tree requires_decl = NULL_TREE;
> +
> +  omp_requires_mask = (omp_requires) 0;
>
>    while ((file_data = file_data_vec[j++]))
>      {
> @@ -1784,6 +1819,7 @@ input_offload_tables (bool do_force_output)
>        if (!ib)
>       continue;
>
> +      tree tmp_decl = NULL_TREE;
>        enum LTO_symtab_tags tag
>       = streamer_read_enum (ib, LTO_symtab_tags, LTO_symtab_last_tag);
>        while (tag)
> @@ -1799,6 +1835,7 @@ input_offload_tables (bool do_force_output)
>                LTO mode.  */
>             if (do_force_output)
>               cgraph_node::get (fn_decl)->mark_force_output ();
> +           tmp_decl = fn_decl;
>           }
>         else if (tag == LTO_symtab_variable)
>           {
> @@ -1810,6 +1847,72 @@ input_offload_tables (bool do_force_output)
>                may be no refs to var_decl in offload LTO mode.  */
>             if (do_force_output)
>               varpool_node::get (var_decl)->force_output = 1;
> +           tmp_decl = var_decl;
> +         }
> +       else if (tag == LTO_symtab_edge)
> +         {
> +           static bool error_emitted = false;
> +           HOST_WIDE_INT val = streamer_read_hwi (ib);
> +
> +           if (omp_requires_mask == 0)
> +             {
> +               omp_requires_mask = (omp_requires) val;
> +               requires_decl = tmp_decl;
> +               requires_fn = file_data->file_name;
> +             }
> +           else if (omp_requires_mask != val && !error_emitted)
> +             {
> +               const char *fn1 = requires_fn;
> +               if (requires_decl != NULL_TREE)
> +                 {
> +                   while (DECL_CONTEXT (requires_decl) != NULL_TREE
> +                          && TREE_CODE (requires_decl) != TRANSLATION_UNIT_DECL)
> +                     requires_decl = DECL_CONTEXT (requires_decl);
> +                   if (requires_decl != NULL_TREE)
> +                     fn1 = IDENTIFIER_POINTER (DECL_NAME (requires_decl));
> +                 }
> +
> +               const char *fn2 = file_data->file_name;
> +               if (tmp_decl != NULL_TREE)
> +                 {
> +                   while (DECL_CONTEXT (tmp_decl) != NULL_TREE
> +                          && TREE_CODE (tmp_decl) != TRANSLATION_UNIT_DECL)
> +                     tmp_decl = DECL_CONTEXT (tmp_decl);
> +                   if (tmp_decl != NULL_TREE)
> +                     fn2 = IDENTIFIER_POINTER (DECL_NAME (requires_decl));
> +                 }

... here: tmp_decl' not 'requires_decl'.  OK to push the attached
"Fix one issue in OpenMP 'requires' directive diagnostics"?

I'd even push that one "as obvious", but thought I'd ask whether you
maybe have a quick idea about the XFAILs that I'm adding?  (I'm otherwise
not planning on resolving that issue at this time.)

> +
> +               char buf1[sizeof ("unified_address, unified_shared_memory, "
> +                                 "reverse_offload")];
> +               char buf2[sizeof ("unified_address, unified_shared_memory, "
> +                                 "reverse_offload")];
> +               omp_requires_to_name (buf2, sizeof (buf2),
> +                                     val != OMP_REQUIRES_TARGET_USED
> +                                     ? val
> +                                     : (HOST_WIDE_INT) omp_requires_mask);
> +               if (val != OMP_REQUIRES_TARGET_USED
> +                   && omp_requires_mask != OMP_REQUIRES_TARGET_USED)
> +                 {
> +                   omp_requires_to_name (buf1, sizeof (buf1),
> +                                         omp_requires_mask);
> +                   error ("OpenMP %<requires%> directive with non-identical "
> +                          "clauses in multiple compilation units: %qs vs. "
> +                          "%qs", buf1, buf2);
> +                   inform (UNKNOWN_LOCATION, "%qs has %qs", fn1, buf1);
> +                   inform (UNKNOWN_LOCATION, "%qs has %qs", fn2, buf2);
> +                 }
> +               else
> +                 {
> +                   error ("OpenMP %<requires%> directive with %qs specified "
> +                          "only in some compilation units", buf2);
> +                   inform (UNKNOWN_LOCATION, "%qs has %qs",
> +                           val != OMP_REQUIRES_TARGET_USED ? fn2 : fn1,
> +                           buf2);
> +                   inform (UNKNOWN_LOCATION, "but %qs has not",
> +                           val != OMP_REQUIRES_TARGET_USED ? fn1 : fn2);
> +                 }
> +               error_emitted = true;
> +             }
>           }
>         else
>           fatal_error (input_location,


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
  

Comments

Tobias Burnus July 7, 2022, 1:56 p.m. UTC | #1
Hi Thomas,

On 07.07.22 15:26, Thomas Schwinge wrote:
> On 2022-07-01T23:08:16+0200, Tobias Burnus <tobias@codesourcery.com>
> wrote:
>> Updated version attached – I hope I got everything right, but I start to
>> get tired, I am not 100% sure.
> ..., and so the obligatory copy'n'past-o;-)  crept in:
...
>> +                  if (tmp_decl != NULL_TREE)
>> +                    fn2 = IDENTIFIER_POINTER (DECL_NAME (requires_decl));
>> +                }
> ... here: tmp_decl' not 'requires_decl'.  OK to push the attached
> "Fix one issue in OpenMP 'requires' directive diagnostics"?
Good that you spotted it and thanks for testing + fixing it!
> I'd even push that one "as obvious", but thought I'd ask whether you
> maybe have a quick idea about the XFAILs that I'm adding?  (I'm otherwise
> not planning on resolving that issue at this time.)

(This question relates to what's printed if there is no TRANSLATION_UNIT_DECL.)

  * * *

Pre-remark - the code does:

* If there is any offload_func or offload_var DECL in the TU, it uses
   that one for diagnostic.
   This is always the case if there is a 'declare target' or 'omp target'
   but not when there is only 'omp target data'.
   → In real-world code it likely has a proper name.

* Otherwise, it takes the file name of file_data->file_name.

With -save-temps, that's based on the input files, which
gives a useful output.

When using
   gcc -c *.c
   gcc *.o
the file name is <inputfile>.o - which is also quite useful.

However, when doing
   gcc *.c
which combines compiling and linking in one step, the filename
is /tmp/cc*.o which is not that helpful.

There is no real way to avoid this, unless we explicitly store the
filename or some location_t for the 'requires'. But the used
LTO writer does not support it directly. It can be fixed, but
requires some re-organization and increased intermittent .o file
size. (Cf. https://gcc.gnu.org/pipermail/gcc-patches/2022-June/597496.html
for what it needed and why it does not work.)

However, in the real world, there should be usually a proper message as
(a) It is unlikely to have code which only does 'omp target ... data'
     transfer - and no 'omp target'
and
(b) for larger code, separating compilation and linking is common
     while for smaller code, 'requires' mismatches is less likely and
     also easier to find the file causing the issue.

Still, like always, having a nice diagnostic would not harm :-)

  * * *

> Subject: [PATCH] Fix one issue in OpenMP 'requires' directive diagnostics
>
> Fix-up for recent commit 683f11843974f0bdf42f79cdcbb0c2b43c7b81b0
> "OpenMP: Move omp requires checks to libgomp".
>
>       gcc/
>       * lto-cgraph.cc (input_offload_tables) <LTO_symtab_edge>: Correct
>       'fn2' computation.
>       libgomp/
>       * testsuite/libgomp.c-c++-common/requires-1.c: Add 'dg-note's.
>       * testsuite/libgomp.c-c++-common/requires-2.c: Likewise.
>       * testsuite/libgomp.c-c++-common/requires-3.c: Likewise.
>       * testsuite/libgomp.c-c++-common/requires-7.c: Likewise.
>       * testsuite/libgomp.fortran/requires-1.f90: Likewise.

Regarding the patch, it adds 'dg-note' for the location data - and fixes the wrong-decl-use bug.

Those LGTM - Thanks!

Regarding the xfail part:

> --- a/libgomp/testsuite/libgomp.c-c++-common/requires-7.c
...
>   -/* { dg-error "OpenMP 'requires' directive with non-identical clauses in multiple compilation units: 'unified_shared_memory' vs. 'unified_address'" "" { target *-*-* } 0 }  */
> +/* { dg-error "OpenMP 'requires' directive with non-identical clauses in multiple compilation units: 'unified_shared_memory' vs. 'unified_address'" "" { target *-*-* } 0 }
> +     { dg-note {requires-7\.c' has 'unified_shared_memory'} {} { target *-*-* } 0 }
> +     TODO There is some issue that we're not seeing the source file name here (but a temporary '*.o' instead):
> +     { dg-note {requires-7-aux\.c' has 'unified_address'} {} { xfail *-*-* } 0 }
> +     ..., so verify that at least the rest of the diagnostic is correct:
> +     { dg-note {' has 'unified_address'} {} { target *-*-* } 0 } */

The requires-7-aux.c file uses, on purpose, only 'omp target enter data'
to trigger the .o name in 'inform' as no decl is written to
offload_func/offload_vars for that TU.

As the testsuite compiles+links the two requires-7*.c files in one step
and is invoked without -save-temps, the used object file names will be
/tmp/cc*.o.

* * *

Regarding the xfail: I think it is fine to have this xfail, but as it is
clear why inform points to /tmp/cc*.o, you could reword the TODO to
state why it goes wrong.

Thanks,

Tobias

-----------------
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
  
Thomas Schwinge July 8, 2022, 6:59 a.m. UTC | #2
Hi!

On 2022-07-07T15:56:28+0200, Tobias Burnus <tobias@codesourcery.com> wrote:
> On 07.07.22 15:26, Thomas Schwinge wrote:
>> On 2022-07-01T23:08:16+0200, Tobias Burnus <tobias@codesourcery.com>
>> wrote:
>>> Updated version attached – I hope I got everything right, but I start to
>>> get tired, I am not 100% sure.
>> ..., and so the obligatory copy'n'past-o;-)  crept in:
> ...
>>> +                 if (tmp_decl != NULL_TREE)
>>> +                   fn2 = IDENTIFIER_POINTER (DECL_NAME (requires_decl));
>>> +               }
>> ... here: tmp_decl' not 'requires_decl'.  OK to push the attached
>> "Fix one issue in OpenMP 'requires' directive diagnostics"?
> Good that you spotted it and thanks for testing + fixing it!
>> I'd even push that one "as obvious", but thought I'd ask whether you
>> maybe have a quick idea about the XFAILs that I'm adding?  (I'm otherwise
>> not planning on resolving that issue at this time.)
>
> (This question relates to what's printed if there is no TRANSLATION_UNIT_DECL.)
> [...]

Thanks for the explanation, makes sense.

> Regarding the xfail: I think it is fine to have this xfail, but as it is
> clear why inform points to /tmp/cc*.o, you could reword the TODO to
> state why it goes wrong.

Done:

    TODO We're currently not streaming location information for the OpenMP
    directives used in 'requires-7-aux.c', so we're not seeing the source file
    name here (but a temporary '*.o' instead; for details, see
    <https://gcc.gnu.org/pipermail/gcc-patches/2022-July/598011.html>):
    { dg-note {requires-7-aux\.c' has 'unified_address'} {} { xfail *-*-* } 0 }
    ..., but we may still verify that the rest of the diagnostic is correct:
    { dg-note {' has 'unified_address'} {} { target *-*-* } 0 }

With just that changed, I've pushed to master branch
commit faa0c328ee65f0d6d65d6e20181d26e336071919
"Fix one issue in OpenMP 'requires' directive diagnostics", 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
  

Patch

From 2271282f127366e785601242a46d4aa668bd6660 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <thomas@codesourcery.com>
Date: Thu, 7 Jul 2022 15:11:03 +0200
Subject: [PATCH] Fix one issue in OpenMP 'requires' directive diagnostics

Fix-up for recent commit 683f11843974f0bdf42f79cdcbb0c2b43c7b81b0
"OpenMP: Move omp requires checks to libgomp".

	gcc/
	* lto-cgraph.cc (input_offload_tables) <LTO_symtab_edge>: Correct
	'fn2' computation.
	libgomp/
	* testsuite/libgomp.c-c++-common/requires-1.c: Add 'dg-note's.
	* testsuite/libgomp.c-c++-common/requires-2.c: Likewise.
	* testsuite/libgomp.c-c++-common/requires-3.c: Likewise.
	* testsuite/libgomp.c-c++-common/requires-7.c: Likewise.
	* testsuite/libgomp.fortran/requires-1.f90: Likewise.
---
 gcc/lto-cgraph.cc                                   | 2 +-
 libgomp/testsuite/libgomp.c-c++-common/requires-1.c | 4 +++-
 libgomp/testsuite/libgomp.c-c++-common/requires-2.c | 4 +++-
 libgomp/testsuite/libgomp.c-c++-common/requires-3.c | 4 +++-
 libgomp/testsuite/libgomp.c-c++-common/requires-7.c | 7 ++++++-
 libgomp/testsuite/libgomp.fortran/requires-1.f90    | 5 +++++
 6 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/gcc/lto-cgraph.cc b/gcc/lto-cgraph.cc
index 48629651e31..6d9c36ea8b6 100644
--- a/gcc/lto-cgraph.cc
+++ b/gcc/lto-cgraph.cc
@@ -1879,7 +1879,7 @@  input_offload_tables (bool do_force_output)
 			     && TREE_CODE (tmp_decl) != TRANSLATION_UNIT_DECL)
 			tmp_decl = DECL_CONTEXT (tmp_decl);
 		      if (tmp_decl != NULL_TREE)
-			fn2 = IDENTIFIER_POINTER (DECL_NAME (requires_decl));
+			fn2 = IDENTIFIER_POINTER (DECL_NAME (tmp_decl));
 		    }
 
 		  char buf1[sizeof ("unified_address, unified_shared_memory, "
diff --git a/libgomp/testsuite/libgomp.c-c++-common/requires-1.c b/libgomp/testsuite/libgomp.c-c++-common/requires-1.c
index ab9a8ddfcde..31996f1ecf6 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/requires-1.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/requires-1.c
@@ -20,5 +20,7 @@  main (void)
   return 0;
 }
 
-/* { dg-error "OpenMP 'requires' directive with non-identical clauses in multiple compilation units: 'unified_shared_memory' vs. 'unified_address'" "" { target *-*-* } 0 }  */
+/* { dg-error "OpenMP 'requires' directive with non-identical clauses in multiple compilation units: 'unified_shared_memory' vs. 'unified_address'" "" { target *-*-* } 0 }
+     { dg-note {requires-1\.c' has 'unified_shared_memory'} {} { target *-*-* } 0 }
+     { dg-note {requires-1-aux\.c' has 'unified_address'} {} { target *-*-* } 0 } */
 /* { dg-excess-errors "Ignore messages like: errors during merging of translation units|mkoffload returned 1 exit status" } */
diff --git a/libgomp/testsuite/libgomp.c-c++-common/requires-2.c b/libgomp/testsuite/libgomp.c-c++-common/requires-2.c
index be1830d0c46..b20e154b0c7 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/requires-2.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/requires-2.c
@@ -21,5 +21,7 @@  main (void)
   return 0;
 }
 
-/* { dg-error "OpenMP 'requires' directive with 'unified_shared_memory' specified only in some compilation units" "" { target *-*-* } 0 }  */
+/* { dg-error "OpenMP 'requires' directive with 'unified_shared_memory' specified only in some compilation units" "" { target *-*-* } 0 }
+     { dg-note {requires-2\.c' has 'unified_shared_memory'} {} { target *-*-* } 0 }
+     { dg-note {but '[^']*requires-2-aux\.c' has not} {} { target *-*-* } 0 } */
 /* { dg-excess-errors "Ignore messages like: errors during merging of translation units|mkoffload returned 1 exit status" } */
diff --git a/libgomp/testsuite/libgomp.c-c++-common/requires-3.c b/libgomp/testsuite/libgomp.c-c++-common/requires-3.c
index 1c204c8a21e..a549a19ebbb 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/requires-3.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/requires-3.c
@@ -20,5 +20,7 @@  main (void)
   return 0;
 }
 
-/* { dg-error "OpenMP 'requires' directive with non-identical clauses in multiple compilation units: 'unified_address, unified_shared_memory' vs. 'unified_address'" "" { target *-*-* } 0 }  */
+/* { dg-error "OpenMP 'requires' directive with non-identical clauses in multiple compilation units: 'unified_address, unified_shared_memory' vs. 'unified_address'" "" { target *-*-* } 0 }
+     { dg-note {requires-3\.c' has 'unified_address, unified_shared_memory'} {} { target *-*-* } 0 }
+     { dg-note {requires-3-aux\.c' has 'unified_address'} {} { target *-*-* } 0 } */
 /* { dg-excess-errors "Ignore messages like: errors during merging of translation units|mkoffload returned 1 exit status" } */
diff --git a/libgomp/testsuite/libgomp.c-c++-common/requires-7.c b/libgomp/testsuite/libgomp.c-c++-common/requires-7.c
index 7473aa62e08..370ed338e4c 100644
--- a/libgomp/testsuite/libgomp.c-c++-common/requires-7.c
+++ b/libgomp/testsuite/libgomp.c-c++-common/requires-7.c
@@ -20,5 +20,10 @@  main (void)
   return 0;
 }
 
-/* { dg-error "OpenMP 'requires' directive with non-identical clauses in multiple compilation units: 'unified_shared_memory' vs. 'unified_address'" "" { target *-*-* } 0 }  */
+/* { dg-error "OpenMP 'requires' directive with non-identical clauses in multiple compilation units: 'unified_shared_memory' vs. 'unified_address'" "" { target *-*-* } 0 }
+     { dg-note {requires-7\.c' has 'unified_shared_memory'} {} { target *-*-* } 0 }
+     TODO There is some issue that we're not seeing the source file name here (but a temporary '*.o' instead):
+     { dg-note {requires-7-aux\.c' has 'unified_address'} {} { xfail *-*-* } 0 }
+     ..., so verify that at least the rest of the diagnostic is correct:
+     { dg-note {' has 'unified_address'} {} { target *-*-* } 0 } */
 /* { dg-excess-errors "Ignore messages like: errors during merging of translation units|mkoffload returned 1 exit status" } */
diff --git a/libgomp/testsuite/libgomp.fortran/requires-1.f90 b/libgomp/testsuite/libgomp.fortran/requires-1.f90
index e957b1b5918..59211496c33 100644
--- a/libgomp/testsuite/libgomp.fortran/requires-1.f90
+++ b/libgomp/testsuite/libgomp.fortran/requires-1.f90
@@ -23,4 +23,9 @@  program main
 end
 
 ! { dg-error "OpenMP 'requires' directive with non-identical clauses in multiple compilation units: 'unified_shared_memory' vs. 'unified_address'" "" { target *-*-* } 0 }
+!   { dg-note {requires-1\.f90' has 'unified_shared_memory'} {} { target *-*-* } 0 }
+!   TODO There is some issue that we're not seeing the source file name here (but a temporary '*.o' instead):
+!   { dg-note {requires-1-aux\.f90' has 'unified_address'} {} { xfail *-*-* } 0 }
+!   ..., so verify that at least the rest of the diagnostic is correct:
+!   { dg-note {' has 'unified_address'} {} { target *-*-* } 0 }
 ! { dg-excess-errors "Ignore messages like: errors during merging of translation units|mkoffload returned 1 exit status" }
-- 
2.35.1