From patchwork Wed Apr 20 06:23:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 53064 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 87B9E3857341 for ; Wed, 20 Apr 2022 06:25:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 87B9E3857341 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1650435920; bh=R7wiIvyudWT/90pQrJt8qnB5tph7aspIcyDNXTcBPso=; h=Subject:To:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=PUbtBcuuleL5UX9crEV0TjmCDZVdUjKwP1AHRS22o+IH8+jaJH24EpfnvyQLwDzis Osw6+4RNDhHTEyz+C7iaQ/jX+LCmgDX8mZmX0htxUEGcxMflnihwIXOaF4yNPFYEJJ I+Uex89+C+79gGk3VGJJmaF9mTUx8ZRsulGJ5qqs= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mengyan1223.wang (mengyan1223.wang [89.208.246.23]) by sourceware.org (Postfix) with ESMTPS id 1B0BA385734F for ; Wed, 20 Apr 2022 06:23:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 1B0BA385734F Received: from localhost.localdomain (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@mengyan1223.wang) by mengyan1223.wang (Postfix) with ESMTPSA id 02E9066529; Wed, 20 Apr 2022 02:23:56 -0400 (EDT) Message-ID: <4ec7e7a716cb0ca090983f0400c99c50bc67bcb3.camel@mengyan1223.wang> Subject: [PATCH] loongarch: ignore zero-size fields in calling convention To: Xi Ruoyao via Gcc-patches Date: Wed, 20 Apr 2022 14:23:53 +0800 User-Agent: Evolution 3.44.0 MIME-Version: 1.0 X-Spam-Status: No, score=-3037.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_SHORT, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Xi Ruoyao via Gcc-patches From: Xi Ruoyao Reply-To: Xi Ruoyao Cc: Chenghua Xu , Lulu Cheng , Xuerui Wang Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Currently, LoongArch ELF psABI is not clear on the handling of zero- sized fields in aggregates arguments or return values [1]. The behavior of GCC trunk is puzzling considering the following cases: struct test1 { double a[0]; float x; }; struct test2 { float a[0]; float x; }; GCC trunk passes test1::x via GPR, but test2::x via FPR. I believe no rational Homo Sapiens can understand (or even expect) this. And, to make things even worse, test1 behaves differently in C and C++. GCC trunk passes test1::x via GPR, but G++ trunk passes test1::x via FPR. I've write a paragraph about current GCC behavior for the psABI [2], but I think it's cleaner to just ignore all zero-sized fields in the ABI. This will require only a two-line change in GCC (this patch), and an one-line change in the ABI doc. If there is not any better idea I'd like to see this reviewed and applied ASAP. If we finally have to apply this patch after GCC 12 release, we'll need to add a lot more boring code to emit a -Wpsabi inform [3]. That will be an unnecessary burden for both us, and the users using the compiler (as the compiler will spend CPU time only for checking if a warning should be informed). [1]:https://github.com/loongson/LoongArch-Documentation/issues/48 [2]:https://github.com/loongson/LoongArch-Documentation/pull/49 [3]:https://gcc.gnu.org/PR102024 gcc/ * config/loongarch/loongarch.cc (loongarch_flatten_aggregate_field): Ignore empty fields for RECORD_TYPE. gcc/testsuite/ * gcc.target/loongarch/zero-size-field-pass.c: New test. * gcc.target/loongarch/zero-size-field-ret.c: New test. --- gcc/config/loongarch/loongarch.cc | 3 ++ .../loongarch/zero-size-field-pass.c | 30 +++++++++++++++++++ .../loongarch/zero-size-field-ret.c | 28 +++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c create mode 100644 gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index f22150a60cc..57e4d9f82ce 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -326,6 +326,9 @@ loongarch_flatten_aggregate_field (const_tree type, for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f)) if (TREE_CODE (f) == FIELD_DECL) { + if (DECL_SIZE (f) && integer_zerop (DECL_SIZE (f))) + continue; + if (!TYPE_P (TREE_TYPE (f))) return -1; diff --git a/gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c b/gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c new file mode 100644 index 00000000000..999dc913a71 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/zero-size-field-pass.c @@ -0,0 +1,30 @@ +/* Test that LoongArch backend ignores zero-sized fields of aggregates in + argument passing. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -mdouble-float -mabi=lp64d" } */ +/* { dg-final { scan-assembler "\\\$f1" } } */ + +struct test +{ + int empty1[0]; + double empty2[0]; + int : 0; + float x; + long empty3[0]; + long : 0; + float y; + unsigned : 0; + char empty4[0]; +}; + +extern void callee (struct test); + +void +caller (void) +{ + struct test test; + test.x = 114; + test.y = 514; + callee (test); +} diff --git a/gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c b/gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c new file mode 100644 index 00000000000..40137d97555 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/zero-size-field-ret.c @@ -0,0 +1,28 @@ +/* Test that LoongArch backend ignores zero-sized fields of aggregates in + returning. */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -mdouble-float -mabi=lp64d" } */ +/* { dg-final { scan-assembler-not "\\\$r4" } } */ + +struct test +{ + int empty1[0]; + double empty2[0]; + int : 0; + float x; + long empty3[0]; + long : 0; + float y; + unsigned : 0; + char empty4[0]; +}; + +extern struct test callee (void); + +float +caller (void) +{ + struct test test = callee (); + return test.x + test.y; +}