Hello,

Test gcc.c-torture/execute/ieee/pr72824-2.c fails for arm targets
because the code generated to move a vector of signed and unsigned zeros
treats it as a vector of unsigned zeros.

That is, an assignment x = { 0.f, -0.f, 0.f, -0.f } is treated as the
assignment x = { 0.f, 0.f, 0.f, 0.f }.

This is due to config/arm/arm.c/neon_valid_immediate using real_equal to
compare the vector elements. This patch replaces the check, using
const_vec_duplicate_p instead. It doesn't add a new test because
pr72824-2.c is enough to check the behaviour.

Tested for arm-none-linux-gnueabihf with native bootstrap and make check
and for arm-none-eabi with cross-compiled check-gcc.

2016-08-19  Matthew Wahab  <matthew.wa...@arm.com>

        PR target/77281
        * config/arm/arm.c (neon_valid_immediate): Delete declaration.
        Use const_vec_duplicate to check for duplicated elements.

Ok for trunk?
Matthew
>From 90c1c86b7a3d8bc6ac07363aea5fba8f29ef3e96 Mon Sep 17 00:00:00 2001
From: Matthew Wahab <matthew.wa...@arm.com>
Date: Wed, 17 Aug 2016 14:43:48 +0100
Subject: [PATCH] [ARM] Fix a wrong test for vectors of the same constants.

---
 gcc/config/arm/arm.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a6afdcc..c1d010c 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -12471,7 +12471,6 @@ neon_valid_immediate (rtx op, machine_mode mode, int inverse,
   if (GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
     {
       rtx el0 = CONST_VECTOR_ELT (op, 0);
-      const REAL_VALUE_TYPE *r0;
 
       if (!vfp3_const_double_rtx (el0) && el0 != CONST0_RTX (GET_MODE (el0)))
         return -1;
@@ -12480,14 +12479,10 @@ neon_valid_immediate (rtx op, machine_mode mode, int inverse,
       if (GET_MODE_INNER (mode) == HFmode)
 	return -1;
 
-      r0 = CONST_DOUBLE_REAL_VALUE (el0);
-
-      for (i = 1; i < n_elts; i++)
-        {
-          rtx elt = CONST_VECTOR_ELT (op, i);
-          if (!real_equal (r0, CONST_DOUBLE_REAL_VALUE (elt)))
-            return -1;
-        }
+      /* All elements in the vector must be the same.  Note that 0.0 and -0.0
+	 are distinct in this context.  */
+      if (!const_vec_duplicate_p (op))
+	return -1;
 
       if (modconst)
         *modconst = CONST_VECTOR_ELT (op, 0);
-- 
2.1.4

Reply via email to