]> sourceware.org Git - valgrind.git/commitdiff
Bug 434296 - s390x: Add memcheck test cases for vector string insns
authorAndreas Arnez <arnez@linux.ibm.com>
Fri, 16 Apr 2021 10:44:44 +0000 (12:44 +0200)
committerAndreas Arnez <arnez@linux.ibm.com>
Fri, 7 May 2021 15:16:57 +0000 (17:16 +0200)
Bug 434296 addresses memcheck false positives with the vector string
instructions VISTR, VSTRC, VFAE, VFEE, and VFENE.  Add test cases that
verify the fix for that bug.  Without the fix, memcheck yields many
complains with these tests, most of which are false positives.

14 files changed:
.gitignore
NEWS
memcheck/tests/s390x/Makefile.am
memcheck/tests/s390x/vfae.c [new file with mode: 0644]
memcheck/tests/s390x/vfae.stderr.exp [new file with mode: 0644]
memcheck/tests/s390x/vfae.stdout.exp [new file with mode: 0644]
memcheck/tests/s390x/vfae.vgtest [new file with mode: 0644]
memcheck/tests/s390x/vistr.c [new file with mode: 0644]
memcheck/tests/s390x/vistr.stderr.exp [new file with mode: 0644]
memcheck/tests/s390x/vistr.vgtest [new file with mode: 0644]
memcheck/tests/s390x/vstrc.c [new file with mode: 0644]
memcheck/tests/s390x/vstrc.stderr.exp [new file with mode: 0644]
memcheck/tests/s390x/vstrc.stdout.exp [new file with mode: 0644]
memcheck/tests/s390x/vstrc.vgtest [new file with mode: 0644]

index 7e1b17ab6f8140b73a25663f503d30eec1be7b6b..fddb1e75b7aaec297a4b23ed743c90bbdf0ef868 100644 (file)
 /memcheck/tests/s390x/cu21
 /memcheck/tests/s390x/cu42
 /memcheck/tests/s390x/ltgjhe
