8000 Extend configure's __int128 test to check for a known gcc bug. · postgres/postgres@456cab2 · GitHub
[go: up one dir, main page]

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)
0