From patchwork Mon Sep 12 17:45:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 668903 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3sXwGF2lHlz9sRZ for ; Tue, 13 Sep 2016 03:46:10 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=QGCQSnCN; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; q=dns; s=default; b=VVGQGnbcOZ2jLfIl ClWFdDi18kv9XxKQaSSD5Frta8fA6cCyJEUE3SHQYOeitRqXgL7TwVnORS1hSS8/ OH9qFjmgDfP8RQjTVMVN/kO7/eAbiolOJEeIVuMZtQYt7e9PQFFSiDLwDh+cJgrB BvffP9U3v2l89+h8oaDTjpeKEYw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; s=default; bh=VKHTPSLQbAaqhOXJ4RjoST P5OkU=; b=QGCQSnCN4gRKHUAizCwUkNQW6rmY3LUcXhMgCa53gkpXIbhhSO3CAJ jKgmAA50AUMcXFtA/Udfppm1SsIVgbvZ6m/Q99AJy7pr2pLGI/VS3ASba9hRH+Ke qzbm6iUqkikQqFywsBm1/qlPqFsyULx6Dlcx4GkqIGayRFc9wDJ+U= Received: (qmail 51176 invoked by alias); 12 Sep 2016 17:46:02 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 51166 invoked by uid 89); 12 Sep 2016 17:46:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.2 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS, URIBL_RED autolearn=no version=3.3.2 spammy=__float128, sk:__SIZEO, sk:__sizeo, ginclude X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 12 Sep 2016 17:45:52 +0000 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=svr-ies-mbx-01.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1bjVIj-0006cB-OZ from joseph_myers@mentor.com ; Mon, 12 Sep 2016 10:45:50 -0700 Received: from digraph.polyomino.org.uk (137.202.0.87) by svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) with Microsoft SMTP Server (TLS) id 15.0.1210.3; Mon, 12 Sep 2016 18:45:46 +0100 Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.86_2) (envelope-from ) id 1bjVIc-0004qz-AC; Mon, 12 Sep 2016 17:45:42 +0000 Date: Mon, 12 Sep 2016 17:45:42 +0000 From: Joseph Myers To: CC: , Subject: Make max_align_t respect _Float128 [version 3] In-Reply-To: Message-ID: References: User-Agent: Alpine 2.20 (DEB 67 2015-01-07) MIME-Version: 1.0 X-ClientProxiedBy: svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) To svr-ies-mbx-01.mgc.mentorg.com (139.181.222.1) [Patch version 3 is updated for Jason's changes to cxx_fundamental_alignment_p.] The _FloatN, _FloatNx, _DecimalN and _DecimalNx types are specified in such a way that they are basic types, meaning that max_align_t must be at least as aligned as those types. On 32-bit x86, max_align_t is currently 8-byte aligned, but _Decimal128 and _Float128 are 16-byte aligned, so the alignment of max_align_t needs to increase to meet the standard requirements for these types. This patch implements such an increase. Because max_align_t needs to be usable for C++ as well as for C, can't actually refer to _Float128, but needs to use __float128 (or some other notation for the type) instead. And since __float128 is architecture-specific, there isn't a preprocessor conditional that means "__float128 is available" (whereas one could test __FLT128_MANT_DIG__ to see if _Float128 is available; __SIZEOF_FLOAT128__ is available on x86 only). But I believe the only case that actually has an alignment problem here is 32-bit x86, and already has lots of conditional specific to particular architectures or OSes, so this patch uses a conditional on __i386__; that also is the minimal change that ensures neither size nor alignment of max_align_t is changed in any case other than where it is necessary. If any other architectures turn out to have such an issue, it will show up as failures of one of the testcases added by this patch. Such an increase is of course an ABI change, but a reasonably safe one, in that max_align_t doesn't tend to appear in library interfaces (rather, it's something to use when writing allocators and similar code; most matches found on codesearch.debian.net look like copies of the gnulib stddef.h module rather than anything actually using max_align_t at all). max_align_t_align has a corresponding change (adding _Float128 to the types considered). (I think glibc malloc alignment should also increase to 16-byte on 32-bit x86 so it works for allocating objects of these types, which is now straightforward given the fix made for 32-bit powerpc.) Bootstrapped with no regressions on x86_64-pc-linux-gnu, and spot-tested with -m32 that the new float128-align.c test now compiles where previously it didn't. OK to commit? gcc: 2016-09-12 Joseph Myers * ginclude/stddef.h (max_align_t) [__i386__]: Add __float128 element. gcc/c-family: 2016-09-12 Joseph Myers * c-common.c (max_align_t_align): Also consider alignment of float128_type_node. gcc/testsuite: 2016-09-12 Joseph Myers * gcc.dg/float128-align.c, gcc.dg/float128x-align.c, gcc.dg/float16-align.c, gcc.dg/float32-align.c, gcc.dg/float32x-align.c, gcc.dg/float64-align.c, gcc.dg/float64x-align.c, gcc.dg/floatn-align.h: New tests. Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c (revision 240091) +++ gcc/c-family/c-common.c (working copy) @@ -12873,8 +12873,11 @@ scalar_to_vector (location_t loc, enum tree_code c unsigned max_align_t_align () { - return MAX (TYPE_ALIGN (long_long_integer_type_node), - TYPE_ALIGN (long_double_type_node)); + unsigned int max_align = MAX (TYPE_ALIGN (long_long_integer_type_node), + TYPE_ALIGN (long_double_type_node)); + if (float128_type_node != NULL_TREE) + max_align = MAX (max_align, TYPE_ALIGN (float128_type_node)); + return max_align; } /* Return true iff ALIGN is an integral constant that is a fundamental Index: gcc/ginclude/stddef.h =================================================================== --- gcc/ginclude/stddef.h (revision 240091) +++ gcc/ginclude/stddef.h (working copy) @@ -426,6 +426,14 @@ typedef __WINT_TYPE__ wint_t; typedef struct { long long __max_align_ll __attribute__((__aligned__(__alignof__(long long)))); long double __max_align_ld __attribute__((__aligned__(__alignof__(long double)))); + /* _Float128 is defined as a basic type, so max_align_t must be + sufficiently aligned for it. This code must work in C++, so we + use __float128 here; that is only available on some + architectures, but only on i386 is extra alignment needed for + __float128. */ +#ifdef __i386__ + __float128 __max_align_f128 __attribute__((__aligned__(__alignof(__float128)))); +#endif } max_align_t; #endif #endif /* C11 or C++11. */ Index: gcc/testsuite/gcc.dg/float128-align.c =================================================================== --- gcc/testsuite/gcc.dg/float128-align.c (nonexistent) +++ gcc/testsuite/gcc.dg/float128-align.c (working copy) @@ -0,0 +1,9 @@ +/* Test _Float128 alignment. */ +/* { dg-do compile } */ +/* { dg-options "" } */ +/* { dg-add-options float128 } */ +/* { dg-require-effective-target float128 } */ + +#define WIDTH 128 +#define EXT 0 +#include "floatn-align.h" Index: gcc/testsuite/gcc.dg/float128x-align.c =================================================================== --- gcc/testsuite/gcc.dg/float128x-align.c (nonexistent) +++ gcc/testsuite/gcc.dg/float128x-align.c (working copy) @@ -0,0 +1,9 @@ +/* Test _Float128 alignment. */ +/* { dg-do compile } */ +/* { dg-options "" } */ +/* { dg-add-options float128x } */ +/* { dg-require-effective-target float128x } */ + +#define WIDTH 128 +#define EXT 1 +#include "floatn-align.h" Index: gcc/testsuite/gcc.dg/float16-align.c =================================================================== --- gcc/testsuite/gcc.dg/float16-align.c (nonexistent) +++ gcc/testsuite/gcc.dg/float16-align.c (working copy) @@ -0,0 +1,9 @@ +/* Test _Float16 alignment. */ +/* { dg-do compile } */ +/* { dg-options "" } */ +/* { dg-add-options float16 } */ +/* { dg-require-effective-target float16 } */ + +#define WIDTH 16 +#define EXT 0 +#include "floatn-align.h" Index: gcc/testsuite/gcc.dg/float32-align.c =================================================================== --- gcc/testsuite/gcc.dg/float32-align.c (nonexistent) +++ gcc/testsuite/gcc.dg/float32-align.c (working copy) @@ -0,0 +1,9 @@ +/* Test _Float32 alignment. */ +/* { dg-do compile } */ +/* { dg-options "" } */ +/* { dg-add-options float32 } */ +/* { dg-require-effective-target float32 } */ + +#define WIDTH 32 +#define EXT 0 +#include "floatn-align.h" Index: gcc/testsuite/gcc.dg/float32x-align.c =================================================================== --- gcc/testsuite/gcc.dg/float32x-align.c (nonexistent) +++ gcc/testsuite/gcc.dg/float32x-align.c (working copy) @@ -0,0 +1,9 @@ +/* Test _Float32 alignment. */ +/* { dg-do compile } */ +/* { dg-options "" } */ +/* { dg-add-options float32x } */ +/* { dg-require-effective-target float32x } */ + +#define WIDTH 32 +#define EXT 1 +#include "floatn-align.h" Index: gcc/testsuite/gcc.dg/float64-align.c =================================================================== --- gcc/testsuite/gcc.dg/float64-align.c (nonexistent) +++ gcc/testsuite/gcc.dg/float64-align.c (working copy) @@ -0,0 +1,9 @@ +/* Test _Float64 alignment. */ +/* { dg-do compile } */ +/* { dg-options "" } */ +/* { dg-add-options float64 } */ +/* { dg-require-effective-target float64 } */ + +#define WIDTH 64 +#define EXT 0 +#include "floatn-align.h" Index: gcc/testsuite/gcc.dg/float64x-align.c =================================================================== --- gcc/testsuite/gcc.dg/float64x-align.c (nonexistent) +++ gcc/testsuite/gcc.dg/float64x-align.c (working copy) @@ -0,0 +1,9 @@ +/* Test _Float64 alignment. */ +/* { dg-do compile } */ +/* { dg-options "" } */ +/* { dg-add-options float64x } */ +/* { dg-require-effective-target float64x } */ + +#define WIDTH 64 +#define EXT 1 +#include "floatn-align.h" Index: gcc/testsuite/gcc.dg/floatn-align.h =================================================================== --- gcc/testsuite/gcc.dg/floatn-align.h (nonexistent) +++ gcc/testsuite/gcc.dg/floatn-align.h (working copy) @@ -0,0 +1,18 @@ +/* Tests for _FloatN / _FloatNx types: test max_align_t alignment. + Before including this file, define WIDTH as the value N; define EXT + to 1 for _FloatNx and 0 for _FloatN. */ + +#define CONCATX(X, Y) X ## Y +#define CONCAT(X, Y) CONCATX (X, Y) +#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z) + +#if EXT +# define TYPE CONCAT3 (_Float, WIDTH, x) +#else +# define TYPE CONCAT (_Float, WIDTH) +#endif + +#include + +_Static_assert (_Alignof (max_align_t) >= _Alignof (TYPE), + "max_align_t must be at least as aligned as _Float* types");