From 32312d588b77c5b5b5a0145bb0cc6f795b447790 Mon Sep 17 00:00:00 2001 From: Andreas Arnez Date: Fri, 16 Apr 2021 12:44:44 +0200 Subject: [PATCH] Bug 434296 - s390x: Add memcheck test cases for vector string insns 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. --- .gitignore | 3 + NEWS | 2 + memcheck/tests/s390x/Makefile.am | 6 +- memcheck/tests/s390x/vfae.c | 72 +++++++++++++++++++++ memcheck/tests/s390x/vfae.stderr.exp | 20 ++++++ memcheck/tests/s390x/vfae.stdout.exp | 0 memcheck/tests/s390x/vfae.vgtest | 2 + memcheck/tests/s390x/vistr.c | 76 ++++++++++++++++++++++ memcheck/tests/s390x/vistr.stderr.exp | 20 ++++++ memcheck/tests/s390x/vistr.vgtest | 2 + memcheck/tests/s390x/vstrc.c | 92 +++++++++++++++++++++++++++ memcheck/tests/s390x/vstrc.stderr.exp | 20 ++++++ memcheck/tests/s390x/vstrc.stdout.exp | 0 memcheck/tests/s390x/vstrc.vgtest | 2 + 14 files changed, 316 insertions(+), 1 deletion(-) create mode 100644 memcheck/tests/s390x/vfae.c create mode 100644 memcheck/tests/s390x/vfae.stderr.exp create mode 100644 memcheck/tests/s390x/vfae.stdout.exp create mode 100644 memcheck/tests/s390x/vfae.vgtest create mode 100644 memcheck/tests/s390x/vistr.c create mode 100644 memcheck/tests/s390x/vistr.stderr.exp create mode 100644 memcheck/tests/s390x/vistr.vgtest create mode 100644 memcheck/tests/s390x/vstrc.c create mode 100644 memcheck/tests/s390x/vstrc.stderr.exp create mode 100644 memcheck/tests/s390x/vstrc.stdout.exp create mode 100644 memcheck/tests/s390x/vstrc.vgtest diff --git a/.gitignore b/.gitignore index 7e1b17ab6f..fddb1e75b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1118,6 +1118,9 @@ /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 a84ee6b730..2e8174e6f3 100644 --- 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 diff --git a/memcheck/tests/s390x/Makefile.am b/memcheck/tests/s390x/Makefile.am index e4e69eb38a..d183841ef0 100644 --- a/memcheck/tests/s390x/Makefile.am +++ b/memcheck/tests/s390x/Makefile.am @@ -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 index 0000000000..68781e7fb7 --- /dev/null +++ b/memcheck/tests/s390x/vfae.c @@ -0,0 +1,72 @@ +#include +#include + +#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 index 0000000000..8aad3c87f8 --- /dev/null +++ b/memcheck/tests/s390x/vfae.stderr.exp @@ -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 index 0000000000..e69de29bb2 diff --git a/memcheck/tests/s390x/vfae.vgtest b/memcheck/tests/s390x/vfae.vgtest new file mode 100644 index 0000000000..ae36c22fe5 --- /dev/null +++ b/memcheck/tests/s390x/vfae.vgtest @@ -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 index 0000000000..7ed59b94b8 --- /dev/null +++ b/memcheck/tests/s390x/vistr.c @@ -0,0 +1,76 @@ +#include +#include + +#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 index 0000000000..e4f35fd749 --- /dev/null +++ b/memcheck/tests/s390x/vistr.stderr.exp @@ -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 index 0000000000..f99749d85a --- /dev/null +++ b/memcheck/tests/s390x/vistr.vgtest @@ -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 index 0000000000..268e2f8586 --- /dev/null +++ b/memcheck/tests/s390x/vstrc.c @@ -0,0 +1,92 @@ +#include +#include + +#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 index 0000000000..c1125bea15 --- /dev/null +++ b/memcheck/tests/s390x/vstrc.stderr.exp @@ -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 index 0000000000..e69de29bb2 diff --git a/memcheck/tests/s390x/vstrc.vgtest b/memcheck/tests/s390x/vstrc.vgtest new file mode 100644 index 0000000000..26f5db99bd --- /dev/null +++ b/memcheck/tests/s390x/vstrc.vgtest @@ -0,0 +1,2 @@ +prog: vstrc +vgopts: -q -- 2.47.2