From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 007E3394843F for ; Tue, 22 Mar 2022 17:11:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 007E3394843F Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9ACA81042; Tue, 22 Mar 2022 10:11:52 -0700 (PDT) Received: from [10.57.41.3] (unknown [10.57.41.3]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id C00573F66F; Tue, 22 Mar 2022 10:11:51 -0700 (PDT) Message-ID: Date: Tue, 22 Mar 2022 17:11:50 +0000 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0 Subject: Re: Urgent GCC ABI backend maintainer ping re zero width bitfield passing (PR102024) Content-Language: en-GB To: Jakub Jelinek Cc: Richard Earnshaw , Richard Sandiford , Ulrich Weigand , gcc@gcc.gnu.org References: <121930f1-4c90-eb69-a87f-7158000f1592@foss.arm.com> From: Richard Earnshaw In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-3491.0 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, NICE_REPLY_A, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=no 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@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Mar 2022 17:11:54 -0000 On 22/03/2022 16:51, Jakub Jelinek via Gcc wrote: > On Tue, Mar 22, 2022 at 04:28:08PM +0000, Richard Earnshaw wrote: >> Unless I've missed something subtle here, the layout of >> >> struct S { float a; int : 0; float b;}; >> >> is going to identical to >> >> struct T { float a; float b;}; >> >> on pretty much every architecture I can think of, so this is purely about >> parameter passing rules for the former and whether the two cases above >> should behave the same way. > > Layout is always done with the int : 0; bitfields in TYPE_FIELDS and > only after that is done C++ FE used to remove them. > So yes, it only can affect the passing of parameters and return values > in registers (or partially in registers, partially in memory). > >> The AAPCS and AAPCS64 both contain the same statement as part of the >> definition of an HFA: >> >> | The test for homogeneity is applied after data layout is >> | completed and without regard to access control or other source >> | language restrictions. >> >> The access control and source language restrictions was intended to cover >> c++-style features such as public/private, so aren't really relevant to this >> discussion (though you might plausibly read 'source language restriction' to >> cover this). However, the fact that the test is applied after layout has >> been done and because a zero-sized bit-field neither >> - adds an accessible member >> - changes the layout in any case I can think of that would potentially be an >> HFA. >> my preliminary conclusion is that for Arm and AArch64 we still have a duck >> here (if it walks like one and quacks like one...). >> >> I'm still awaiting final confirmation of this from our internal ABI group, >> but I'm pretty confident that this will be our final position. >> >> PS. It looks like llvm and llvm++ are inconsistent on this one as well. > > At least on x86_64 clang and clang++ consistently honored the zero width > bitfields during structure layout and ignored them during parameter passing > decisions (i.e. what the x86_64 psABI chose to clarify). > I was looking at aarch32 (arm). Compiling struct S { float a; int : 0; float b; }; struct S foo (struct S x) { x.b += 1.0f; return x; } with clang-10 I get foo: .fnstart vmov.f32 s0, #1.000000e+00 str r1, [r0] vmov s2, r2 vadd.f32 s0, s2, s0 vstr s0, [r0, #4] bx lr while clang++10 gives _Z3foo1S: .fnstart vmov.f32 s2, #1.000000e+00 vadd.f32 s1, s1, s2 bx lr Both with the options -S -O2 abi-bf.c -o - --target=arm-none-eabi -march=armv8-a -mfpu=neon -mfloat-abi=hard So for C it has passed the object in r1/r2 and returned it in memory, while for C++ it has passed it as an HFA. But for AArch64 it doesn't look right either: clang-10 foo: // @foo // %bb.0: lsr x8, x0, #32 fmov s0, #1.00000000 fmov s1, w8 fadd s0, s1, s0 fmov w8, s0 bfi x0, x8, #32, #32 ret clang++-10: _Z3foo1S: // @_Z3foo1S // %bb.0: fmov s2, #1.00000000 fadd s1, s1, s2 ret > I guess it would be nice to include the testcases we are talking about, > like { float x; int : 0; float y; } and { float x; int : 0; } and > { int : 0; float x; } into compat.exp testsuite so that we see ABI > differences in compat testing. > > Jakub > Yes, we might also add some specific Arm ABI tests as well. R.