+/memcheck/tests/s390x/vstrc
+/memcheck/tests/s390x/vfae
+/memcheck/tests/s390x/vistr
 
 # /memcheck/tests/solaris/
 /memcheck/tests/solaris/*.stderr.diff
diff --git a/NEWS b/NEWS
index a84ee6b730c6f18366f6a753c3590a818d550429..2e8174e6f31787c515ca42070254fc73baf8b536 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,8 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 433801  PPC ISA 3.1 support is missing, part 10 (ISA 3.1 support complete)
 433863  s390x: memcheck/tests/s390x/{cds,cs,csg} failures
 434840  PPC64 darn instruction not supported
+434296  s390x: False-positive memcheck diagnostics from vector string
+        instructions
 
 To see details of a given bug, visit
   https://bugs.kde.org/show_bug.cgi?id=XXXXXX
index e4e69eb38a4c7380633a2adf8b43af3855812f62..d183841ef0bc96c7358832d19ae5d02b8c585f7c 100644 (file)
@@ -2,7 +2,7 @@ include $(top_srcdir)/Makefile.tool-tests.am
 
 dist_noinst_SCRIPTS = filter_stderr
 
-INSN_TESTS = cdsg cu21 cu42 ltgjhe
+INSN_TESTS = cdsg cu21 cu42 ltgjhe vstrc vfae vistr
 
 check_PROGRAMS = $(INSN_TESTS) 
 
@@ -14,3 +14,7 @@ EXTRA_DIST = \
 AM_CFLAGS    += @FLAG_M64@
 AM_CXXFLAGS  += @FLAG_M64@
 AM_CCASFLAGS += @FLAG_M64@
+
+vstrc_CFLAGS  = $(AM_CFLAGS) -march=z13
+vfae_CFLAGS   = $(AM_CFLAGS) -march=z13
+vistr_CFLAGS  = $(AM_CFLAGS) -march=z13
diff --git a/memcheck/tests/s390x/vfae.c b/memcheck/tests/s390x/vfae.c
new file mode 100644 (file)
index 0000000..68781e7
--- /dev/null
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <string.h>
+
+#define VECTOR __attribute__ ((vector_size (16)))
+
+typedef char VECTOR char_v;
+
+volatile char tmp;
+static const char *hex_digit = "0123456789abcdefGHIJKLMNOPQRSTUV";
+
+static char_v to_char_vec(const char *str)
+{
+   char_v v;
+   char buf[17];
+   int len = strlen(str);
+
+   memcpy(buf, str, (len && str[len - 1] == '~') ? len - 1 : len + 1);
+   v = *(char_v *) buf;
+   return v;
+}
+
+#define GENERATE_TEST(mnem)                                          \
+static void test_ ## mnem ## _char(const char *str, const char *match, \
+                                   int expect_res, int expect_cc)    \
+{                                                                    \
+   int cc;                                                           \
+   char_v v1;                                                        \
+   char_v v2 = to_char_vec(str);                                     \
+   char_v v3 = to_char_vec(match);                                   \
+                                                                     \
+   __asm__(                                                          \
+      "cr    0,0\n\t"           /* Clear CC */                       \
+      #mnem "  %[v1],%[v2],%[v3],0,3\n\t"                            \
+      "ipm   %[cc]\n\t"                                              \
+      "srl   %[cc],28"                                               \
+      : [v1] "=v" (v1),                                              \
+        [cc] "=d" (cc)                                               \
+      : [v2] "v" (v2),                                               \
+        [v3] "v" (v3)                                                \
+      : "cc");                                                       \
+                                                                     \
+   tmp = hex_digit[v1[7] & 0x1f];                                    \
+   if (expect_res >= 0  && v1[7] != expect_res)                      \
+      printf("result %u != %d\n", v1[7], expect_res);                \
+                                                                     \
+   tmp = hex_digit[cc & 0xf];                                        \
+   if (expect_cc >= 0 && cc != expect_cc)                            \
+      printf("CC %d != %d\n", cc, expect_cc);                        \
+}
+
+GENERATE_TEST(vfae)
+
+GENERATE_TEST(vfee)
+
+GENERATE_TEST(vfene)
+
+int main()
+{
+   test_vfae_char("not found", "................", 9, 0);
+   test_vfae_char("xy", "zzzzzzzzyyyyyyyy", 1, 2);
+   test_vfae_char("incomplete~", "xxxxxxxxxxxxxxxx", -1, -1);
+
+   test_vfee_char("same char here", "..........here", 10, 2);
+   test_vfee_char("and here too ...", "_________t~", 9, 1);
+   test_vfee_char("equality!~", "========!!~", 8, -1);
+
+   test_vfene_char("strings equal", "strings equal", 13, 0);
+   test_vfene_char(hex_digit, hex_digit, 16, 3);
+   test_vfene_char("undef~", "undefined", -1, -1);
+   test_vfene_char("active~", "actually ok", 3, 1);
+   return 0;
+}
diff --git a/memcheck/tests/s390x/vfae.stderr.exp b/memcheck/tests/s390x/vfae.stderr.exp
new file mode 100644 (file)
index 0000000..8aad3c8
--- /dev/null
@@ -0,0 +1,20 @@
+Use of uninitialised value of size 8
+   at 0x........: test_vfae_char (vfae.c:51)
+   by 0x........: main (vfae.c:61)
+
+Use of uninitialised value of size 8
+   at 0x........: test_vfae_char (vfae.c:51)
+   by 0x........: main (vfae.c:61)
+
+Use of uninitialised value of size 8
+   at 0x........: test_vfee_char (vfae.c:53)
+   by 0x........: main (vfae.c:65)
+
+Use of uninitialised value of size 8
+   at 0x........: test_vfene_char (vfae.c:55)
+   by 0x........: main (vfae.c:69)
+
+Use of uninitialised value of size 8
+   at 0x........: test_vfene_char (vfae.c:55)
+   by 0x........: main (vfae.c:69)
+
diff --git a/memcheck/tests/s390x/vfae.stdout.exp b/memcheck/tests/s390x/vfae.stdout.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/s390x/vfae.vgtest b/memcheck/tests/s390x/vfae.vgtest
new file mode 100644 (file)
index 0000000..ae36c22
--- /dev/null
@@ -0,0 +1,2 @@
+prog: vfae
+vgopts: -q
diff --git a/memcheck/tests/s390x/vistr.c b/memcheck/tests/s390x/vistr.c
new file mode 100644 (file)
index 0000000..7ed59b9
--- /dev/null
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <string.h>
+
+#define VECTOR __attribute__ ((vector_size (16)))
+
+typedef char VECTOR char_v;
+
+volatile char tmp;
+static const char *hex_digit = "0123456789abcdef";
+
+static char_v to_char_vec(const char *str, char_v *maskp)
+{
+   char buf[17];
+   char_v v;
+   char_v mask = {0};
+
+   for (int i = 0; i < sizeof(buf); i++) {
+      char ch = str[i];
+      if (ch == '\0')
+         break;
+      else if (ch == '$') {
+         buf[i] = '\0';
+         mask[i] = -1;
+      } else if (ch != '~') {
+         buf[i] = ch;
+         mask[i] = -1;
+      }
+   }
+   v = *(char_v *) buf;
+   *maskp = mask;
+   return v;
+}
+
+static void test_vistr_char(const char *str, const char *expect_res,
+                            int expect_cc)
+{
+   int cc, count;
+   char_v v1, mask;
+   char_v v2 = to_char_vec(str, &mask);
+   char_v exp_v1 = to_char_vec(expect_res, &mask);
+   char equal[16];
+
+   __asm__(
+      "cr    0,0\n\t"           /* Clear CC */
+      "vistr %[v1],%[v2],0,1\n\t"
+      "ipm   %[cc]\n\t"
+      "srl   %[cc],28"
+      : [v1] "=v" (v1),
+        [cc] "=d" (cc)
+      : [v2] "v" (v2)
+      : "cc");
+
+   *(char_v *) equal = (v1 & mask) == (exp_v1 & mask);
+   if (memchr(equal, 0, sizeof(equal)))
+      printf("Result doesn't match `%s'\n", expect_res);
+
+   count = 0;
+   for (int i = 0; i < 16; i++) {
+      if (v1[i] == 0) count++;
+   }
+   tmp = hex_digit[count];
+
+   tmp = hex_digit[cc & 0xf];
+   if (expect_cc >= 0 && cc != expect_cc)
+      printf("CC %d != %d\n", cc, expect_cc);
+}
+
+int main()
+{
+   test_vistr_char("terminated$====~", "terminated$$$$$$", 0);
+   test_vistr_char("undef~~~~~~~~~~~", "undef", -1);
+   test_vistr_char("undef, 2nd half~", "undef, 2nd half", -1);
+   test_vistr_char("Not. Terminated.", "Not. Terminated.", 3);
+   test_vistr_char("partiallyOK~~$~~", "partiallyOK~~$$$", 0);
+   return 0;
+}
diff --git a/memcheck/tests/s390x/vistr.stderr.exp b/memcheck/tests/s390x/vistr.stderr.exp
new file mode 100644 (file)
index 0000000..e4f35fd
--- /dev/null
@@ -0,0 +1,20 @@
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: test_vistr_char (vistr.c:59)
+   by 0x........: main (vistr.c:71)
+
+Use of uninitialised value of size 8
+   at 0x........: test_vistr_char (vistr.c:63)
+   by 0x........: main (vistr.c:71)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: test_vistr_char (vistr.c:59)
+   by 0x........: main (vistr.c:72)
+
+Use of uninitialised value of size 8
+   at 0x........: test_vistr_char (vistr.c:63)
+   by 0x........: main (vistr.c:72)
+
+Conditional jump or move depends on uninitialised value(s)
+   at 0x........: test_vistr_char (vistr.c:59)
+   by 0x........: main (vistr.c:74)
+
diff --git a/memcheck/tests/s390x/vistr.vgtest b/memcheck/tests/s390x/vistr.vgtest
new file mode 100644 (file)
index 0000000..f99749d
--- /dev/null
@@ -0,0 +1,2 @@
+prog: vistr
+vgopts: -q
diff --git a/memcheck/tests/s390x/vstrc.c b/memcheck/tests/s390x/vstrc.c
new file mode 100644 (file)
index 0000000..268e2f8
--- /dev/null
@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <string.h>
+
+#define VECTOR __attribute__ ((vector_size (16)))
+
+typedef char VECTOR char_v;
+
+struct vstrc_char_rng {
+   unsigned char range[16];
+   unsigned char flags[16];
+};
+
+#define RNG_FLAG_EQ   0x80
+#define RNG_FLAG_LT   0x40
+#define RNG_FLAG_GT   0x20
+#define RNG_FLAG_ANY  0xe0
+#define RNG_FLAG_NONE 0x00
+
+volatile char tmp;
+static const char *hex_digit = "0123456789abcdefGHIJKLMNOPQRSTUV";
+
+static void test_vstrc_char(const char *str, const struct vstrc_char_rng *rng,
+                            int expect_res, int expect_cc)
+{
+   int cc;
+   char_v v1;
+   char_v v2 = *(const char_v *) str;
+   char_v v3 = *(const char_v *) rng->range;
+   char_v v4 = *(const char_v *) rng->flags;
+
+   __asm__(
+      "cr    0,0\n\t"           /* Clear CC */
+      "vstrc %[v1],%[v2],%[v3],%[v4],0,3\n\t"
+      "ipm   %[cc]\n\t"
+      "srl   %[cc],28"
+      : [v1] "=v" (v1),
+        [cc] "=d" (cc)
+      : [v2] "v" (v2),
+        [v3] "v" (v3),
+        [v4] "v" (v4)
+      : "cc");
+
+   tmp = hex_digit[v1[7] & 0x1f];
+   if (expect_res >= 0  && v1[7] != expect_res)
+      printf("result %u != %d\n", v1[7], expect_res);
+
+   tmp = hex_digit[cc & 0xf];
+   if (expect_cc >= 0 && cc != expect_cc)
+      printf("CC %d != %d\n", cc, expect_cc);
+}
+
+int main()
+{
+   struct vstrc_char_rng rng;
+   char buf[16];
+
+   memset(rng.flags, RNG_FLAG_NONE, 16);
+
+   rng.range[4] = 'z';
+   rng.flags[4] = RNG_FLAG_GT | RNG_FLAG_EQ;
+   rng.flags[5] = RNG_FLAG_ANY;
+   /* OK: match at the 'z' */
+   test_vstrc_char("find the z", &rng, 9, 2);
+
+   rng.flags[12] = RNG_FLAG_GT | RNG_FLAG_EQ;
+   rng.flags[13] = RNG_FLAG_LT | RNG_FLAG_EQ;
+   /* Bad: undefined range */
+   test_vstrc_char("undefined", &rng, -1, -1);
+
+   rng.range[12] = 'a';
+   rng.range[13] = 'c';
+   /* OK: match at the 'a' */
+   test_vstrc_char("get the abc", &rng, 8, 2);
+
+   rng.flags[12] = RNG_FLAG_LT;
+   rng.flags[13] = RNG_FLAG_GT;
+   /* OK: no match up to null terminator */
+   test_vstrc_char("no match", &rng, 8, 0);
+
+   /* OK: no match, no null terminator */
+   test_vstrc_char("0123456789abcdef", &rng, 16, 3);
+
+   buf[0] = 'x';
+   /* Bad: undefined string */
+   test_vstrc_char(buf, &rng, -1, -1);
+
+   buf[1] = 'z';
+   /* Bad: valid match, but CC undefined */
+   test_vstrc_char(buf, &rng, 1, -1);
+
+   return 0;
+}
diff --git a/memcheck/tests/s390x/vstrc.stderr.exp b/memcheck/tests/s390x/vstrc.stderr.exp
new file mode 100644 (file)
index 0000000..c1125be
--- /dev/null
@@ -0,0 +1,20 @@
+Use of uninitialised value of size 8
+   at 0x........: test_vstrc_char (vstrc.c:43)
+   by 0x........: main (vstrc.c:68)
+
+Use of uninitialised value of size 8
+   at 0x........: test_vstrc_char (vstrc.c:47)
+   by 0x........: main (vstrc.c:68)
+
+Use of uninitialised value of size 8
+   at 0x........: test_vstrc_char (vstrc.c:43)
+   by 0x........: main (vstrc.c:85)
+
+Use of uninitialised value of size 8
+   at 0x........: test_vstrc_char (vstrc.c:47)
+   by 0x........: main (vstrc.c:85)
+
+Use of uninitialised value of size 8
+   at 0x........: test_vstrc_char (vstrc.c:47)
+   by 0x........: main (vstrc.c:89)
+
diff --git a/memcheck/tests/s390x/vstrc.stdout.exp b/memcheck/tests/s390x/vstrc.stdout.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/s390x/vstrc.vgtest b/memcheck/tests/s390x/vstrc.vgtest
new file mode 100644 (file)
index 0000000..26f5db9
--- /dev/null
@@ -0,0 +1,2 @@
+prog: vstrc
+vgopts: -q
This page took 0.057631 seconds and 5 git commands to generate.