]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
arm64 regtest: add 2 tests for bug489338
authorPaul Floyd <pjfloyd@wanadoo.fr>
Mon, 1 Jul 2024 06:24:39 +0000 (08:24 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Mon, 1 Jul 2024 06:24:39 +0000 (08:24 +0200)
.gitignore
NEWS
none/tests/arm64/Makefile.am
none/tests/arm64/bug489338.c [new file with mode: 0644]
none/tests/arm64/bug489338.stderr.exp [new file with mode: 0644]
none/tests/arm64/bug489338.stdout.exp [new file with mode: 0644]
none/tests/arm64/bug489338.vgtest [new file with mode: 0644]
none/tests/arm64/fcvta_s_u.cpp [new file with mode: 0644]
none/tests/arm64/fcvta_s_u.stderr.exp [new file with mode: 0644]
none/tests/arm64/fcvta_s_u.vgtest [new file with mode: 0644]

index ae366c54445e13c6c541e710ab0447884fe4a870..33e71c133fa8817a68be4cf3e17fe0fb47828aac 100644 (file)
 /none/tests/arm64/allexec
 /none/tests/arm64/atomics_v81
 /none/tests/arm64/bug484426
+/none/tests/arm64/bug489338
 /none/tests/arm64/crc32
 /none/tests/arm64/cvtf_imm
 /none/tests/arm64/dc_cvax
+/none/tests/arm64/fcvta_s_u
 /none/tests/arm64/fmadd_sub
 /none/tests/arm64/fp_and_simd
 /none/tests/arm64/fp_and_simd_v82
diff --git a/NEWS b/NEWS
index d860bd07b2412614fcb78544d81dde6df13e9870..87aa1bd7dd37a2d38adfaf8cb37f839d55aad3a3 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -53,6 +53,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 488441  Add tests for --track-fds=yes --xml=yes and fd suppression tests
 489040  massif trace change to show the location increasing the stack
 489088  Valgrind throws unhandled instruction bytes: 0xC5 0x79 0xD6 0xE0 0xC5
+489338  arm64: Instruction fcvtas should round 322.5 to 323, but result is 322.
 
 To see details of a given bug, visit
   https://bugs.kde.org/show_bug.cgi?id=XXXXXX
index 071cce0057c21b36ddd24a8b104d19205934bf9f..8e57118e31ca5ec818e0736c45cf62f66cc937ae 100644 (file)
@@ -5,9 +5,11 @@ dist_noinst_SCRIPTS = filter_stderr filter_nan
 
 EXTRA_DIST = \
        bug484426.stdout.exp bug484426.stderr.exp bug484426.vgtest \
-        crc32.stdout.exp crc32.stderr.exp crc32.vgtest \
-        cvtf_imm.stdout.exp cvtf_imm.stderr.exp cvtf_imm.vgtest \
-        dc_cvax.vgtest dc_cvax.stderr.exp \
+       bug489338.stdout.exp bug489338.stderr.exp bug489338.vgtest \
+       crc32.stdout.exp crc32.stderr.exp crc32.vgtest \
+       cvtf_imm.stdout.exp cvtf_imm.stderr.exp cvtf_imm.vgtest \
+       dc_cvax.vgtest dc_cvax.stderr.exp \
+       fcvta_s_u.vgtest fcvta_s_u.stderr.exp \
        fp_and_simd.stdout.exp fp_and_simd.stderr.exp fp_and_simd.vgtest \
        frinta_frintn.stderr.exp frinta_frintn.vgtest \
        integer.stdout.exp integer.stderr.exp integer.vgtest \
@@ -16,7 +18,7 @@ EXTRA_DIST = \
        atomics_v81.stdout.exp atomics_v81.stderr.exp atomics_v81.vgtest \
        simd_v81.stdout.exp simd_v81.stderr.exp simd_v81.vgtest \
        simd_dotprod.stdout.exp simd_dotprod.stderr.exp simd_dotprod.vgtest \
-        fmadd_sub.stdout.exp fmadd_sub.stderr.exp fmadd_sub.vgtest \
+       fmadd_sub.stdout.exp fmadd_sub.stderr.exp fmadd_sub.vgtest \
        fp_and_simd_v82.stdout.exp fp_and_simd_v82.stderr.exp \
        fp_and_simd_v82.vgtest \
        ldxp_stxp_basisimpl.stdout.exp ldxp_stxp_basisimpl.stderr.exp \
@@ -28,6 +30,7 @@ EXTRA_DIST = \
 check_PROGRAMS = \
        allexec \
        bug484426 \
+       bug489338 \
         cvtf_imm \
         dc_cvax \
        fp_and_simd \
@@ -53,7 +56,7 @@ if HAVE_SHA3
 endif
 
 if HAVE_CXX17
-  check_PROGRAMS += frinta_frintn
+  check_PROGRAMS += fcvta_s_u frinta_frintn
 endif
 
 if BUILD_ARMV82_DOTPROD_TESTS
@@ -78,6 +81,8 @@ fp_and_simd_v82_CFLAGS = $(AM_CFLAGS) -march=armv8.2-a+fp16+crypto
 # SHA-512 is not part of SHA-3, either as an algorithm or in Arm features, but
 # GCC lumps SHA-512 and SHA-3 extensions together as "sha3".
 sha512_v82_CFLAGS = $(AM_CFLAGS) -march=armv8.2-a+sha3
+fcvta_s_u_SOURCES  = fcvta_s_u.cpp
+fcvta_s_u_CXXFLAGS = ${AM_CXXFLAGS} -std=c++17
 frinta_frintn_SOURCES  = frinta_frintn.cpp
 frinta_frintn_CXXFLAGS = ${AM_CXXFLAGS} -std=c++17
 integer_CFLAGS     = $(AM_CFLAGS) -g -O0 -DTEST_BFM=0
diff --git a/none/tests/arm64/bug489338.c b/none/tests/arm64/bug489338.c
new file mode 100644 (file)
index 0000000..481d744
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+cat fp-valgrind-test.c
+gcc -g -O2 fp-valgrind-test.c -o fp-valgrind-test
+./fp-valgrind-test
+valgrind ./fp-valgrind-test
+gdb -q --args ./fp-valgrind-test
+disassemble main
+q
+*/
+
+#include <stdio.h>
+#include <math.h>
+
+double value(int s)
+{
+  switch (s) {
+    case 0:  return -322.500001; break;
+    case 1:  return -322.5;       break;
+    case 2:  return -322.499999; break;
+    case 3:  return  322.499999; break;
+    case 4:  return  322.5;       break;
+    default: return  322.500001; break;
+  }
+}
+
+int main()
+{
+  for (int i = 0; i < 6; i++) {
+    volatile double a = value(i);
+    int b = (int)round(a);
+    printf("i=%d a=%f a=0x%llx b=%d\n", i, a, *(long long unsigned int*)&a, b);
+  }
+}
diff --git a/none/tests/arm64/bug489338.stderr.exp b/none/tests/arm64/bug489338.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/arm64/bug489338.stdout.exp b/none/tests/arm64/bug489338.stdout.exp
new file mode 100644 (file)
index 0000000..a26feaa
--- /dev/null
@@ -0,0 +1,6 @@
+i=0 a=-322.500001 a=0xc0742800010c6f7a b=-323
+i=1 a=-322.500000 a=0xc074280000000000 b=-323
+i=2 a=-322.499999 a=0xc07427fffef39086 b=-322
+i=3 a=322.499999 a=0x407427fffef39086 b=322
+i=4 a=322.500000 a=0x4074280000000000 b=323
+i=5 a=322.500001 a=0x40742800010c6f7a b=323
diff --git a/none/tests/arm64/bug489338.vgtest b/none/tests/arm64/bug489338.vgtest
new file mode 100644 (file)
index 0000000..80f0b39
--- /dev/null
@@ -0,0 +1,2 @@
+prog: bug489338
+vgopts: -q
diff --git a/none/tests/arm64/fcvta_s_u.cpp b/none/tests/arm64/fcvta_s_u.cpp
new file mode 100644 (file)
index 0000000..4bd5681
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * An extra testcase for bug489338
+ * The testcase supplied only tests op-codes used by round()
+ */
+
+#include <type_traits>
+#include <cassert>
+#include <iostream>
+
+template<typename T, typename U>
+void test_fcvtas(T input, U expected)
+{
+   U result;
+   U* rp(&result);
+   T* ip(&input);
+   if constexpr (std::is_same_v<double, T> == true)
+   {
+      if constexpr (std::is_same_v<long, U> == true)
+      {
+         // double to long
+         __asm__ __volatile__(
+            "ldr d0, [%1];\n"
+            "fcvtas x0, d0;\n"
+            "str x0, [%0];\n"
+            : "+rm" (rp)
+            : "r" (ip)
+            : "memory", "d0", "x0");
+          assert(result == expected);
+      }
+      else
+      {
+         // double to int
+         __asm__ __volatile__(
+            "ldr d0, [%1];\n"
+            "fcvtas w0, d0;\n"
+            "str w0, [%0];\n"
+            : "+rm" (rp)
+            : "r" (ip)
+            : "memory", "d0", "x0");
+          assert(result == expected);
+      }
+   }
+   else
+   {
+      if constexpr (std::is_same_v<long, U> == true)
+      {
+         // float to long
+         __asm__ __volatile__(
+            "ldr s0, [%1];\n"
+            "fcvtas x0, s0;\n"
+            "str x0, [%0];\n"
+            : "+rm" (rp)
+            : "r" (ip)
+            : "memory", "s0", "x0");
+          assert(result == expected);
+      }
+      else
+      {
+         // float to int
+         __asm__ __volatile__(
+            "ldr s0, [%1];\n"
+            "fcvtas w0, s0;\n"
+            "str w0, [%0];\n"
+            : "+rm" (rp)
+            : "r" (ip)
+            : "memory", "s0", "w0");
+          assert(result == expected);
+      }
+   }
+}
+
+template<typename T, typename U>
+void test_fcvtau(T input, U expected)
+{
+   U result;
+   U* rp(&result);
+   T* ip(&input);
+   if constexpr (std::is_same_v<double, T> == true)
+   {
+      if constexpr (std::is_same_v<unsigned long, U> == true)
+      {
+         // double to unsigned long
+         __asm__ __volatile__(
+            "ldr d0, [%1];\n"
+            "fcvtau x0, d0;\n"
+            "str x0, [%0];\n"
+            : "+rm" (rp)
+            : "r" (ip)
+            : "memory", "d0", "x0");
+          assert(result == expected);
+      }
+      else
+      {
+         // double to unsigned int
+         __asm__ __volatile__(
+            "ldr d0, [%1];\n"
+            "fcvtau w0, d0;\n"
+            "str w0, [%0];\n"
+            : "+rm" (rp)
+            : "r" (ip)
+            : "memory", "d0", "w0");
+          assert(result == expected);
+      }
+   }
+   else
+   {
+      if constexpr (std::is_same_v<unsigned long, U> == true)
+      {
+         // float to unsigned long
+         __asm__ __volatile__(
+            "ldr s0, [%1];\n"
+            "fcvtau x0, s0;\n"
+            "str x0, [%0];\n"
+            : "+rm" (rp)
+            : "r" (ip)
+            : "memory", "s0", "x0");
+          assert(result == expected);
+      }
+      else
+      {
+         // float to unsigned int
+         __asm__ __volatile__(
+            "ldr s0, [%1];\n"
+            "fcvtau w0, s0;\n"
+            "str w0, [%0];\n"
+            : "+rm" (rp)
+            : "r" (ip)
+            : "memory", "s0", "w0");
+          assert(result == expected);
+      }
+   }
+}
+
+
+int main()
+{
+    // round "away from zero"
+    test_fcvtas(1.5, 2L);
+    test_fcvtas(2.5, 3L);
+    test_fcvtas(-1.5, -2L);
+    test_fcvtas(-2.5, -3L);
+    test_fcvtas(0.0, 0L);
+
+    test_fcvtas(1.5, 2);
+    test_fcvtas(2.5, 3);
+    test_fcvtas(-1.5, -2);
+    test_fcvtas(-2.5, -3);
+    test_fcvtas(0.0, 0);
+
+    test_fcvtas(1.5F, 2L);
+    test_fcvtas(2.5F, 3L);
+    test_fcvtas(-1.5F, -2L);
+    test_fcvtas(-2.5F, -3L);
+    test_fcvtas(0.0F, 0L);
+
+    test_fcvtas(1.5F, 2);
+    test_fcvtas(2.5F, 3);
+    test_fcvtas(-1.5F, -2);
+    test_fcvtas(-2.5F, -3);
+    test_fcvtas(0.0F, 0);
+
+    test_fcvtau(1.5, 2UL);
+    test_fcvtau(2.5, 3UL);
+    test_fcvtau(0.0, 0UL);
+
+    test_fcvtau(1.5, 2U);
+    test_fcvtau(2.5, 3U);
+    test_fcvtau(0.0, 0U);
+
+    test_fcvtau(1.5F, 2UL);
+    test_fcvtau(2.5F, 3UL);
+    test_fcvtau(0.0F, 0UL);
+
+    test_fcvtau(1.5F, 2U);
+    test_fcvtau(2.5F, 3U);
+    test_fcvtau(0.0F, 0U);
+}
+
diff --git a/none/tests/arm64/fcvta_s_u.stderr.exp b/none/tests/arm64/fcvta_s_u.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/none/tests/arm64/fcvta_s_u.vgtest b/none/tests/arm64/fcvta_s_u.vgtest
new file mode 100644 (file)
index 0000000..f3454b5
--- /dev/null
@@ -0,0 +1,2 @@
+prog: fcvta_s_u
+vgopts: -q