]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 502288 - s390x: Fix false positive with NNPA pad elements
authorAndreas Arnez <arnez@linux.ibm.com>
Tue, 1 Apr 2025 15:21:16 +0000 (17:21 +0200)
committerAndreas Arnez <arnez@linux.ibm.com>
Tue, 1 Apr 2025 15:21:16 +0000 (17:21 +0200)
The size of the non-pad elements in the last dimension of NNPA tensors is
computed incorrectly.  This can lead to memcheck false positives that look
like this:

==3180208== Syscall param NNPA(in_tensor_1) points to uninitialised byte(s)

Fix the computation.

NEWS
coregrind/m_extension/extension-s390x.c

diff --git a/NEWS b/NEWS
index b2036da737c66dae4098ba29ce8028e335f592a8..7f1d4246c38edaee11be14a288124d1db7d89483 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -72,6 +72,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 501850  FreeBSD syscall arguments 7 and 8 incorrect.
 501893  Missing suppression for __wcscat_avx2 (strcat-strlen-avx2.h.S:68)?
 502126  glibc 2.41 extra syscall_cancel frames
+502288  s390x: Memcheck false positives with NNPA last tensor dimension
 
 To see details of a given bug, visit
   https://bugs.kde.org/show_bug.cgi?id=XXXXXX
index 8a17c6fbddef5a9dbbeaa7d0546c13a783fbf957..5751afc87bbf5d6c8e1dd524b3ce27c97874ea4a 100644 (file)
@@ -417,9 +417,11 @@ static const char* const s390_NNPA_errmsg_access[s390_NNPA_message_n] = {
 };
 
 struct s390_NNPA_mem_dimensions {
+   UChar layout;
    ULong dim[5];  // total dimensions
-   ULong used[5]; // used dimensions, without padding
+   ULong used[4]; // used dimensions, without padding
    ULong step[5];
+   ULong last_dim4_size;
 };
 
 /* Determine the 5 dimensions used to represent the tensor data in memory */
@@ -431,6 +433,7 @@ NNPA_tensor0_size(const struct s390_NNPA_tensor0*  t,
    struct s390_NNPA_mem_dimensions md;
    ULong                           elem_size;
 
+   md.layout = t->layout;
    if (t->dtype == 0)
       elem_size = 2;
    else
@@ -444,7 +447,7 @@ NNPA_tensor0_size(const struct s390_NNPA_tensor0*  t,
       md.dim[3]              = (t->dim2 + 31) / 32 * 32;
       md.used[3]             = t->dim2;
       md.dim[4]              = 64;
-      md.used[4]             = t->dim1;
+      md.last_dim4_size      = elem_size * (t->dim1 % 64);
       break;
    case 1: // 4D-kernel tensor
       md.dim[0] = md.used[0] = (t->dim1 + 63) / 64;
@@ -453,7 +456,7 @@ NNPA_tensor0_size(const struct s390_NNPA_tensor0*  t,
       md.dim[3]              = (t->dim2 + 31) / 32 * 32;
       md.used[3]             = t->dim2;
       md.dim[4]              = 64;
-      md.used[4]             = t->dim1;
+      md.last_dim4_size      = elem_size * (t->dim1 % 64);
       break;
    default:
       return INSN_ERR(s390_NNPA_errmsg_layout[msg_idx]);
@@ -467,6 +470,20 @@ NNPA_tensor0_size(const struct s390_NNPA_tensor0*  t,
    return ExtErr_OK;
 }
 
+/* Determine the size of the non-pad elements in the last dimension */
+static ULong NNPA_mem_dim4_size(const struct s390_NNPA_mem_dimensions* md,
+                                ULong                                  d0,
+                                ULong                                  d1)
+{
+   switch (md->layout) {
+   case 0: // 4D-feature tensor
+      return d1 + 1 == md->dim[1] ? md->last_dim4_size : md->step[4];
+   case 1: // 4D-kernel tensor
+      return d0 + 1 == md->dim[0] ? md->last_dim4_size : md->step[4];
+   }
+   return 0;
+}
+
 static enum ExtensionError NNPA_pre_read_tensor0(
    ThreadState* tst, UInt msg_idx, const struct s390_NNPA_tensor0* t)
 {
@@ -483,8 +500,8 @@ static enum ExtensionError NNPA_pre_read_tensor0(
             for (ULong d3 = 0; d3 < md.used[3]; d3++) {
                ULong addr = t->address + d0 * md.step[1] + d1 * md.step[2] +
                             d2 * md.step[3] + d3 * md.step[4];
-               PRE_MEM_READ(tst, s390_NNPA_errmsg_access[msg_idx], addr,
-                            md.dim[4]);
+               ULong len = NNPA_mem_dim4_size(&md, d0, d1);
+               PRE_MEM_READ(tst, s390_NNPA_errmsg_access[msg_idx], addr, len);
             }
          }
       }
@@ -524,7 +541,8 @@ static void NNPA_post_write_tensor0(ThreadState*                    tst,
             for (ULong d3 = 0; d3 < md.used[3]; d3++) {
                ULong addr = t->address + d0 * md.step[1] + d1 * md.step[2] +
                             d2 * md.step[3] + d3 * md.step[4];
-               POST_MEM_WRITE(tst, addr, md.dim[4]);
+               ULong len = NNPA_mem_dim4_size(&md, d0, d1);
+               POST_MEM_WRITE(tst, addr, len);
             }
          }
       }