From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id AC7C7396D839; Fri, 20 Nov 2020 11:31:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AC7C7396D839 From: "cvs-commit at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/88101] Implement P0528R3, C++20 cmpxchg and padding bits Date: Fri, 20 Nov 2020 11:31:48 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: unknown X-Bugzilla-Keywords: X-Bugzilla-Severity: enhancement X-Bugzilla-Who: cvs-commit at gcc dot gnu.org X-Bugzilla-Status: ASSIGNED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: jakub at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Nov 2020 11:31:48 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D88101 --- Comment #9 from CVS Commits --- The master branch has been updated by Jakub Jelinek : https://gcc.gnu.org/g:1bea0d0aa5936cb36b6f86f721ca03c1a1bb601d commit r11-5196-g1bea0d0aa5936cb36b6f86f721ca03c1a1bb601d Author: Jakub Jelinek Date: Fri Nov 20 12:28:34 2020 +0100 c++: Add __builtin_clear_padding builtin - C++20 P0528R3 compiler side [PR88101] The following patch implements __builtin_clear_padding builtin that cle= ars the padding bits in object representation (but preserves value representation). Inside of unions it clears only those padding bits th= at are padding for all the union members (so that it never alters value representation). It handles trailing padding, padding in the middle of structs including bitfields (PDP11 unhandled, I've never figured out how those bitfields work), VLAs (doesn't handle variable length structures, but I think alm= ost nobody uses them and it isn't worth the extra complexity). For VLAs and sufficiently large arrays it uses runtime clearing loop instead of emit= ting straight-line code (unless arrays are inside of a union). The way I think this can be used for atomics is e.g. if the structures are power of two sized and small enough that we use the hw atomics for say compare_exchange __builtin_clear_padding could be called first = on the address of expected and desired arguments (for desired only if we w= ant to ensure that most of the time the atomic memory will have padding bits cleared), then perform the weak cmpxchg and if that fails, we got the value from the atomic memory; we can call __builtin_clear_padding on a = copy of that and then compare it with expected, and if it is the same with t= he padding bits masked off, we can use the original with whatever random padding bits in it as the new expected for next cmpxchg. __builtin_clear_padding itself is not atomic and therefore it shouldn't be called on the atomic memory itself, but compare_exchange*'s expected argument is a reference and normally the implementation may store there the current value from memory, so padding bits can be cleared in that, and desired is passed by value rather than reference, so clearing is fi= ne too. When using libatomic, we can use it either that way, or add new libatom= ic APIs that accept another argument, pointer to the padding bit bitmask, and construct that in the template as alignas (_T) unsigned char _mask[sizeof (_T)]; std::memset (_mask, ~0, sizeof (_mask)); __builtin_clear_padding ((_T *) _mask); which will have bits cleared for padding bits and set for bits taking p= art in the value representation. Then libatomic could internally instead of using memcmp compare for (i =3D 0; i < N; i++) if ((val1[i] & mask[i]) !=3D (val2[i] & mask[= i])) 2020-11-20 Jakub Jelinek PR libstdc++/88101 gcc/ * builtins.def (BUILT_IN_CLEAR_PADDING): New built-in function. * gimplify.c (gimplify_call_expr): Rewrite single argument BUILT_IN_CLEAR_PADDING into two-argument variant. * gimple-fold.c (clear_padding_unit, clear_padding_buf_size): N= ew const variables. (struct clear_padding_struct): New type. (clear_padding_flush, clear_padding_add_padding, clear_padding_emit_loop, clear_padding_type, clear_padding_union, clear_padding_real_needs_padding_p, clear_padding_type_may_have_padding_p, gimple_fold_builtin_clear_padding): New functions. (gimple_fold_builtin): Handle BUILT_IN_CLEAR_PADDING. * doc/extend.texi (__builtin_clear_padding): Document. gcc/c-family/ * c-common.c (check_builtin_function_arguments): Handle BUILT_IN_CLEAR_PADDING. gcc/testsuite/ * c-c++-common/builtin-clear-padding-1.c: New test. * c-c++-common/torture/builtin-clear-padding-1.c: New test. * c-c++-common/torture/builtin-clear-padding-2.c: New test. * c-c++-common/torture/builtin-clear-padding-3.c: New test. * c-c++-common/torture/builtin-clear-padding-4.c: New test. * c-c++-common/torture/builtin-clear-padding-5.c: New test. * g++.dg/torture/builtin-clear-padding-1.C: New test. * g++.dg/torture/builtin-clear-padding-2.C: New test. * gcc.dg/builtin-clear-padding-1.c: New test.=