Skip to content

Commit 456cab2

Browse files
committed
Extend configure's __int128 test to check for a known gcc bug.
On Sparc64, use of __attribute__(aligned(8)) with __int128 causes faulty code generation in gcc versions at least through 5.5.0. We can work around that by disabling use of __int128, so teach configure to test for the bug. This solution doesn't fix things for the case of cross-compiling with a buggy compiler; to support that nicely, we'd need to add a manual disable switch. Unless more such cases turn up, it doesn't seem worth the work. Affected users could always edit pg_config.h manually. In passing, fix some typos in the existing configure test for __int128. They're harmless because we only compile that code not run it, but they're still confusing for anyone looking at it closely. This is needed in support of commit 7518049, so back-patch to 9.5 as that was. Marina Polyakova, Victor Wagner, Tom Lane Discussion: https://postgr.es/m/0d3a9fa264cebe1cb9966f37b7c06e86@postgrespro.ru
1 parent 4a81c02 commit 456cab2

File tree

2 files changed

+105
-15
lines changed

2 files changed

+105
-15
lines changed

config/c-compiler.m4

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,29 +106,61 @@ AC_DEFUN([PGAC_TYPE_128BIT_INT],
106106
[AC_CACHE_CHECK([for __int128], [pgac_cv__128bit_int],
107107
[AC_LINK_IFELSE([AC_LANG_PROGRAM([
108108
/*
109+
* We don't actually run this test, just link it to verify that any support
110+
* functions needed for __int128 are present.
111+
*
109112
* These are globals to discourage the compiler from folding all the
110113
* arithmetic tests down to compile-time constants. We do not have
111-
* convenient support for 64bit literals at this point...
114+
* convenient support for 128bit literals at this point...
112115
*/
113116
__int128 a = 48828125;
114-
__int128 b = 97656255;
117+
__int128 b = 97656250;
115118
],[
116119
__int128 c,d;
117120
a = (a << 12) + 1; /* 200000000001 */
118121
b = (b << 12) + 5; /* 400000000005 */
119-
/* use the most relevant arithmetic ops */
122+
/* try the most relevant arithmetic ops */
120123
c = a * b;
121124
d = (c + b) / b;
122-
/* return different values, to prevent optimizations */
125+
/* must use the results, else compiler may optimize arithmetic away */
123126
if (d != a+1)
124-
return 0;
125-
return 1;
127+
return 1;
126128
])],
127129
[pgac_cv__128bit_int=yes],
128130
[pgac_cv__128bit_int=no])])
129131
if test x"$pgac_cv__128bit_int" = xyes ; then
130-
AC_DEFINE(PG_INT128_TYPE, __int128, [Define to the name of a signed 128-bit integer type.])
131-
AC_CHECK_ALIGNOF(PG_INT128_TYPE)
132+
# Use of non-default alignment with __int128 tickles bugs in some compilers.
133+
# If not cross-compiling, we can test for bugs and disable use of __int128
134+
# with buggy compilers. If cross-compiling, hope for the best.
135+
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83925
136+
AC_CACHE_CHECK([for __int128 alignment bug], [pgac_cv__128bit_int_bug],
137+
[AC_RUN_IFELSE([AC_LANG_PROGRAM([
138+
/* This must match the corresponding code in c.h: */
139+
#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__)
140+
#define pg_attribute_aligned(a) __attribute__((aligned(a)))
141+
#endif
142+
typedef __int128 int128a
143+
#if defined(pg_attribute_aligned)
144+
pg_attribute_aligned(8)
145+
#endif
146+
;
147+
int128a holder;
148+
void pass_by_val(void *buffer, int128a par) { holder = par; }
149+
],[
150+
long int i64 = 97656225L << 12;
151+
int128a q;
152+
pass_by_val(main, (int128a) i64);
153+
q = (int128a) i64;
154+
if (q != holder)
155+
return 1;
156+
])],
157+
[pgac_cv__128bit_int_bug=ok],
158+
[pgac_cv__128bit_int_bug=broken],
159+
[pgac_cv__128bit_int_bug="assuming ok"])])
160+
if test x"$pgac_cv__128bit_int_bug" != xbroken ; then
161+
AC_DEFINE(PG_INT128_TYPE, __int128, [Define to the name of a signed 128-bit integer type.])
162+
AC_CHECK_ALIGNOF(PG_INT128_TYPE)
163+
fi
132164
fi])# PGAC_TYPE_128BIT_INT
133165

134166

