From patchwork Wed Jun 29 21:13:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1650361 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=ENl3zB4A; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4LYDjB6czlz9s1l for ; Thu, 30 Jun 2022 07:13:49 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9E5EA3842ACB for ; Wed, 29 Jun 2022 21:13:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9E5EA3842ACB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1656537225; bh=FnezQMjSjVoZaWNFFy36iw47Gl5uUcqWihbLm5aeYR4=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=ENl3zB4A8oQMUsWtgZEEjQivVBOi4dt5PkpTYm8ncbKzgBakX/Kwad2SHcErOKKGK 481cGf5haayVS3cu8EA8azKny2QIvjljB+XgUVFIRkHM0NSZyofITCLElQ2BrV8NKD e2kx8ag8yIJLhKH+OWyjHb3Jf/ffZXkuTrl0SpZ4= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-101.mailbox.org (mout-p-101.mailbox.org [80.241.56.151]) by sourceware.org (Postfix) with ESMTPS id 45AAA384D1B0 for ; Wed, 29 Jun 2022 21:13:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 45AAA384D1B0 Received: from smtp2.mailbox.org (smtp2.mailbox.org [IPv6:2001:67c:2050:b231:465::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4LYDhb3m4Qz9sr5; Wed, 29 Jun 2022 23:13:19 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [committed] d: Fix error: aggregate value used where floating point was expected (PR106139) Date: Wed, 29 Jun 2022 23:13:17 +0200 Message-Id: <20220629211317.2698766-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4LYDhb3m4Qz9sr5 X-Spam-Status: No, score=-13.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Hi, Casting from vector to static array is permitted in the D, and the front-end 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. As this is a bug also affecting previous versions, this will be backported as appropriate, with a couple more changes required to fix other related issues in the dmd front-end, so it'll go out separately. Bootstrapped and regression tested on x86_64-linux-gnu/-m32/-mx32, and committed to mainline. Regards, Iain. --- 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. --- 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(-) create mode 100644 gcc/testsuite/gdc.dg/pr106139a.d create mode 100644 gcc/testsuite/gdc.dg/pr106139b.d create mode 100644 gcc/testsuite/gdc.dg/pr106139c.d create mode 100644 gcc/testsuite/gdc.dg/pr106139d.d 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 *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 34b3ddd3f10..1bb10a835d2 100644 --- a/gcc/d/expr.cc +++ b/gcc/d/expr.cc @@ -2917,14 +2917,13 @@ public: void visit (VectorExp *e) final override { - tree type = build_ctype (e->type); - /* First handle array literal expressions. */ if (e->e1->op == EXP::arrayLiteral) { 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++) @@ -2944,9 +2943,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 50d44156cca..e5f5751f6db 100644 --- a/gcc/d/toir.cc +++ b/gcc/d/toir.cc @@ -1022,6 +1022,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; +}