public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Make max_align_t respect _Float128
@ 2016-08-26 20:55 Joseph Myers
  2016-08-26 21:10 ` Marc Glisse
                   ` (4 more replies)
  0 siblings, 5 replies; 51+ messages in thread
From: Joseph Myers @ 2016-08-26 20:55 UTC (permalink / raw)
  To: gcc-patches; +Cc: fweimer, eggert

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, <stddef.h> 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).  But I believe the only case that actually has an
alignment problem here is 32-bit x86, and <stddef.h> already has lots
of conditional specific to particular architectures or OSes, so this
patch uses a conditional on __i386__.  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).

(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-08-26  Joseph Myers  <joseph@codesourcery.com>

	* ginclude/stddef.h (max_align_t) [__i386__]: Add __float128
	element.

gcc/testsuite:
2016-08-26  Joseph Myers  <joseph@codesourcery.com>

	* 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/ginclude/stddef.h
===================================================================
--- gcc/ginclude/stddef.h	(revision 239784)
+++ gcc/ginclude/stddef.h	(working copy)
@@ -426,6 +426,14 @@
 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 <stddef.h>
+
+_Static_assert (_Alignof (max_align_t) >= _Alignof (TYPE),
+		"max_align_t must be at least as aligned as _Float* types");

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 51+ messages in thread
* Re: Make max_align_t respect _Float128 [version 2]
@ 2016-09-06 18:14 Bernd Edlinger
  2016-09-06 20:58 ` Joseph Myers
  0 siblings, 1 reply; 51+ messages in thread
From: Bernd Edlinger @ 2016-09-06 18:14 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Paul Eggert, Florian Weimer, gcc-patches

Hi,

I'd like to share some of my thoughts about the max_align_t,
if you don't mind.

I think that for _Float128 to become a fundamental data type,
it is *not* sufficient that gcc supports it alone, because glibc
needs to support also all the necessary math library functions.

When that is done, glibc can also increase the malloc alignment.
That will mean that programs built for glibc-2.24 will not
run on old glibc installations.

I think that glibc-2.24 will still have to support older
gcc versions, and should make malloc alignment be fixed,
even if an application is built using an old gcc version,
or am I wrong, which is possible here?

I have some doubt that it will work to change max_align_t's
alignment only based on the gcc version, I mean
there should be a way to allow the max_align_t keep at
8 bytes if the existing glibc will not support 16 bytes.

I *think*, there should be some kind of hand-shake in the
max_align_t to enable __float128 when gcc supports that,
*and* glibc supports that at the same time.

Like, maybe including some glibc-header, that defines some
macro, what the real malloc alignment will be.  And probably
some builtin-macro, if gcc supports __float128, independently
of the i386, that could probably also be helpful for writing
portable applications.



Bernd.

^ permalink raw reply	[flat|nested] 51+ messages in thread
* Re: Make max_align_t respect _Float128 [version 2]
@ 2016-09-07 19:50 Bernd Edlinger
  2016-09-07 20:06 ` Joseph Myers
  2016-09-08 10:50 ` Florian Weimer
  0 siblings, 2 replies; 51+ messages in thread
From: Bernd Edlinger @ 2016-09-07 19:50 UTC (permalink / raw)
  To: Joseph Myers; +Cc: Florian Weimer, Richard Biener, Paul Eggert, gcc-patches

On Wed, 7 Sep 2016, Joseph Myers wrote:
 > On Wed, 7 Sep 2016, Florian Weimer wrote:
 >
 > > The existence of such a cut-off constant appears useful, but it's 
not clear if
 > > it should be tied to the fundamental alignment (especially, as this 
discussion
 > > shows, the fundamental alignment will be somewhat in flux).
 >
 > I don't think it's in flux.  I think it's very rare for a new basic type
 > to be added that has increased alignment requirements compared to the
 > existing basic types.  _Decimal128 was added in GCC 4.3, which increased
 > the requirement on 32-bit x86 (only) (32-bit x86 malloc having been 
buggy
 > in that regard ever since then); __float128 / _Float128 did not increase
 > the requirement relative to that introduced with _Decimal128. 
(Obviously
 > if CPLEX part 2 defines vector types that might have larger alignment
requirements it must avoid defining them as basic types.)


Hmm...

interesting.  I just tried the test case from PR 77330 with _Decimal128.
result: _Decimal128 did *not* trap with gcc4.8.4, but it does trap with
gcc-7.0.0.

include <stdio.h>
#include <stdlib.h>

struct s {
         _Decimal128 f1;
};

int main(void)
{
         struct s *p = malloc(sizeof(struct s));
         printf("%p\n", p);
         p->f1 = 1.234;
         return 0;
}

gcc -m32 test.c

./a.out
0x9588008
Segmentation fault (core dumped)


So it looks to me, the ABI has changed incompatible recently, and I
believe that we need to proceed more carefully here.  While in the
the future most targets will support aligned _Float128, we can
still support 4-byte aligned _Decimal128 on a per-target base.

I think that we need more flexibility in that area than we have
right now, because config/i386/i386.h is doing the ABI,
but it is shared by linux/glibc, windows, vxworks, darwin,
solaris, to name a few.  I can't believe that we can just
change that ABI for the whole world at the same time.

See my experiment at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77330#c9
which may be a hack, but shows that is no impossibility.



Bernd.

^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2016-09-26 16:28 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-26 20:55 Make max_align_t respect _Float128 Joseph Myers
2016-08-26 21:10 ` Marc Glisse
2016-08-26 21:30   ` Joseph Myers
2016-08-26 21:45 ` Florian Weimer
2016-08-26 21:57   ` Paul Eggert
2016-08-26 22:25   ` Joseph Myers
2016-08-26 21:51 ` Paul Eggert
2016-08-29 13:29   ` Marek Polacek
2016-08-29 15:40     ` Joseph Myers
2016-09-01 14:18 ` Ping " Joseph Myers
2016-09-05 17:07 ` Make max_align_t respect _Float128 [version 2] Joseph Myers
2016-09-06  9:06   ` Richard Biener
2016-09-06 11:26     ` Joseph Myers
2016-09-06  9:19   ` Florian Weimer
2016-09-06  9:24     ` Richard Biener
2016-09-07  7:45       ` Florian Weimer
2016-09-07 17:53         ` Joseph Myers
2016-09-08  9:35           ` Florian Weimer
2016-09-06 11:40     ` Joseph Myers
2016-09-06 15:06       ` Florian Weimer
2016-09-06 15:20         ` Joseph Myers
2016-09-06 15:59           ` Paul Eggert
2016-09-06 20:47             ` Joseph Myers
2016-09-06 21:41               ` Paul Eggert
2016-09-07  9:22                 ` Florian Weimer
2016-09-07 11:52                   ` Mark Wielaard
2016-09-08  1:58                     ` Paul Eggert
2016-09-08 11:58                       ` Mark Wielaard
2016-09-08 12:22                         ` Florian Weimer
2016-09-08 14:59                         ` Paul Eggert
2016-09-08 12:30                       ` Bernd Schmidt
2016-09-08 12:34                         ` Florian Weimer
2016-09-07  9:15               ` Florian Weimer
2016-09-06 21:03           ` Jason Merrill
2016-09-06 21:18             ` Joseph Myers
2016-09-06 21:53               ` Jason Merrill
2016-09-06 21:56                 ` Joseph Myers
2016-09-06 12:06     ` Bernd Schmidt
2016-09-06 14:59       ` Florian Weimer
2016-09-12 18:02   ` Make max_align_t respect _Float128 [version 3] Joseph Myers
2016-09-19 16:08     ` Ping " Joseph Myers
2016-09-19 17:11       ` Paul Eggert
2016-09-26 16:35       ` Jeff Law
2016-09-06 18:14 Make max_align_t respect _Float128 [version 2] Bernd Edlinger
2016-09-06 20:58 ` Joseph Myers
2016-09-07 19:50 Bernd Edlinger
2016-09-07 20:06 ` Joseph Myers
2016-09-07 21:00   ` Bernd Edlinger
2016-09-07 21:48     ` Joseph Myers
2016-09-08 10:50 ` Florian Weimer
2016-09-09 17:24   ` Bernd Edlinger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).