On 7/20/21 2:40 AM, Thomas Schwinge wrote:
Hi!

On 2021-07-20T09:23:24+0200, I wrote:
On 2021-07-19T10:46:35+0200, I wrote:
| On 7/16/21 11:42 AM, Thomas Schwinge wrote:
|> On 2021-07-09T17:11:25-0600, Martin Sebor via Gcc-patches 
<gcc-patches@gcc.gnu.org> wrote:
|>> The attached tweak avoids the new -Warray-bounds instances when
|>> building libatomic for arm. Christophe confirms it resolves
|>> the problem (thank you!)
|>
|> As Abid has just reported in
|> <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101374#c16>, similar
|> problem with GCN target libgomp build:
|>
|>      In function ‘gcn_thrs’,
|>          inlined from ‘gomp_thread’ at 
[...]/source-gcc/libgomp/libgomp.h:803:10,
|>          inlined from ‘GOMP_barrier’ at 
[...]/source-gcc/libgomp/barrier.c:34:29:
|>      [...]/source-gcc/libgomp/libgomp.h:792:10: error: array subscript 0 is 
outside array bounds of ‘__lds struct gomp_thread * __lds[0]’ 
[-Werror=array-bounds]
|>        792 |   return *thrs;
|>            |          ^~~~~
|>
|>      gcc/config/gcn/gcn.h:  c_register_addr_space ("__lds", ADDR_SPACE_LDS); 
                  \
|>
|>      libgomp/libgomp.h-static inline struct gomp_thread *gcn_thrs (void)
|>      libgomp/libgomp.h-{
|>      libgomp/libgomp.h-  /* The value is at the bottom of LDS.  */
|>      libgomp/libgomp.h:  struct gomp_thread * __lds *thrs = (struct 
gomp_thread * __lds *)4;
|>      libgomp/libgomp.h-  return *thrs;
|>      libgomp/libgomp.h-}
|>
|> ..., plus a few more.  Work-around:
|>
|>         struct gomp_thread * __lds *thrs = (struct gomp_thread * __lds *)4;
|>      +# pragma GCC diagnostic push
|>      +# pragma GCC diagnostic ignored "-Warray-bounds"
|>         return *thrs;
|>      +# pragma GCC diagnostic pop
|>
|> ..., but it's a bit tedious to add that in all that the other places,
|> too.

Wasn't so bad after all; a lot of duplicates due to 'libgomp.h'.  I've
thus pushed "[gcn] Work-around libgomp 'error: array subscript 0 is
outside array bounds of ‘__lds struct gomp_thread * __lds[0]’
[-Werror=array-bounds]' [PR101484]" to master branch in commit
9f2bc5077debef2b046b6c10d38591ac324ad8b5, see attached.

As I should find, these '#pragma GCC diagnostic [...]' directives cause
some code generation changes (that seems unexpected, problematic!).
(Martin, any idea?  Might be a pre-existing problem, of course.)

OK, phew.  Martin: your diagnostic changes are *not* to be blamed for
code generation changes -- it's my '#pragma GCC diagnostic pop'
placement that triggers:

This
results in a lot (ten thousands) of 'GCN team arena exhausted' run-time
diagnostics, also leading to a few FAILs:

     PASS: libgomp.c/../libgomp.c-c++-common/for-11.c (test for excess errors)
     [-PASS:-]{+FAIL:+} libgomp.c/../libgomp.c-c++-common/for-11.c execution 
test

     PASS: libgomp.c/../libgomp.c-c++-common/for-12.c (test for excess errors)
     [-PASS:-]{+FAIL:+} libgomp.c/../libgomp.c-c++-common/for-12.c execution 
test

     PASS: libgomp.c/../libgomp.c-c++-common/for-3.c (test for excess errors)
     [-PASS:-]{+FAIL:+} libgomp.c/../libgomp.c-c++-common/for-3.c execution test

     PASS: libgomp.c/../libgomp.c-c++-common/for-5.c (test for excess errors)
     [-PASS:-]{+FAIL:+} libgomp.c/../libgomp.c-c++-common/for-5.c execution test

     PASS: libgomp.c/../libgomp.c-c++-common/for-6.c (test for excess errors)
     [-PASS:-]{+FAIL:+} libgomp.c/../libgomp.c-c++-common/for-6.c execution test

     PASS: libgomp.c/../libgomp.c-c++-common/for-9.c (test for excess errors)
     [-PASS:-]{+FAIL:+} libgomp.c/../libgomp.c-c++-common/for-9.c execution test

Same for 'libgomp.c++'.

It remains to be analyzed how '#pragma GCC diagnostic [...]' directives
can cause code generation changes; for now I'm working around the
"unexpected" '-Werror=array-bounds' diagnostics differently:

In addition to a few in straight-line code, I also had these two:

--- a/libgomp/libgomp.h
+++ b/libgomp/libgomp.h
@@ -128,7 +128,10 @@ team_malloc (size_t size)
         : "=v"(result) : "v"(TEAM_ARENA_FREE), "v"(size), "e"(1L) : "memory");

    /* Handle OOM.  */
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Warray-bounds" /*TODO PR101484 */
    if (result + size > *(void * __lds *)TEAM_ARENA_END)
+# pragma GCC diagnostic pop
      {
        /* While this is experimental, let's make sure we know when OOM
        happens.  */
@@ -162,8 +159,11 @@ team_free (void *ptr)
       However, if we fell back to using heap then we should free it.
       It would be better if this function could be a no-op, but at least
       LDS loads are cheap.  */
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Warray-bounds" /*TODO PR101484 */
    if (ptr < *(void * __lds *)TEAM_ARENA_START
        || ptr >= *(void * __lds *)TEAM_ARENA_END)
+# pragma GCC diagnostic pop
      free (ptr);
  }
  #else

..., and it appears that the '#pragma GCC diagnostic pop' are considered
here to be the 'statement' of the 'if'!  That's (a) unexpected (to me, at
least) for this kind of "non-executable" '#pragma', and (b) certainly
would be worth a dignostic, like we have for OMP pragmas, for example:

     if (context == pragma_stmt)
       {
         error_at (loc, "%<#pragma %s%> may only be used in compound 
statements",
                   "[...]");


I agree, that does seem quite surprising.  I opened pr101538 only
to find that the problem is already tracked in pr63326.

Addressing that is for another day.

David Malcolm (CC'd) has a patch attached to pr63326 to issue
a warning to point out that #pragmas are treated as statements
that would help prevent this type of a bug.  David, do you still
plan to submit it?

Martin

Reply via email to