public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r10-10885] d: Fix error: aggregate value used where floating point was expected
@ 2022-07-05  9:40 Iain Buclaw
  0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2022-07-05  9:40 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:0b909ae026e5aaf2ce42ef5c33128dbc06d29803

commit r10-10885-g0b909ae026e5aaf2ce42ef5c33128dbc06d29803
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date:   Wed Jun 29 21:52:39 2022 +0200

    d: Fix error: aggregate value used where floating point was expected
    
    Casting from vector to static array is permitted, and the frontend
    generates a reinterpret cast, but casting back the other way resulted in
    an error.  This has been fixed to be properly handled in the code
    generation pass of VectorExp, and the conversion for lvalue and rvalue
    handling done in convert_expr and convert_for_rvalue respectively.
    
            PR d/106139
    
    gcc/d/ChangeLog:
    
            * d-convert.cc (convert_expr): Handle casting from array to vector.
            (convert_for_rvalue): Rewrite vector to array casts of the same
            element type into a constructor.
            (convert_for_assignment): Return calling convert_for_rvalue.
            * dmd/expressionsem.c (ExpressionSemanticVisitor::visit): Run semantic
            on vector expression after lowering.
            * expr.cc (ExprVisitor::visit (VectorExp *)): Handle generating a
            vector expression from a static array.
    
    gcc/testsuite/ChangeLog:
    
            * gdc.dg/pr106139a.d: New test.
            * gdc.dg/pr106139b.d: New test.
            * gdc.dg/pr106139c.d: New test.
            * gdc.dg/pr106139d.d: New test.
            * gdc.test/fail_compilation/ice20264.d: New test.
    
    (cherry picked from commit 488759b7ea16972c4dfbb62926cd71996b1f77a7)

Diff:
---
 gcc/d/d-convert.cc                                 | 44 +++++++++++++++++++++-
 gcc/d/dmd/expressionsem.c                          |  1 +
 gcc/d/expr.cc                                      | 17 ++++++---
 gcc/testsuite/gdc.dg/pr106139a.d                   | 36 ++++++++++++++++++
 gcc/testsuite/gdc.dg/pr106139b.d                   | 36 ++++++++++++++++++
 gcc/testsuite/gdc.dg/pr106139c.d                   | 27 +++++++++++++
 gcc/testsuite/gdc.dg/pr106139d.d                   | 27 +++++++++++++
 gcc/testsuite/gdc.test/fail_compilation/ice20264.d | 13 +++++++
 8 files changed, 195 insertions(+), 6 deletions(-)

diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index 87062513c33..2cfc2c8cc19 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -502,6 +502,15 @@ convert_expr (tree exp, Type *etype, Type *totype)
 	  gcc_assert (totype->size () == etype->size ());
 	  result = build_vconvert (build_ctype (totype), exp);
 	}
+      else if (tbtype->ty == Tvector && tbtype->size () == ebtype->size ())
+	{
+	  /* Allow casting from array to vector as if its an unaligned load.  */
+	  tree type = build_ctype (totype);
+	  tree unaligned_type = build_variant_type_copy (type);
+	  SET_TYPE_ALIGN (unaligned_type, 1 * BITS_PER_UNIT);
+	  TYPE_USER_ALIGN (unaligned_type) = 1;
+	  result = convert (type, build_vconvert (unaligned_type, exp));
+	}
       else
 	{
 	  error ("cannot cast expression of type %qs to type %qs",
@@ -634,6 +643,39 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype)
       break;
     }
 
+  if (tbtype->ty == Tsarray
+      && ebtype->ty == Tsarray
+      && tbtype->nextOf ()->ty == ebtype->nextOf ()->ty
+      && INDIRECT_REF_P (expr)
+      && CONVERT_EXPR_CODE_P (TREE_CODE (TREE_OPERAND (expr, 0)))
+      && TREE_CODE (TREE_OPERAND (TREE_OPERAND (expr, 0), 0)) == ADDR_EXPR)
+    {
+      /* If expression is a vector that was casted to an array either by
+	 explicit type cast or by taking the vector's `.array' value, strip the
+	 reinterpret cast and build a constructor instead.  */
+      tree ptr = TREE_OPERAND (TREE_OPERAND (expr, 0), 0);
+
+      if (VECTOR_TYPE_P (TREE_TYPE (TREE_TYPE (ptr))))
+	{
+	  /* Rewrite: `*(Array *)&vector'
+		into: `{ vector[0], vector[1], ... }'  */
+	  tree array = d_save_expr (TREE_OPERAND (ptr, 0));
+	  array = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), array);
+
+	  uinteger_t dim = ((TypeSArray *)tbtype)->dim->toUInteger ();
+	  vec <constructor_elt, va_gc> *elms = NULL;
+	  for (uinteger_t i = 0; i < dim; i++)
+	    {
+	      tree index = size_int (i);
+	      tree value = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
+				   array, index, NULL_TREE, NULL_TREE);
+	      CONSTRUCTOR_APPEND_ELT (elms, index, value);
+	    }
+
+	  return build_constructor (build_ctype (totype), elms);
+	}
+    }
+
   return result ? result : convert_expr (expr, etype, totype);
 }
 
@@ -694,7 +736,7 @@ convert_for_assignment (tree expr, Type *etype, Type *totype)
       return expr;
     }
 
-  return convert_expr (expr, etype, totype);
+  return convert_for_rvalue (expr, etype, totype);
 }
 
 /* Return a TREE representation of EXPR converted to represent
diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c
index 5096754e55f..3c199bf1b57 100644
--- a/gcc/d/dmd/expressionsem.c
+++ b/gcc/d/dmd/expressionsem.c
@@ -4309,6 +4309,7 @@ public:
         if (tob->ty == Tvector && t1b->ty != Tvector)
         {
             result = new VectorExp(exp->loc, exp->e1, exp->to);
+            result = semantic(result, sc);
             return;
         }
 
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index a579356104e..aca767cc93b 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -2993,21 +2993,20 @@ public:
 
   void visit (VectorExp *e)
   {
-    tree type = build_ctype (e->type);
-    tree etype = TREE_TYPE (type);
-
     /* First handle array literal expressions.  */
     if (e->e1->op == TOKarrayliteral)
       {
 	ArrayLiteralExp *ale = ((ArrayLiteralExp *) e->e1);
 	vec<constructor_elt, va_gc> *elms = NULL;
 	bool constant_p = true;
+	tree type = build_ctype (e->type);
 
 	vec_safe_reserve (elms, ale->elements->dim);
 	for (size_t i = 0; i < ale->elements->dim; i++)
 	  {
 	    Expression *expr = ale->getElement (i);
-	    tree value = d_convert (etype, build_expr (expr, this->constp_));
+	    tree value = d_convert (TREE_TYPE (type),
+				    build_expr (expr, this->constp_));
 	    if (!CONSTANT_CLASS_P (value))
 	      constant_p = false;
 
@@ -3020,10 +3019,18 @@ public:
 	else
 	  this->result_ = build_constructor (type, elms);
       }
+    else if (e->e1->type->toBasetype ()->ty == Tsarray)
+      {
+	/* Build a vector representation from a static array.  */
+	this->result_ = convert_expr (build_expr (e->e1, this->constp_),
+				      e->e1->type, e->type);
+      }
     else
       {
 	/* Build constructor from single value.  */
-	tree val = d_convert (etype, build_expr (e->e1, this->constp_));
+	tree type = build_ctype (e->type);
+	tree val = d_convert (TREE_TYPE (type),
+			      build_expr (e->e1, this->constp_));
 	this->result_ = build_vector_from_val (type, val);
       }
   }
