public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Iain Buclaw <ibuclaw@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r12-8548] d: Fix error: aggregate value used where floating point was expected
Date: Mon,  4 Jul 2022 13:16:40 +0000 (GMT)	[thread overview]
Message-ID: <20220704131640.1F4A038582A7@sourceware.org> (raw)

https://gcc.gnu.org/g:32dfb075ad31413af9086ce546b5f5317a916d34

commit r12-8548-g32dfb075ad31413af9086ce546b5f5317a916d34
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.
            * expr.cc (ExprVisitor::visit (VectorExp *)): Handle generating a
            vector expression from a static array.
            * toir.cc (IRVisitor::visit (ReturnStatement *)): Call
            convert_for_rvalue on return value.
    
    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.
    
    (cherry picked from commit 329bef49da30158d30fed1106002bb71674776bd)

Diff:
---
 gcc/d/d-convert.cc               | 44 +++++++++++++++++++++++++++++++++++++++-
 gcc/d/expr.cc                    | 10 +++++++--
 gcc/d/toir.cc                    |  1 +
 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 ++++++++++++++++++++++++
 7 files changed, 178 insertions(+), 3 deletions(-)

diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index 3a6a32ab024..ec5da6c10a6 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 == 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",
@@ -643,6 +652,39 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype)
       result = convert (build_ctype (tbtype), result);
     }
 
+  if (tbtype->ty == TY::Tsarray
+      && ebtype->ty == 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 = tbtype->isTypeSArray ()->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);
 }
 
@@ -703,7 +745,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/expr.cc b/gcc/d/expr.cc
index 325cbed892f..73dab463926 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -2932,14 +2932,13 @@ public:
 
   void visit (VectorExp *e)
   {
-    tree type = build_ctype (e->type);
-
     /* First handle array literal expressions.  */
     if (e->e1->op == EXP::arrayLiteral)
       {
 	ArrayLiteralExp *ale = e->e1->isArrayLiteralExp ();
 	vec <constructor_elt, va_gc> *elms = NULL;
 	bool constant_p = true;
+	tree type = build_ctype (e->type);
 
 	vec_safe_reserve (elms, ale->elements->length);
 	for (size_t i = 0; i < ale->elements->length; i++)
@@ -2959,9 +2958,16 @@ public:
 	else
 	  this->result_ = build_constructor (type, elms);
       }
+    else if (e->e1->type->toBasetype ()->ty == 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 type = build_ctype (e->type);
 	tree value = d_convert (TREE_TYPE (type),
 				build_expr (e->e1, this->constp_, true));
 	this->result_ = build_vector_from_val (type, value);
diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc
index d20c5c3b927..bf81dc9ad96 100644
--- a/gcc/d/toir.cc
+++ b/gcc/d/toir.cc
@@ -1022,6 +1022,7 @@ public:
 	    /* Generate: (<retval> = expr, return <retval>);  */
 	    tree expr = build_expr_dtor (s->exp);
 	    tree init = stabilize_expr (&expr);
+	    expr = convert_for_rvalue (expr, s->exp->type, type);
 	    expr = build_assign (INIT_EXPR, this->func_->shidden, expr);
 	    add_stmt (compound_expr (init, expr));
 	  }
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;
+}


                 reply	other threads:[~2022-07-04 13:16 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220704131640.1F4A038582A7@sourceware.org \
    --to=ibuclaw@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).