Hi!

While on x86_64-linux as well as i686-linux inline_ordered_team_ids
array is long long aligned, on other targets like sparc solaris it is not
due to different sizes of mutexes/pointer locks.  The following patch makes
sure that the memory used for lastprivate conditional is always long long
aligned.

Bootstrapped/regtested on x86_64-linux and i686-linux, additionally Rainer
has kindly tested it on sparc-sun-solaris, committed to trunk.

2019-05-27  Jakub Jelinek  <ja...@redhat.com>

        PR libgomp/90641
        * work.c (gomp_init_work_share): Instead of aligning final ordered
        value to multiples of long long alignment, align to that the
        first part (ordered team ids) and if inline_ordered_team_ids
        is not on a long long alignment boundary within the structure,
        use __alignof__ (long long) - 1 pad size always.
        * loop.c (GOMP_loop_start): Fix *mem computation if
        inline_ordered_team_ids is not aligned on long long alignment boundary
        within the structure.
        * loop-ull.c (GOMP_loop_ull_start): Likewise.
        * sections.c (GOMP_sections2_start): Likewise.

--- libgomp/work.c.jj   2019-01-01 12:38:37.703653396 +0100
+++ libgomp/work.c      2019-05-27 13:49:04.513336631 +0200
@@ -110,9 +110,12 @@ gomp_init_work_share (struct gomp_work_s
 
       if (__builtin_expect (ordered != 1, 0))
        {
-         ordered += nthreads * sizeof (*ws->ordered_team_ids) - 1;
-         ordered = ordered + __alignof__ (long long) - 1;
-         ordered &= ~(__alignof__ (long long) - 1);
+         size_t o = nthreads * sizeof (*ws->ordered_team_ids);
+         o += __alignof__ (long long) - 1;
+         if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+              & (__alignof__ (long long) - 1)) == 0)
+           o &= ~(__alignof__ (long long) - 1);
+         ordered += o - 1;
        }
       else
        ordered = nthreads * sizeof (*ws->ordered_team_ids);
--- libgomp/loop.c.jj   2019-01-01 12:38:37.514656497 +0100
+++ libgomp/loop.c      2019-05-27 14:12:10.355836249 +0200
@@ -267,14 +267,17 @@ GOMP_loop_start (long start, long end, l
       if (mem)
        {
          uintptr_t size = (uintptr_t) *mem;
+#define INLINE_ORDERED_TEAM_IDS_OFF \
+  ((offsetof (struct gomp_work_share, inline_ordered_team_ids)         \
+    + __alignof__ (long long) - 1) & ~(__alignof__ (long long) - 1))
          if (size > (sizeof (struct gomp_work_share)
-                     - offsetof (struct gomp_work_share,
-                                 inline_ordered_team_ids)))
-           thr->ts.work_share->ordered_team_ids
-             = gomp_malloc_cleared (size);
+                     - INLINE_ORDERED_TEAM_IDS_OFF))
+           *mem
+             = (void *) (thr->ts.work_share->ordered_team_ids
+                         = gomp_malloc_cleared (size));
          else
-           memset (thr->ts.work_share->ordered_team_ids, '\0', size);
-         *mem = (void *) thr->ts.work_share->ordered_team_ids;
+           *mem = memset (((char *) thr->ts.work_share)
+                          + INLINE_ORDERED_TEAM_IDS_OFF, '\0', size);
        }
       gomp_work_share_init_done ();
     }
@@ -287,7 +290,18 @@ GOMP_loop_start (long start, long end, l
                                                  first_reductions);
        }
       if (mem)
-       *mem = (void *) thr->ts.work_share->ordered_team_ids;
+       {
+         if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+              & (__alignof__ (long long) - 1)) == 0)
+           *mem = (void *) thr->ts.work_share->ordered_team_ids;
+         else
+           {
+             uintptr_t p = (uintptr_t) thr->ts.work_share->ordered_team_ids;
+             p += __alignof__ (long long) - 1;
+             p &= ~(__alignof__ (long long) - 1);
+             *mem = (void *) p;
+           }
+       }
     }
 
   if (!istart)
