Subject: Re: bug#72145: rare Emacs screwups on x86 due to GCC bug 58416

From: Paul Eggert <[email-masked]>
Date: Fri, 19 Jul 2024 14:31:45 -0700

On 2024-07-18 08:19, Pip Cet wrote:
> It should be mentioned that this isn't just about the CPU: the OS also needs to enable the XMM register set, right?

Right.

In <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58416#c10> GCC's 
Richard Biener suggested a more portable workaround: use -fno-tree-sra 
when generating 32-bit x86 code for which it is not known that SSE2 is 
supported. (With SSE2, -mfpmath=sse is a better workaround.) Using 
-fno-tree-rsa means we needn't worry whether the build and host 
platforms use different CPU types.

I did that by installing the attached patch to Emacs on savannah, and am 
closing the bug report.

From 9f4fc6608212191e1a9e07bf89f38ba9e4ea786c Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Fri, 19 Jul 2024 13:39:21 -0700
Subject: [PATCH] Work around GCC bug 58416 on 32-bit x86

* configure.ac (C_SWITCH_MATCHINE): On 32-bit x86 with GCC 4+,
append -mfpmath=sse (if SSE2 is known to work) or -fno-tree-sra
(otherwise) to work around GCC bug 58416.
* etc/NEWS: Mention this.
---
 configure.ac | 45 +++++++++++++++++++++++++++++++++++++++++++++
 etc/NEWS     |  6 ++++++
 2 files changed, 51 insertions(+)

diff --git a/configure.ac b/configure.ac
index b6acdf2e456..67da852667d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2333,6 +2333,51 @@ AC_DEFUN
     fi
   ;;
 esac
+
+AC_CACHE_CHECK([for flags to work around GCC bug 58416],
+  [emacs_cv_gcc_bug_58416_CFLAGS],
+  [emacs_cv_gcc_bug_58416_CFLAGS='none needed'
+   AS_CASE([$canonical],
+     [[i[3456]86-* | x86_64-*]],
+       [AS_IF([test "$GCC" = yes],
+	  [old_CFLAGS=$CFLAGS
+	   # If no flags are needed (e.g., not GCC 4+), don't use any.
+	   # Otherwise, use -mfpmath=sse if already assuming SSE2.
+	   # Otherwise, use -fno-tree-sra.
+	   for emacs_cv_gcc_bug_58416_CFLAGS in \
+	       'none needed' -mfpmath=sse -fno-tree-sra
+	   do
+	     AS_CASE([$emacs_cv_gcc_bug_58416_CFLAGS],
+	       ['none needed'], [],
+	       [-fno-tree-sra], [break],
+	       [CFLAGS="$old_CFLAGS $emacs_cv_gcc_bug_58416_CFLAGS"])
+	     AC_COMPILE_IFELSE(
+	       [AC_LANG_DEFINES_PROVIDED
+		[/* Work around GCC bug with double in unions on x86,
+		    where the generated insns copy non-floating-point data
+		    via fldl/fstpl instruction pairs.  This can misbehave
+		    the data's bit pattern looks like a NaN.  See, e.g.:
+		       https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58416#c10
+		       https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71460
+		       https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93271
+		       https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114659
+		    Problem observed with 'gcc -m32' with GCC 14.1.1
+		    20240607 (Red Hat 14.1.1-5) on x86-64.  */
+		 #include <float.h>
+		 #if \
+		     (4 <= __GNUC__ && !defined __clang__ \
+		      && (defined __i386__ || defined __x86_64__) \
+		      && ! (0 <= FLT_EVAL_METHOD && FLT_EVAL_METHOD <= 1))
+		 # error "GCC bug 58416 is possibly present"
+		 #endif
+	       ]],
+	       [break])
+	   done
+	   CFLAGS=$old_CFLAGS])])])
+AS_CASE([$emacs_cv_gcc_bug_58416_CFLAGS],
+  [-*],
+    [C_SWITCH_MACHINE="$C_SWITCH_MACHINE $emacs_cv_gcc_bug_58416_CFLAGS"])
+
 AC_SUBST([C_SWITCH_MACHINE])
 
 C_SWITCH_SYSTEM=
diff --git a/etc/NEWS b/etc/NEWS
index 5429db1dded..0e13f471c74 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -24,6 +24,12 @@ applies, and please also update docstrings as needed.
 
 * Installation Changes in Emacs 31.1
 
+** When using GCC 4 or later to build Emacs on 32-bit x86 systems,
+'configure' now defaults to using the GCC options -mfpmath=sse (if the
+host system supports SSE2) or -fno-tree-sra (if not).  These GCC options
+work around GCC bug 58416, which can cause Emacs to behave incorrectly
+in rare cases.
+
 
 * Startup Changes in Emacs 31.1
 
-- 
2.43.0