From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id AFC5E3858D20 for ; Thu, 25 May 2023 02:47:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AFC5E3858D20 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from loongson.cn (unknown [10.20.4.52]) by gateway (Coremail) with SMTP id _____8Bx1fAkzG5kr7kAAA--.1782S3; Thu, 25 May 2023 10:47:00 +0800 (CST) Received: from [10.20.4.52] (unknown [10.20.4.52]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxHuQhzG5kQRx2AA--.65235S2; Thu, 25 May 2023 10:46:57 +0800 (CST) Subject: Re: [PATCH] LoongArch: Fix the problem of structure parameter passing in C++. This structure has empty structure members and less than three floating point members. To: Jason Merrill , Jonathan Wakely Cc: Xi Ruoyao , gcc-patches@gcc.gnu.org, i@xen0n.name, xuchenghua@loongson.cn References: <20230524060407.19181-1-chenglulu@loongson.cn> <2d33bf204b0d59f16df8714123ee812be5754617.camel@xry111.site> <356c3dfd86b82689483fc96f97790909a2e57c47.camel@xry111.site> From: Lulu Cheng Message-ID: Date: Thu, 25 May 2023 10:46:57 +0800 User-Agent: Mozilla/5.0 (X11; Linux mips64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/alternative; boundary="------------1B7DE9851C258957431CAB7C" Content-Language: en-US X-CM-TRANSID:AQAAf8BxHuQhzG5kQRx2AA--.65235S2 X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBjvJXoWxur4xCF4UtF1UJr15Jw18Xwb_yoWrGw1UpF Z3K3WrKrWDJr4kur4kZa1kZFWaqFsxJan8Jryrtr1vvFy5KryFvFW0kF15uFZxWrsYgayY qr45ta9rurZ8Z3DanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUj1kv1TuYvTs0mT0YCTnIWj DUYxn0WfASr-VFAUDa7-sFnT9fnUUIcSsGvfJTRUUUbxxYFVCjjxCrM7AC8VAFwI0_Jr0_ Gr1l1xkIjI8I6I8E6xAIw20EY4v20xvaj40_Wr0E3s1l1IIY67AEw4v_JrI_Jryl8cAvFV AK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW8JVW5JwA2 z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr 1l84ACjcxK6I8E87Iv6xkF7I0E14v26r4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG 8wAqjxCEc2xF0cIa020Ex4CE44I27wAv7VC0I7IYx2IY67AKxVWUJVWUGwAv7VC2z280aV AFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcVAKI48JMx8GjcxK6IxK0xII j40E5I8CrwCYjI0SjxkI62AI1cAE67vIY487MxAIw28IcxkI7VAKI48JMxC20s026xCaFV Cjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_JrI_JrWlx2IqxVCjr7xvwVAFwI0_JrI_JrWl x4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjxv20xvE14v26r1j6r 1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY6xAIw20EY4v20xvaj40_Jr0_ JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267AKxVWUJVW8JbIYCT nIWIevJa73UjIFyTuYvjxUz4SrUUUUU X-Spam-Status: No, score=-6.5 required=5.0 tests=BAYES_00,HTML_MESSAGE,KAM_DMARC_STATUS,KAM_SHORT,NICE_REPLY_A,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 List-Id: This is a multi-part message in MIME format. --------------1B7DE9851C258957431CAB7C Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit 在 2023/5/25 上午4:15, Jason Merrill 写道: > On Wed, May 24, 2023 at 5:00 AM Jonathan Wakely via Gcc-patches > > wrote: > > On Wed, 24 May 2023 at 09:41, Xi Ruoyao wrote: > > > Wang Lei raised some concerns about Itanium C++ ABI, so let's > ask a C++ > > expert here... > > > > Jonathan: AFAIK the standard and the Itanium ABI treats an empty > class > > as size 1 > > Only as a complete object, not as a subobject. > > > Also as a data member subobject. > > > in order to guarantee unique address, so for the following: > > > > class Empty {}; > > class Test { Empty empty; double a, b; }; > > There is no need to have a unique address here, so Test::empty and > Test::a > have the same address. It's a potentially-overlapping subobject. > > For the Itanium ABI, sizeof(Test) == 2 * sizeof(double). > > > That would be true if Test::empty were marked [[no_unique_address]], > but without that attribute, sizeof(Test) is actually 3 * sizeof(double). > > > When we pass "Test" via registers, we may only allocate the > registers > > for Test::a and Test::b, and complete ignore Test::empty because > there > > is no addresses of registers.  Is this correct or not? > > I think that's a decision for the loongarch psABI. In principle, > there's no > reason a register has to be used to pass Test::empty, since you > can't read > from it or write to it. > > > Agreed.  The Itanium C++ ABI has nothing to say about how registers > are allocated for parameter passing; this is a matter for the psABI. > > And there is no need for a psABI to allocate a register for > Test::empty because it contains no data. > > In the x86_64 psABI, Test above is passed in memory because of its > size ("the size of the aggregate exceeds two eightbytes...").  But > > struct Test2 { Empty empty; double a; }; > > is passed in a single floating-point register; the Test2::empty > subobject is not passed anywhere, because its eightbyte is classified > as NO_CLASS, because there is no actual data there. > > I know nothing about the LoongArch psABI, but going out of your way to > assign a register to an empty class seems like a mistake. MIPS64 and ARM64 also allocate parameter registers for empty structs. https://godbolt.org/z/jT4cY3T5o Our original intention is not to pass this empty structure member, but to make the following two structures treat empty structure members in the same way in the process of passing parameters. struct st1 {     struct empty {} e1;     long a;     long b; }; struct st2 {     struct empty {} e1;     double f0;     double f1; }; > > > On Wed, 2023-05-24 at 14:45 +0800, Xi Ruoyao via Gcc-patches wrote: > > > On Wed, 2023-05-24 at 14:04 +0800, Lulu Cheng wrote: > > > > An empty struct type that is not non-trivial for the purposes of > > > > calls > > > > will be treated as though it were the following C type: > > > > > > > > struct { > > > >   char c; > > > > }; > > > > > > > > Before this patch was added, a structure parameter containing an > > > > empty structure and > > > > less than three floating-point members was passed through > one or two > > > > floating-point > > > > registers, while nested empty structures are ignored. Which > did not > > > > conform to the > > > > calling convention. > > > > > > No, it's a deliberate decision I've made in > > > https://gcc.gnu.org/r12-8294. And we already agreed "the ABI > needs to > > > be updated" when we applied r12-8294, but I've never improved my > > > English > > > skill to revise the ABI myself :(. > > > > > > We are also using the same "de-facto" ABI throwing away the empty > > > struct > > > for Clang++ (https://reviews.llvm.org/D132285). So we should > update > > > the > > > spec here, instead of changing every implementation. > > > > > > The C++ standard treats the empty struct as size 1 for > ensuring the > > > semantics of pointer comparison operations.  When we pass it > through > > > the > > > registers, there is no need to really consider the empty field > because > > > there is no pointers to registers. > > > > > > > > --------------1B7DE9851C258957431CAB7C--