mirror of https://github.com/python/cpython
Properly detect float word ordering on Linux (gh-125571) autoconf-archive patch by Dan Amelang. (cherry picked from commit26d627779f
) Hardcode WASM float word ordering to little endian (gh-126387) (cherry picked from commit532fc08102
)
This commit is contained in:
parent
88e01318c2
commit
9dd3addc0c
|
@ -89,7 +89,7 @@ jobs:
|
|||
# reproducible: to get the same tools versions (autoconf, aclocal, ...)
|
||||
runs-on: ubuntu-24.04
|
||||
container:
|
||||
image: ghcr.io/python/autoconf:2024.10.11.11293396815
|
||||
image: ghcr.io/python/autoconf:2024.10.16.11360930377
|
||||
timeout-minutes: 60
|
||||
needs: check_source
|
||||
if: needs.check_source.outputs.run_tests == 'true'
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Improve detection of float word ordering on Linux when link-time optimizations
|
||||
are enabled.
|
|
@ -0,0 +1 @@
|
|||
Hard-code float word ordering as little endian on WASM.
|
|
@ -5,7 +5,7 @@ set -e -x
|
|||
# The check_autoconf_regen job of .github/workflows/build.yml must kept in
|
||||
# sync with this script. Use the same container image than the job so the job
|
||||
# doesn't need to run autoreconf in a container.
|
||||
IMAGE="ghcr.io/python/autoconf:2024.10.06.11200919239"
|
||||
IMAGE="ghcr.io/python/autoconf:2024.10.16.11360930377"
|
||||
AUTORECONF="autoreconf -ivf -Werror"
|
||||
|
||||
WORK_DIR="/src"
|
||||
|
|
|
@ -41,32 +41,81 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun
|
|||
# If neither value is found, the user is instructed to specify the
|
||||
# ordering.
|
||||
#
|
||||
# Early versions of this macro (i.e., before serial 12) would not work
|
||||
# when interprocedural optimization (via link-time optimization) was
|
||||
# enabled. This would happen when, say, the GCC/clang "-flto" flag, or the
|
||||
# ICC "-ipo" flag was used, for example. The problem was that under
|
||||
# these conditions, the compiler did not allocate for and write the special
|
||||
# float value in the data segment of the object file, since doing so might
|
||||
# not prove optimal once more context was available. Thus, the special value
|
||||
# (in platform-dependent binary form) could not be found in the object file,
|
||||
# and the macro would fail.
|
||||
#
|
||||
# The solution to the above problem was to:
|
||||
#
|
||||
# 1) Compile and link a whole test program rather than just compile an
|
||||
# object file. This ensures that we reach the point where even an
|
||||
# interprocedural optimizing compiler writes values to the data segment.
|
||||
#
|
||||
# 2) Add code that requires the compiler to write the special value to
|
||||
# the data segment, as opposed to "optimizing away" the variable's
|
||||
# allocation. This could be done via compiler keywords or options, but
|
||||
# it's tricky to make this work for all versions of all compilers with
|
||||
# all optimization settings. The chosen solution was to make the exit
|
||||
# code of the test program depend on the storing of the special value
|
||||
# in memory (in the data segment). Because the exit code can be
|
||||
# verified, any compiler that aspires to be correct will produce a
|
||||
# program binary that contains the value, which the macro can then find.
|
||||
#
|
||||
# How does the exit code depend on the special value residing in memory?
|
||||
# Memory, unlike variables and registers, can be addressed indirectly at run
|
||||
# time. The exit code of this test program is a result of indirectly reading
|
||||
# and writing to the memory region where the special value is supposed to
|
||||
# reside. The actual memory addresses used and the values to be written are
|
||||
# derived from the the program input ("argv") and are therefore not known at
|
||||
# compile or link time. The compiler has no choice but to defer the
|
||||
# computation to run time, and to prepare by allocating and populating the
|
||||
# data segment with the special value. For further details, refer to the
|
||||
# source code of the test program.
|
||||
#
|
||||
# Note that the test program is never meant to be run. It only exists to host
|
||||
# a double float value in a given platform's binary format. Thus, error
|
||||
# handling is not included.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Daniel Amelang <dan@amelang.net>
|
||||
# Copyright (c) 2008, 2023 Daniel Amelang <dan@amelang.net>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 11
|
||||
#serial 12
|
||||
|
||||
AC_DEFUN([AX_C_FLOAT_WORDS_BIGENDIAN],
|
||||
[AC_CACHE_CHECK(whether float word ordering is bigendian,
|
||||
ax_cv_c_float_words_bigendian, [
|
||||
|
||||
ax_cv_c_float_words_bigendian=unknown
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
AC_LINK_IFELSE([AC_LANG_SOURCE([[
|
||||
|
||||
double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0;
|
||||
#include <stdlib.h>
|
||||
|
||||
static double m[] = {9.090423496703681e+223, 0.0};
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
m[atoi (argv[1])] += atof (argv[2]);
|
||||
return m[atoi (argv[3])] > 0.0;
|
||||
}
|
||||
|
||||
]])], [
|
||||
|
||||
if grep noonsees conftest.$ac_objext >/dev/null ; then
|
||||
if grep noonsees conftest$EXEEXT >/dev/null ; then
|
||||
ax_cv_c_float_words_bigendian=yes
|
||||
fi
|
||||
if grep seesnoon conftest.$ac_objext >/dev/null ; then
|
||||
if grep seesnoon conftest$EXEEXT >/dev/null ; then
|
||||
if test "$ax_cv_c_float_words_bigendian" = unknown; then
|
||||
ax_cv_c_float_words_bigendian=no
|
||||
else
|
||||
|
|
|
@ -23703,18 +23703,26 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|||
/* end confdefs.h. */
|
||||
|
||||
|
||||
double d = 90904234967036810337470478905505011476211692735615632014797120844053488865816695273723469097858056257517020191247487429516932130503560650002327564517570778480236724525140520121371739201496540132640109977779420565776568942592.0;
|
||||
#include <stdlib.h>
|
||||
|
||||
static double m[] = {9.090423496703681e+223, 0.0};
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
m[atoi (argv[1])] += atof (argv[2]);
|
||||
return m[atoi (argv[3])] > 0.0;
|
||||
}
|
||||
|
||||
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
|
||||
|
||||
if grep noonsees conftest.$ac_objext >/dev/null ; then
|
||||
if grep noonsees conftest$EXEEXT >/dev/null ; then
|
||||
ax_cv_c_float_words_bigendian=yes
|
||||
fi
|
||||
if grep seesnoon conftest.$ac_objext >/dev/null ; then
|
||||
if grep seesnoon conftest$EXEEXT >/dev/null ; then
|
||||
if test "$ax_cv_c_float_words_bigendian" = unknown; then
|
||||
ax_cv_c_float_words_bigendian=no
|
||||
else
|
||||
|
@ -23724,7 +23732,8 @@ fi
|
|||
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_c_float_words_bigendian" >&5
|
||||
printf "%s\n" "$ax_cv_c_float_words_bigendian" >&6; }
|
||||
|
@ -23732,41 +23741,34 @@ printf "%s\n" "$ax_cv_c_float_words_bigendian" >&6; }
|
|||
case $ax_cv_c_float_words_bigendian in
|
||||
yes)
|
||||
|
||||
printf "%s\n" "#define FLOAT_WORDS_BIGENDIAN 1" >>confdefs.h
|
||||
printf "%s\n" "#define DOUBLE_IS_BIG_ENDIAN_IEEE754 1" >>confdefs.h
|
||||
;;
|
||||
no)
|
||||
|
||||
printf "%s\n" "#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1" >>confdefs.h
|
||||
;;
|
||||
*)
|
||||
as_fn_error $? "
|
||||
case $host_cpu in #(
|
||||
*arm*) :
|
||||
# Some ARM platforms use a mixed-endian representation for
|
||||
# doubles. While Python doesn't currently have full support
|
||||
# for these platforms (see e.g., issue 1762561), we can at
|
||||
# least make sure that float <-> string conversions work.
|
||||
# FLOAT_WORDS_BIGENDIAN doesn't actually detect this case,
|
||||
# but if it's not big or little, then it must be this?
|
||||
|
||||
Unknown float word ordering. You need to manually preset
|
||||
ax_cv_c_float_words_bigendian=no (or yes) according to your system.
|
||||
printf "%s\n" "#define DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 1" >>confdefs.h
|
||||
;; #(
|
||||
wasm*) :
|
||||
|
||||
" "$LINENO" 5 ;;
|
||||
printf "%s\n" "#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1" >>confdefs.h
|
||||
;; #(
|
||||
*) :
|
||||
;;
|
||||
esac ;;
|
||||
esac
|
||||
|
||||
|
||||
if test "$ax_cv_c_float_words_bigendian" = "yes"
|
||||
then
|
||||
|
||||
printf "%s\n" "#define DOUBLE_IS_BIG_ENDIAN_IEEE754 1" >>confdefs.h
|
||||
|
||||
elif test "$ax_cv_c_float_words_bigendian" = "no"
|
||||
then
|
||||
|
||||
printf "%s\n" "#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754 1" >>confdefs.h
|
||||
|
||||
else
|
||||
# Some ARM platforms use a mixed-endian representation for doubles.
|
||||
# While Python doesn't currently have full support for these platforms
|
||||
# (see e.g., issue 1762561), we can at least make sure that float <-> string
|
||||
# conversions work.
|
||||
# FLOAT_WORDS_BIGENDIAN doesn't actually detect this case, but if it's not big
|
||||
# or little, then it must be this?
|
||||
|
||||
printf "%s\n" "#define DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
# The short float repr introduced in Python 3.1 requires the
|
||||
# correctly-rounded string <-> double conversion functions from
|
||||
|
|
40
configure.ac
40
configure.ac
|
@ -5856,28 +5856,26 @@ AS_VAR_IF([ac_cv_gcc_asm_for_x64], [yes], [
|
|||
# * Check for various properties of floating point *
|
||||
# **************************************************
|
||||
|
||||
AX_C_FLOAT_WORDS_BIGENDIAN
|
||||
if test "$ax_cv_c_float_words_bigendian" = "yes"
|
||||
then
|
||||
AC_DEFINE([DOUBLE_IS_BIG_ENDIAN_IEEE754], [1],
|
||||
[Define if C doubles are 64-bit IEEE 754 binary format, stored
|
||||
with the most significant byte first])
|
||||
elif test "$ax_cv_c_float_words_bigendian" = "no"
|
||||
then
|
||||
AC_DEFINE([DOUBLE_IS_LITTLE_ENDIAN_IEEE754], [1],
|
||||
[Define if C doubles are 64-bit IEEE 754 binary format, stored
|
||||
with the least significant byte first])
|
||||
else
|
||||
# Some ARM platforms use a mixed-endian representation for doubles.
|
||||
# While Python doesn't currently have full support for these platforms
|
||||
# (see e.g., issue 1762561), we can at least make sure that float <-> string
|
||||
# conversions work.
|
||||
# FLOAT_WORDS_BIGENDIAN doesn't actually detect this case, but if it's not big
|
||||
# or little, then it must be this?
|
||||
AX_C_FLOAT_WORDS_BIGENDIAN(
|
||||
[AC_DEFINE([DOUBLE_IS_BIG_ENDIAN_IEEE754], [1],
|
||||
[Define if C doubles are 64-bit IEEE 754 binary format,
|
||||
stored with the most significant byte first])],
|
||||
[AC_DEFINE([DOUBLE_IS_LITTLE_ENDIAN_IEEE754], [1],
|
||||
[Define if C doubles are 64-bit IEEE 754 binary format,
|
||||
stored with the least significant byte first])],
|
||||
[AS_CASE([$host_cpu],
|
||||
[*arm*], [# Some ARM platforms use a mixed-endian representation for
|
||||
# doubles. While Python doesn't currently have full support
|
||||
# for these platforms (see e.g., issue 1762561), we can at
|
||||
# least make sure that float <-> string conversions work.
|
||||
# FLOAT_WORDS_BIGENDIAN doesn't actually detect this case,
|
||||
# but if it's not big or little, then it must be this?
|
||||
AC_DEFINE([DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754], [1],
|
||||
[Define if C doubles are 64-bit IEEE 754 binary format, stored
|
||||
in ARM mixed-endian order (byte order 45670123)])
|
||||
fi
|
||||
[Define if C doubles are 64-bit IEEE 754 binary format,
|
||||
stored in ARM mixed-endian order (byte order 45670123)])],
|
||||
[wasm*], [AC_DEFINE([DOUBLE_IS_LITTLE_ENDIAN_IEEE754], [1],
|
||||
[Define if C doubles are 64-bit IEEE 754 binary format,
|
||||
stored with the least significant byte first])])])
|
||||
|
||||
# The short float repr introduced in Python 3.1 requires the
|
||||
# correctly-rounded string <-> double conversion functions from
|
||||
|
|
|
@ -47,10 +47,6 @@
|
|||
/* Define if --enable-ipv6 is specified */
|
||||
#undef ENABLE_IPV6
|
||||
|
||||
/* Define to 1 if your system stores words within floats with the most
|
||||
significant word first */
|
||||
#undef FLOAT_WORDS_BIGENDIAN
|
||||
|
||||
/* Define if getpgrp() must be called as getpgrp(0). */
|
||||
#undef GETPGRP_HAVE_ARG
|
||||
|
||||
|
|
Loading…
Reference in New Issue