From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id 6AA89385C33E; Mon, 4 Jul 2022 15:54:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6AA89385C33E MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Iain Buclaw To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-10109] d: Fix error: aggregate value used where floating point was expected X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/heads/releases/gcc-11 X-Git-Oldrev: 6acd54d7497727241e79037e40ac0af87d2331f1 X-Git-Newrev: 488759b7ea16972c4dfbb62926cd71996b1f77a7 Message-Id: <20220704155429.6AA89385C33E@sourceware.org> Date: Mon, 4 Jul 2022 15:54:29 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 04 Jul 2022 15:54:29 -0000 https://gcc.gnu.org/g:488759b7ea16972c4dfbb62926cd71996b1f77a7 commit r11-10109-g488759b7ea16972c4dfbb62926cd71996b1f77a7 Author: Iain Buclaw 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. * 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. * gdc.test/fail_compilation/ice20264.d: New test. (cherry picked from commit 329bef49da30158d30fed1106002bb71674776bd) Diff: --- gcc/d/d-convert.cc | 44 +++++++++++++++++++++- gcc/d/dmd/expressionsem.c | 1 + 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 +++++++++++++ gcc/testsuite/gdc.test/fail_compilation/ice20264.d | 13 +++++++ 9 files changed, 192 insertions(+), 3 deletions(-) diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc index d43485dca77..cd6551e64f3 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", @@ -636,6 +645,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 = tbtype->isTypeSArray ()->dim->toUInteger (); + vec *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); } @@ -696,7 +738,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 5ae5fe6a717..fe90039d6f0 100644 --- a/gcc/d/dmd/expressionsem.c +++ b/gcc/d/dmd/expressionsem.c @@ -6330,6 +6330,7 @@ public: if (tob->ty == Tvector && t1b->ty != Tvector) { result = new VectorExp(exp->loc, exp->e1, exp->to); + result = expressionSemantic(result, sc); return; } diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc index 85269c6b2be..eb5feffef6a 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -3034,14 +3034,13 @@ public: void visit (VectorExp *e) { - tree type = build_ctype (e->type); - /* First handle array literal expressions. */ if (e->e1->op == TOKarrayliteral) { ArrayLiteralExp *ale = e->e1->isArrayLiteralExp (); vec *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++) @@ -3061,9 +3060,16 @@ 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 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 eaee6f7e803..460edc15143 100644 --- a/gcc/d/toir.cc +++ b/gcc/d/toir.cc @@ -1090,6 +1090,7 @@ public: /* Generate: ( = expr, return ); */ 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; +} 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; +}