diff --git a/gcc/testsuite/gdc.dg/pr106139a.d b/gcc/testsuite/gdc.dg/pr106139a.d
new file mode 100644
index 00000000000..f635eabc745
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr106139a.d
@@ -0,0 +1,36 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106139
+// { dg-do compile }
+
+alias A = int[4];
+
+static if (__traits(compiles, __vector(A))):
+
+A vector2array(__vector(A) v)
+{
+    return cast(A)v;
+}
+
+void vector2array(ref A a, __vector(A) v)
+{
+    a = cast(A)v;
+}
+
+__vector(A) array2vector(A a)
+{
+    return cast(__vector(A)) a;
+}
+
+void array2vector(ref __vector(A) v, A a)
+{
+    v = cast(__vector(A))a;
+}
+
+A vector2array_array(__vector(A) v)
+{
+    return v.array;
+}
+
+void vector2array_array(ref A a, __vector(A) v)
+{
+    a = v.array;
+}
diff --git a/gcc/testsuite/gdc.dg/pr106139b.d b/gcc/testsuite/gdc.dg/pr106139b.d
new file mode 100644
index 00000000000..f9caf026f86
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr106139b.d
@@ -0,0 +1,36 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106139
+// { dg-do compile }
+
+alias A = float[4];
+
+static if (__traits(compiles, __vector(A))):
+
+A vector2array(__vector(A) v)
+{
+    return cast(A)v;
+}
+
+void vector2array(ref A a, __vector(A) v)
+{
+    a = cast(A)v;
+}
+
+__vector(A) array2vector(A a)
+{
+    return cast(__vector(A)) a;
+}
+
+void array2vector(ref __vector(A) v, A a)
+{
+    v = cast(__vector(A))a;
+}
+
+A vector2array_array(__vector(A) v)
+{
+    return v.array;
+}
+
+void vector2array_array(ref A a, __vector(A) v)
+{
+    a = v.array;
+}
diff --git a/gcc/testsuite/gdc.dg/pr106139c.d b/gcc/testsuite/gdc.dg/pr106139c.d
new file mode 100644
index 00000000000..3b6b7a83341
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr106139c.d
@@ -0,0 +1,27 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106139
+// { dg-do compile }
+
+alias V = int[4];
+alias A = float[4];
+
+static if (__traits(compiles, __vector(V))):
+
+A vector2array(__vector(V) v)
+{
+    return cast(A)v;
+}
+
+void vector2array(ref A a, __vector(V) v)
+{
+    a = cast(A)v;
+}
+
+__vector(V) array2vector(A a)
+{
+    return cast(__vector(V)) a;
+}
+
+void array2vector(ref __vector(V) v, A a)
+{
+    v = cast(__vector(V))a;
+}
diff --git a/gcc/testsuite/gdc.dg/pr106139d.d b/gcc/testsuite/gdc.dg/pr106139d.d
new file mode 100644
index 00000000000..4c6f0ef3a3a
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr106139d.d
@@ -0,0 +1,27 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106139
+// { dg-do compile }
+
+alias V = float[4];
+alias A = int[4];
+
+static if (__traits(compiles, __vector(V))):
+
+A vector2array(__vector(V) v)
+{
+    return cast(A)v;
+}
+
+void vector2array(ref A a, __vector(V) v)
+{
+    a = cast(A)v;
+}
+
+__vector(V) array2vector(A a)
+{
+    return cast(__vector(V)) a;
+}
+
+void array2vector(ref __vector(V) v, A a)
+{
+    v = cast(__vector(V))a;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice20264.d b/gcc/testsuite/gdc.test/fail_compilation/ice20264.d
new file mode 100644
index 00000000000..0d697e22c9f
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/ice20264.d
@@ -0,0 +1,13 @@
+/*
+DISABLED: freebsd32 linux32 osx32 win32
+TEST_OUTPUT:
+---
+fail_compilation/ice20264.d(12): Error: `cast(__vector(float[4]))a` is not an lvalue and cannot be modified
+---
+*/
+
+void foo(float *a)
+{
+    alias float4 = __vector(float[4]);
+    cast(float4)(a) = 1.0f;
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-07-05  9:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-05  9:40 [gcc r10-10885] d: Fix error: aggregate value used where floating point was expected Iain Buclaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).