[cfe-dev] cfe-dev Digest, Vol 161, Issue 22
Christoffer Lernö via cfe-dev
cfe-dev at lists.llvm.org
Fri Nov 13 04:07:51 PST 2020
Is it also C++ which will trigger the special case in GetX86_64ByValArgumentPair?
Here the comments state:
> // In order to correctly satisfy the ABI, we need to the high part to start
> // at offset 8. If the high and low parts we inferred are both 4-byte types
> // (e.g. i32 and i32) then the resultant struct type ({i32,i32}) won't have
> // the second element at offset 8. Check for this:
Here I am suspecting that struct Foo { int a; struct { } b; int c; } will create this situation in C++ but not in C. Is that a correct assumption?
Christoffer
AEGIK / www.aegik.se
> Date: Fri, 13 Nov 2020 09:44:54 +0000
> From: David Chisnall via cfe-dev <cfe-dev at lists.llvm.org>
> To: cfe-dev at lists.llvm.org
> Subject: Re: [cfe-dev] The x64 ABI lowering, direct pass of upper
> 8-bytes, can it happen?
> Message-ID: <54e66ccf-58c7-263e-aa86-f5889ec1d272 at cl.cam.ac.uk>
> Content-Type: text/plain; charset=utf-8; format=flowed
>
> To give a little bit more context:
>
> C and C++ require that every field in a structure has a unique pointer
> value (unless explicitly annotated in C++20) and C requires that a
> pointer to the first field of an object is equivalent to a pointer to
> the object.
>
> This combination of constraints first means that `s3_0` in this example
> will report a size of 1, but that byte is purely padding. When we lay
> out `s3_1`, we have a first field that is one byte (purely of padding)
> followed by 7 bytes of padding to correctly align `b`. This adds up to
> 8 bytes of padding.
>
> No one would write that by hand deliberately, but you can encounter
> things like this when you use std::conditional_t in a C++ class to do
> something like:
>
> ```c++
> struct Placeholder {};
>
> template<typename T = void>
> struct SomeClass
> {
> std::conditional_t<std::is_same_v<T, void>, T, PlaceHolder> extra_data;
> long unconditional_field;
> ...
> };
> ```
>
> This pattern is quite useful for classes where you want to provide an
> extension point for carrying some extra state but still support the case
> where the instantiating code doesn't want to provide any. Prior to
> C++20 there was no standard way of ensuring that the placeholder didn't
> take up any space. If you happened to pick the first field of the
> object for this field then you could end up with something equivalent to
> Craig's example, where you have 8 bytes of padding at the start of
> `SomeClass` before `unconditional_field`.
>
> In C++20, you can write this:
>
> ```c++
> struct Placeholder {};
>
> template<typename T = void>
> struct SomeClass
> {
> [[no_unique_address]]
> std::conditional_t<std::is_same_v<T, void>, T, PlaceHolder> extra_data;
> long unconditional_field;
> ...
> };
> ```
>
> Now, if `extra_data` gets the type `PlaceHolder`, `(char*)&extra_data ==
> (char*)&unconditional_Field`. That's typically what you want, because
> any accesses to `extra_data` will be guarded by a `constexpr if` that
> checks that `T` is not `void` and so the field will not actually be
> referenced at all in instantiations where it is not used to carry extra
> state.
>
>
> David
>
>
> On 12/11/2020 22:13, Craig Topper via cfe-dev wrote:
>> Adding an assert(0) inside that if fires on this test case from
>> clang/test/CodeGenCXX/x86_64-arguments.cpp
>>
>> // PR5831
>> // CHECK-LABEL: define void @_Z2f34s3_1(i64 %x.coerce)
>> struct s3_0 {};
>> struct s3_1 { struct s3_0 a; long b; };
>> void f3(struct s3_1 x) {}
>>
>> ~Craig
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20201113/f1450583/attachment.html>
More information about the cfe-dev
mailing list