This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][AArch64] Fix strict aliasing issue in gcc.target/aarch64/simd/vminmaxnm_1.c


Hi all,

While doing some unrelated work the gcc.target/aarch64/simd/vminmaxnm_1.c testcase started failing for me.
Upon investigation it turns out that it breaks the C strict aliasing rules in the CHECK macro by casting
a pointer to an incompatible type and dereferencing it. GCC even warns about it if compiled with -Wstrict-aliasing.

This patch fixes the testcase by making it use memcmp to compare the vector elements.
This avoids the undefined behaviour.

The testcase still passes on trunk.
Ok to commit?

Thanks,
Kyrill

2017-07-04  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

    * gcc.target/aarch64/simd/vminmaxnm_1.c: Fix strict aliasing issues.
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/vminmaxnm_1.c b/gcc/testsuite/gcc.target/aarch64/simd/vminmaxnm_1.c
index 192bad9..8fd4281 100644
--- a/gcc/testsuite/gcc.target/aarch64/simd/vminmaxnm_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/simd/vminmaxnm_1.c
@@ -7,12 +7,10 @@
 
 extern void abort ();
 
-#define CHECK(T, N, R, E) \
+#define CHECK(R, E) \
   {\
-    int i = 0;\
-    for (; i < N; i++)\
-      if (* (T *) &R[i] != * (T *) &E[i])\
-	abort ();\
+    if (__builtin_memcmp (&R, &E, sizeof (R)) != 0)\
+      abort ();\
   }
 
 int
@@ -26,8 +24,8 @@ main (int argc, char **argv)
   float32x2_t f32x2_ret_minnm  = vminnm_f32 (f32x2_input1, f32x2_input2);
   float32x2_t f32x2_ret_maxnm  = vmaxnm_f32 (f32x2_input1, f32x2_input2);
 
-  CHECK (uint32_t, 2, f32x2_ret_minnm, f32x2_exp_minnm);
-  CHECK (uint32_t, 2, f32x2_ret_maxnm, f32x2_exp_maxnm);
+  CHECK (f32x2_ret_minnm, f32x2_exp_minnm);
+  CHECK (f32x2_ret_maxnm, f32x2_exp_maxnm);
 
   /* v{min|max}nm_f32 NaN.  */
   f32x2_input1 = vdup_n_f32 (__builtin_nanf (""));
@@ -37,8 +35,8 @@ main (int argc, char **argv)
   f32x2_ret_minnm  = vminnm_f32 (f32x2_input1, f32x2_input2);
   f32x2_ret_maxnm  = vmaxnm_f32 (f32x2_input1, f32x2_input2);
 
-  CHECK (uint32_t, 2, f32x2_ret_minnm, f32x2_exp_minnm);
-  CHECK (uint32_t, 2, f32x2_ret_maxnm, f32x2_exp_maxnm);
+  CHECK (f32x2_ret_minnm, f32x2_exp_minnm);
+  CHECK (f32x2_ret_maxnm, f32x2_exp_maxnm);
 
   /* v{min|max}nmq_f32 normal.  */
   float32x4_t f32x4_input1 = vdupq_n_f32 (-1024.0);
@@ -48,8 +46,8 @@ main (int argc, char **argv)
   float32x4_t f32x4_ret_minnm  = vminnmq_f32 (f32x4_input1, f32x4_input2);
   float32x4_t f32x4_ret_maxnm  = vmaxnmq_f32 (f32x4_input1, f32x4_input2);
 
-  CHECK (uint32_t, 4, f32x4_ret_minnm, f32x4_exp_minnm);
-  CHECK (uint32_t, 4, f32x4_ret_maxnm, f32x4_exp_maxnm);
+  CHECK (f32x4_ret_minnm, f32x4_exp_minnm);
+  CHECK (f32x4_ret_maxnm, f32x4_exp_maxnm);
 
   /* v{min|max}nmq_f32 NaN.  */
   f32x4_input1 = vdupq_n_f32 (-__builtin_nanf (""));
@@ -59,8 +57,8 @@ main (int argc, char **argv)
   f32x4_ret_minnm  = vminnmq_f32 (f32x4_input1, f32x4_input2);
   f32x4_ret_maxnm  = vmaxnmq_f32 (f32x4_input1, f32x4_input2);
 
-  CHECK (uint32_t, 4, f32x4_ret_minnm, f32x4_exp_minnm);
-  CHECK (uint32_t, 4, f32x4_ret_maxnm, f32x4_exp_maxnm);
+  CHECK (f32x4_ret_minnm, f32x4_exp_minnm);
+  CHECK (f32x4_ret_maxnm, f32x4_exp_maxnm);
 
   /* v{min|max}nm_f64 normal.  */
   float64x1_t f64x1_input1 = vdup_n_f64 (1.23);
