From patchwork Wed Mar 13 18:39:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 1056189 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-497842-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=embecosm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="CTtGZCbd"; dkim=pass (2048-bit key; unprotected) header.d=embecosm.com header.i=@embecosm.com header.b="ZOGmnGhd"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44KLHW6hZyz9s9N for ; Thu, 14 Mar 2019 05:40:06 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; q=dns; s=default; b=it/eaIhVYr4Y HCTmiVWto1MKeu13en8N8IieTbhXFTgtmzB2i01XDhbb2ZpfvEqVLu0XnXXuHtXB 9fSvKT6NxMPLq2X3Sox8M/hc5C6DN0HpYuMt6EztyI9pqHMbQWO/MV97wJPsPW43 Q5GnZKcsyuInLpyd/1L4kys+FuXZ+kg= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id; s=default; bh=ubMiAj8rPI1MvgS4Ai PwZE8+P+g=; b=CTtGZCbdFKFv2Musg2B4pswLJIawSuF+3ZPwrx3Tx49vQQiwXi mZ9EDqMMF2nP8fVeXTY1NX2bAMVBXezy3q+smyqrjcnVzxRdl6MA4IN7LdaFBpf3 QLcvYfwbbsegmcPs9aZhji7Q7qa4XIVS7tqWeY1StGltr7uO6ZpYRYe0s= Received: (qmail 102655 invoked by alias); 13 Mar 2019 18:39:59 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 102353 invoked by uid 89); 13 Mar 2019 18:39:58 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=riscv***, riscv*-*-*, sf, 89627 X-HELO: mail-wm1-f68.google.com Received: from mail-wm1-f68.google.com (HELO mail-wm1-f68.google.com) (209.85.128.68) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 13 Mar 2019 18:39:56 +0000 Received: by mail-wm1-f68.google.com with SMTP id n19so354462wmi.1 for ; Wed, 13 Mar 2019 11:39:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=from:to:cc:subject:date:message-id; bh=hvCAtCFLPe6a26kL3OrEO3ztPV8yRbOZdBK02e7Uw08=; b=ZOGmnGhdM4dz56+xWiV3ZQ2ddGD9XexyJ7mzDqgcdLkqQnGInPmbTTTpnWJ69HyN2O rbcjDlBNcwtK95LWG7oLzdU0C8qmmzWMz9hMdD/dE/xUlgZnw8/Qs9cPZckN8VHwOeFU bVr+opoYuojlGk0qpNgxdeQu1Hr1Ss3NJr+FMDw2a69f3r2rF8CQEIzzF2kgiMR+I+gL ZXkfRe4mrV8kV89VgkdF1Y63FUpPnyEl6Ot9qsmGri3MHQsvF6nuHB6fFsPMB9MOwkLG sghiHHM7cI5c2+Cn7BNtXrbD2nybWrigzlnZvbPlmywpPMriSTdywDyqwPoijyeGW8PW yopQ== Received: from localhost (host86-142-70-198.range86-142.btcentralplus.com. [86.142.70.198]) by smtp.gmail.com with ESMTPSA id w9sm663006wrs.23.2019.03.13.11.39.53 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Mar 2019 11:39:53 -0700 (PDT) From: Andrew Burgess To: gcc-patches@gcc.gnu.org Cc: jimw@sifive.com, Andrew Burgess Subject: [PATCH] gcc/riscv: Correctly ignore empty C++ structs when flattening for ABI Date: Wed, 13 Mar 2019 18:39:49 +0000 Message-Id: <20190313183949.8920-1-andrew.burgess@embecosm.com> X-IsSubscribed: yes Jim, Sorry for the delay in sending this patch. Thanks, Andrew --- This fixes PR target/89627. The RISC-V ABI document[1] says: For the purposes of this section, "struct" refers to a C struct with its hierarchy flattened, including any array fields. That is, struct { struct { float f[1]; } g[2]; } and struct { float f; float g; } are treated the same. Fields containing empty structs or unions are ignored while flattening, even in C++, unless they have nontrivial copy constructors or destructors. However, this flattening only applies when one of the fields of the flattened structure can be placed into a floating point register, otherwise no flattening occurs. Currently GCC fails to correctly consider that empty C++ structures have a non-zero size when constructing the arguments from a flattened structure, and as a result, trying to pass a C++ structure like this: struct sf { struct {} e; float f; }; Doesn't work correctly, GCC fails to take the offset of 'f' within 'sf' into account and will actually pass the space backing 'e' as the contents of 'f'. This patch fixes this so that 'f' will be passed correctly. A couple of new tests are added to cover this functionality. [1] https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md gcc/ChangeLog: PR target/89627 * config/riscv/riscv.c (riscv_pass_fpr_single): Add offset parameter, and make use of it. (riscv_get_arg_info): Pass offset to riscv_pass_fpr_single. gcc/testsuite/ChangeLog: PR target/89627 * g++.target/riscv/call-with-empty-struct-float.C: New file. * g++.target/riscv/call-with-empty-struct-int.C: New file. * g++.target/riscv/call-with-empty-struct.H: New file. * g++.target/riscv/riscv.exp: New file. --- gcc/ChangeLog | 7 +++++ gcc/config/riscv/riscv.c | 8 +++-- gcc/testsuite/ChangeLog | 8 +++++ .../riscv/call-with-empty-struct-float.C | 6 ++++ .../g++.target/riscv/call-with-empty-struct-int.C | 6 ++++ .../g++.target/riscv/call-with-empty-struct.H | 19 ++++++++++++ gcc/testsuite/g++.target/riscv/riscv.exp | 34 ++++++++++++++++++++++ 7 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.target/riscv/call-with-empty-struct-float.C create mode 100644 gcc/testsuite/g++.target/riscv/call-with-empty-struct-int.C create mode 100644 gcc/testsuite/g++.target/riscv/call-with-empty-struct.H create mode 100644 gcc/testsuite/g++.target/riscv/riscv.exp diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c index 8881f80e18f..8e78ab76375 100644 --- a/gcc/config/riscv/riscv.c +++ b/gcc/config/riscv/riscv.c @@ -2449,13 +2449,14 @@ riscv_pass_aggregate_in_fpr_and_gpr_p (const_tree type, static rtx riscv_pass_fpr_single (machine_mode type_mode, unsigned regno, - machine_mode value_mode) + machine_mode value_mode, + HOST_WIDE_INT offset) { rtx x = gen_rtx_REG (value_mode, regno); if (type_mode != value_mode) { - x = gen_rtx_EXPR_LIST (VOIDmode, x, const0_rtx); + x = gen_rtx_EXPR_LIST (VOIDmode, x, GEN_INT (offset)); x = gen_rtx_PARALLEL (type_mode, gen_rtvec (1, x)); } return x; @@ -2517,7 +2518,8 @@ riscv_get_arg_info (struct riscv_arg_info *info, const CUMULATIVE_ARGS *cum, { case 1: return riscv_pass_fpr_single (mode, fregno, - TYPE_MODE (fields[0].type)); + TYPE_MODE (fields[0].type), + fields[0].offset); case 2: return riscv_pass_fpr_pair (mode, fregno, diff --git a/gcc/testsuite/g++.target/riscv/call-with-empty-struct-float.C b/gcc/testsuite/g++.target/riscv/call-with-empty-struct-float.C new file mode 100644 index 00000000000..76d0dc6d93d --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/call-with-empty-struct-float.C @@ -0,0 +1,6 @@ +// { dg-do run } + +#include "call-with-empty-struct.H" + +MAKE_STRUCT_PASSING_TEST(float,2.5) + diff --git a/gcc/testsuite/g++.target/riscv/call-with-empty-struct-int.C b/gcc/testsuite/g++.target/riscv/call-with-empty-struct-int.C new file mode 100644 index 00000000000..cc82912dc3e --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/call-with-empty-struct-int.C @@ -0,0 +1,6 @@ +/* { dg-do run } */ + +#include "call-with-empty-struct.H" + +MAKE_STRUCT_PASSING_TEST(int,2) + diff --git a/gcc/testsuite/g++.target/riscv/call-with-empty-struct.H b/gcc/testsuite/g++.target/riscv/call-with-empty-struct.H new file mode 100644 index 00000000000..d2a46e78619 --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/call-with-empty-struct.H @@ -0,0 +1,19 @@ +#define MAKE_STRUCT_PASSING_TEST(type,val) \ + static struct struct_ ## type ## _t \ + { \ + struct { } e; \ + struct { type f; } s; \ + } global_struct_ ## type = { {}, { val } }; \ + \ + static bool \ + check_struct_ ## type (struct_ ## type ## _t obj) \ + { \ + return (obj.s.f == global_struct_ ## type .s.f); \ + } \ + \ + int \ + main () \ + { \ + bool result = check_struct_ ## type ( global_struct_ ## type ); \ + return result ? 0 : 1; \ + } diff --git a/gcc/testsuite/g++.target/riscv/riscv.exp b/gcc/testsuite/g++.target/riscv/riscv.exp new file mode 100644 index 00000000000..a339b5cc56d --- /dev/null +++ b/gcc/testsuite/g++.target/riscv/riscv.exp @@ -0,0 +1,34 @@ +# Copyright (C) 2019 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# GCC testsuite that uses the `dg.exp' driver. + +# Exit immediately if this isn't a RISC-V target. +if ![istarget riscv*-*-*] then { + return +} + +# Load support procs. +load_lib g++-dg.exp + +# Initialize `dg'. +dg-init + +# Main loop. +dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C]] "" "" + +# All done. +dg-finish