Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5dcbdcb

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 3f05a30 commit 5dcbdcb

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

136168

configure

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14886,12 +14886,15 @@ else
1488614886
/* end confdefs.h. */
1488714887
1488814888
/*
14889+
* We don't actually run this test, just link it to verify that any support
14890+
* functions needed for __int128 are present.
14891+
*
1488914892
* These are globals to discourage the compiler from folding all the
1489014893
* arithmetic tests down to compile-time constants. We do not have
14891-
* convenient support for 64bit literals at this point...
14894+
* convenient support for 128bit literals at this point...
1489214895
*/
1489314896
__int128 a = 48828125;
14894-
__int128 b = 97656255;
14897+
__int128 b = 97656250;
1489514898
1489614899
int
1489714900
main ()
@@ -14900,13 +14903,12 @@ main ()
1490014903
__int128 c,d;
1490114904
a = (a << 12) + 1; /* 200000000001 */
1490214905
b = (b << 12) + 5; /* 400000000005 */
14903-
/* use the most relevant arithmetic ops */
14906+
/* try the most relevant arithmetic ops */
1490414907
c = a * b;
1490514908
d = (c + b) / b;
14906-
/* return different values, to prevent optimizations */
14909+
/* must use the results, else compiler may optimize arithmetic away */
1490714910
if (d != a+1)
14908-
return 0;
14909-
return 1;
14911+
return 1;
1491014912
1491114913
;
1491214914
return 0;
@@ -14923,10 +14925,65 @@ fi
1492314925
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__128bit_int" >&5
1492414926
$as_echo "$pgac_cv__128bit_int" >&6; }
1492514927
if test x"$pgac_cv__128bit_int" = xyes ; then
14928+
# Use of non-default alignment with __int128 tickles bugs in some compilers.
14929+
# If not cross-compiling, we can test for bugs and disable use of __int128
14930+
# with buggy compilers. If cross-compiling, hope for the best.
14931+
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83925
14932+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __int128 alignment bug" >&5
14933+
$as_echo_n "checking for __int128 alignment bug... " >&6; }
14934+
if ${pgac_cv__128bit_int_bug+:} false; then :
14935+
$as_echo_n "(cached) " >&6
14936+
else
14937+
if test "$cross_compiling" = yes; then :
14938+
pgac_cv__128bit_int_bug="assuming ok"
14939+
else
14940+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
14941+
/* end confdefs.h. */
14942+
14943+
/* This must match the corresponding code in c.h: */
14944+
#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__IBMC__)
14945+
#define pg_attribute_aligned(a) __attribute__((aligned(a)))
14946+
#endif
14947+
typedef __int128 int128a
14948+
#if defined(pg_attribute_aligned)
14949+
pg_attribute_aligned(8)
14950+
#endif
14951+
;
14952+
int128a holder;
14953+
void pass_by_val(void *buffer, int128a par) { holder = par; }
14954+
14955+
int
14956+
main ()
14957+
{
14958+
14959+
long int i64 = 97656225L << 12;
14960+
int128a q;
14961+
pass_by_val(main, (int128a) i64);
14962+
q = (int128a) i64;
14963+
if (q != holder)
14964+
return 1;
14965+
14966+
;
14967+
return 0;
14968+
}
14969+
_ACEOF
14970+
if ac_fn_c_try_run "$LINENO"; then :
14971+
pgac_cv__128bit_int_bug=ok
14972+
else
14973+
pgac_cv__128bit_int_bug=broken
14974+
fi
14975+
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
14976+
conftest.$ac_objext conftest.beam conftest.$ac_ext
14977+
fi
14978+
14979+
fi
14980+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__128bit_int_bug" >&5
14981+
$as_echo "$pgac_cv__128bit_int_bug" >&6; }
14982+
if test x"$pgac_cv__128bit_int_bug" != xbroken ; then
1492614983

1492714984
$as_echo "#define PG_INT128_TYPE __int128" >>confdefs.h
1492814985

14929-
# The cast to long int works around a bug in the HP C Compiler,
14986+
# The cast to long int works around a bug in the HP C Compiler,
1493014987
# see AC_CHECK_SIZEOF for more information.
1493114988
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking alignment of PG_INT128_TYPE" >&5
1493214989
$as_echo_n "checking alignment of PG_INT128_TYPE... " >&6; }
@@ -14961,6 +15018,7 @@ cat >>confdefs.h <<_ACEOF
1496115018
_ACEOF
1496215019

1496315020

15021+
fi
1496415022
fi
1496515023

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

0 commit comments

Comments
 (0)