@@ -69,16 +67,16 @@ main (int argc, char **argv)
   float64x1_t f64x1_exp_maxnm  = vdup_n_f64 (4.56);
   float64x1_t f64x1_ret_minnm  = vminnm_f64 (f64x1_input1, f64x1_input2);
   float64x1_t f64x1_ret_maxnm  = vmaxnm_f64 (f64x1_input1, f64x1_input2);
-  CHECK (uint64_t, 1, f64x1_ret_minnm, f64x1_exp_minnm);
-  CHECK (uint64_t, 1, f64x1_ret_maxnm, f64x1_exp_maxnm);
+  CHECK (f64x1_ret_minnm, f64x1_exp_minnm);
+  CHECK (f64x1_ret_maxnm, f64x1_exp_maxnm);
 
   /* v{min|max}_f64 normal.  */
   float64x1_t f64x1_exp_min  = vdup_n_f64 (1.23);
   float64x1_t f64x1_exp_max  = vdup_n_f64 (4.56);
   float64x1_t f64x1_ret_min  = vmin_f64 (f64x1_input1, f64x1_input2);
   float64x1_t f64x1_ret_max  = vmax_f64 (f64x1_input1, f64x1_input2);
-  CHECK (uint64_t, 1, f64x1_ret_min, f64x1_exp_min);
-  CHECK (uint64_t, 1, f64x1_ret_max, f64x1_exp_max);
+  CHECK (f64x1_ret_min, f64x1_exp_min);
+  CHECK (f64x1_ret_max, f64x1_exp_max);
 
   /* v{min|max}nmq_f64 normal.  */
   float64x2_t f64x2_input1 = vdupq_n_f64 (1.23);
@@ -87,8 +85,8 @@ main (int argc, char **argv)
   float64x2_t f64x2_exp_maxnm  = vdupq_n_f64 (4.56);
   float64x2_t f64x2_ret_minnm  = vminnmq_f64 (f64x2_input1, f64x2_input2);
   float64x2_t f64x2_ret_maxnm  = vmaxnmq_f64 (f64x2_input1, f64x2_input2);
-  CHECK (uint64_t, 2, f64x2_ret_minnm, f64x2_exp_minnm);
-  CHECK (uint64_t, 2, f64x2_ret_maxnm, f64x2_exp_maxnm);
+  CHECK (f64x2_ret_minnm, f64x2_exp_minnm);
+  CHECK (f64x2_ret_maxnm, f64x2_exp_maxnm);
 
   /* v{min|max}nm_f64 NaN.  */
   f64x1_input1 = vdup_n_f64 (-__builtin_nanf (""));
@@ -98,8 +96,8 @@ main (int argc, char **argv)
   f64x1_ret_minnm  = vminnm_f64 (f64x1_input1, f64x1_input2);
   f64x1_ret_maxnm  = vmaxnm_f64 (f64x1_input1, f64x1_input2);
 
-  CHECK (uint64_t, 1, f64x1_ret_minnm, f64x1_exp_minnm);
-  CHECK (uint64_t, 1, f64x1_ret_maxnm, f64x1_exp_maxnm);
+  CHECK (f64x1_ret_minnm, f64x1_exp_minnm);
+  CHECK (f64x1_ret_maxnm, f64x1_exp_maxnm);
 
   /* v{min|max}_f64 NaN.  */
   f64x1_input1 = vdup_n_f64 (-__builtin_nanf (""));
@@ -109,8 +107,8 @@ main (int argc, char **argv)
   f64x1_ret_minnm  = vmin_f64 (f64x1_input1, f64x1_input2);
   f64x1_ret_maxnm  = vmax_f64 (f64x1_input1, f64x1_input2);
 
-  CHECK (uint64_t, 1, f64x1_ret_minnm, f64x1_exp_minnm);
-  CHECK (uint64_t, 1, f64x1_ret_maxnm, f64x1_exp_maxnm);
+  CHECK (f64x1_ret_minnm, f64x1_exp_minnm);
+  CHECK (f64x1_ret_maxnm, f64x1_exp_maxnm);
 
   /* v{min|max}nmq_f64 NaN.  */
   f64x2_input1 = vdupq_n_f64 (-__builtin_nan (""));
@@ -120,8 +118,8 @@ main (int argc, char **argv)
   f64x2_ret_minnm  = vminnmq_f64 (f64x2_input1, f64x2_input2);
   f64x2_ret_maxnm  = vmaxnmq_f64 (f64x2_input1, f64x2_input2);
 
-  CHECK (uint64_t, 2, f64x2_ret_minnm, f64x2_exp_minnm);
-  CHECK (uint64_t, 2, f64x2_ret_maxnm, f64x2_exp_maxnm);
+  CHECK (f64x2_ret_minnm, f64x2_exp_minnm);
+  CHECK (f64x2_ret_maxnm, f64x2_exp_maxnm);
 
   return 0;
 }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]