--- libgomp/loop_ull.c.jj       2019-01-01 12:38:37.893650279 +0100
+++ libgomp/loop_ull.c  2019-05-27 14:58:23.140888183 +0200
@@ -266,14 +266,17 @@ GOMP_loop_ull_start (bool up, gomp_ull s
       if (mem)
        {
          uintptr_t size = (uintptr_t) *mem;
+#define INLINE_ORDERED_TEAM_IDS_OFF \
+  ((offsetof (struct gomp_work_share, inline_ordered_team_ids)         \
+    + __alignof__ (long long) - 1) & ~(__alignof__ (long long) - 1))
          if (size > (sizeof (struct gomp_work_share)
-                     - offsetof (struct gomp_work_share,
-                                 inline_ordered_team_ids)))
-           thr->ts.work_share->ordered_team_ids
-             = gomp_malloc_cleared (size);
+                     - INLINE_ORDERED_TEAM_IDS_OFF))
+           *mem
+             = (void *) (thr->ts.work_share->ordered_team_ids
+                         = gomp_malloc_cleared (size));
          else
-           memset (thr->ts.work_share->ordered_team_ids, '\0', size);
-         *mem = (void *) thr->ts.work_share->ordered_team_ids;
+           *mem = memset (((char *) thr->ts.work_share)
+                          + INLINE_ORDERED_TEAM_IDS_OFF, '\0', size);
        }
       gomp_work_share_init_done ();
     }
@@ -286,7 +289,18 @@ GOMP_loop_ull_start (bool up, gomp_ull s
                                                  first_reductions);
        }
       if (mem)
-       *mem = (void *) thr->ts.work_share->ordered_team_ids;
+       {
+         if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+              & (__alignof__ (long long) - 1)) == 0)
+           *mem = (void *) thr->ts.work_share->ordered_team_ids;
+         else
+           {
+             uintptr_t p = (uintptr_t) thr->ts.work_share->ordered_team_ids;
+             p += __alignof__ (long long) - 1;
+             p &= ~(__alignof__ (long long) - 1);
+             *mem = (void *) p;
+           }
+       }
     }
 
   return ialias_call (GOMP_loop_ull_runtime_next) (istart, iend);
--- libgomp/sections.c.jj       2019-01-01 12:38:37.770652297 +0100
+++ libgomp/sections.c  2019-05-27 14:59:15.380044507 +0200
@@ -118,14 +118,17 @@ GOMP_sections2_start (unsigned count, ui
       if (mem)
        {
          uintptr_t size = (uintptr_t) *mem;
+#define INLINE_ORDERED_TEAM_IDS_OFF \
+  ((offsetof (struct gomp_work_share, inline_ordered_team_ids)         \
+    + __alignof__ (long long) - 1) & ~(__alignof__ (long long) - 1))
          if (size > (sizeof (struct gomp_work_share)
-                     - offsetof (struct gomp_work_share,
-                                 inline_ordered_team_ids)))
-           thr->ts.work_share->ordered_team_ids
-             = gomp_malloc_cleared (size);
+                     - INLINE_ORDERED_TEAM_IDS_OFF))
+           *mem
+             = (void *) (thr->ts.work_share->ordered_team_ids
+                         = gomp_malloc_cleared (size));
          else
-           memset (thr->ts.work_share->ordered_team_ids, '\0', size);
-         *mem = (void *) thr->ts.work_share->ordered_team_ids;
+           *mem = memset (((char *) thr->ts.work_share)
+                          + INLINE_ORDERED_TEAM_IDS_OFF, '\0', size);
        }
       gomp_work_share_init_done ();
     }
@@ -138,7 +141,18 @@ GOMP_sections2_start (unsigned count, ui
                                                  first_reductions);
        }
       if (mem)
-       *mem = (void *) thr->ts.work_share->ordered_team_ids;
+       {
+         if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+              & (__alignof__ (long long) - 1)) == 0)
+           *mem = (void *) thr->ts.work_share->ordered_team_ids;
+         else
+           {
+             uintptr_t p = (uintptr_t) thr->ts.work_share->ordered_team_ids;
+             p += __alignof__ (long long) - 1;
+             p &= ~(__alignof__ (long long) - 1);
+             *mem = (void *) p;
+           }
+       }
     }
 
 #ifdef HAVE_SYNC_BUILTINS

        Jakub

Reply via email to