configure

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14355,12 +14355,15 @@ else
1435514355
/* end confdefs.h. */
1435614356
1435714357
/*
14358+
* We don't actually run this test, just link it to verify that any support
14359+
* functions needed for __int128 are present.
14360+
*
1435814361
* These are globals to discourage the compiler from folding all the
1435914362
* arithmetic tests down to compile-time constants. We do not have
14360-
* convenient support for 64bit literals at this point...
14363+
* convenient support for 128bit literals at this point...
1436114364
*/
1436214365
__int128 a = 48828125;
14363-
__int128 b = 97656255;
14366+
__int128 b = 97656250;
1436414367
1436514368
int
1436614369
main ()
@@ -14369,13 +14372,12 @@ main ()
1436914372
__int128 c,d;
1437014373
a = (a << 12) + 1; /* 200000000001 */
1437114374
b = (b << 12) + 5; /* 400000000005 */
14372-
/* use the most relevant arithmetic ops */
14375+
/* try the most relevant arithmetic ops */
1437314376
c = a * b;
1437414377
d = (c + b) / b;
14375-
/* return different values, to prevent optimizations */
14378+
/* must use the results, else compiler may optimize arithmetic away */
1437614379
if (d != a+1)
14377-
return 0;
14378-
return 1;
14380+
return 1;
1437914381
1438014382
;
1438114383
return 0;
@@ -14392,10 +14394,65 @@ fi
1439214394
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__128bit_int" >&5
1439314395
$as_echo "$pgac_cv__128bit_int" >&6; }
1439414396
if test x"$pgac_cv__128bit_int" = xyes ; then
14397+
# Use of non-default alignment with __int128 tickles bugs in some compilers.
14398+
# If not cross-compiling, we can test for bugs and disable use of __int128
14399+
# with buggy compilers. If cross-compiling, hope for the best.
14400+
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83925
14401+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __int128 alignment bug" >&5
14402+
$as_echo_n "checking for __int128 alignment bug... " >&6; }
14403+
if ${pgac_cv__128bit_int_bug+:} false; then :
14404+
$as_echo_n "(cached) " >&6
14405+
else
14406+
if test "$cross_compiling" = yes; then :
14407+
pgac_cv__128bit_int_bug="assuming ok"
14408+
else
14409+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
14410+
/* end confdefs.h. */
14411+
14412+
/* This must match the corresponding code in c.h: */
14413+
#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__)
14414+
#define pg_attribute_aligned(a) __attribute__((aligned(a)))
14415+
#endif
14416+
typedef __int128 int128a
14417+
#if defined(pg_attribute_aligned)
14418+
pg_attribute_aligned(8)
14419+
#endif
14420+
;
14421+
int128a holder;
14422+
void pass_by_val(void *buffer, int128a par) { holder = par; }
14423+
14424+
int
14425+
main ()
14426+
{
14427+
14428+
long int i64 = 97656225L << 12;
14429+
int128a q;
14430+
pass_by_val(main, (int128a) i64);
14431+
q = (int128a) i64;
14432+
if (q != holder)
14433+
return 1;
14434+
14435+
;
14436+
return 0;
14437+
}
14438+
_ACEOF
14439+
if ac_fn_c_try_run "$LINENO"; then :
14440+
pgac_cv__128bit_int_bug=ok
14441+
else
14442+
pgac_cv__128bit_int_bug=broken
14443+
fi
14444+
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
14445+
conftest.$ac_objext conftest.beam conftest.$ac_ext
14446+
fi
14447+
14448+
fi
14449+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__128bit_int_bug" >&5
14450+
$as_echo "$pgac_cv__128bit_int_bug" >&6; }
14451+
if test x"$pgac_cv__128bit_int_bug" != xbroken ; then
1439514452

1439614453
$as_echo "#define PG_INT128_TYPE __int128" >>confdefs.h
1439714454

14398-
# The cast to long int works around a bug in the HP C Compiler,
14455+
# The cast to long int works around a bug in the HP C Compiler,
1439914456
# see AC_CHECK_SIZEOF for more information.
1440014457
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of PG_INT128_TYPE" >&5
1440114458
$as_echo_n "checking alignment of PG_INT128_TYPE... " >&6; }
@@ -14430,6 +14487,7 @@ cat >>confdefs.h <<_ACEOF
1443014487
_ACEOF
1443114488

1443214489

14490+
fi
1443314491
fi
1443414492

1443514493
# Check for various atomic operations now that we have checked how to declare

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy