diff --git a/Makerules b/Makerules
index 2ebb8e0..f532b16 100644
--- a/Makerules
+++ b/Makerules
@@ -106,10 +106,12 @@ $(common-objpfx)%.latest: $(common-objpfx)abi-versions.h
 	    $(common-objpfx)abi-versions.h > $@T
 	mv -f $@T $@
 
-# first-versions.h provides macros used in various symbol versioning
-# macro calls.
-before-compile := $(common-objpfx)first-versions.h $(before-compile)
+# first-versions.h and ldbl-compat-choose.h provide macros used in
+# various symbol versioning macro calls.
+before-compile := $(common-objpfx)first-versions.h \
+		  $(common-objpfx)ldbl-compat-choose.h $(before-compile)
 $(common-objpfx)first-versions.h: $(common-objpfx)versions.stmp
+$(common-objpfx)ldbl-compat-choose.h: $(common-objpfx)versions.stmp
 endif # avoid-generated
 endif # $(build-shared) = yes
 
diff --git a/scripts/versions.awk b/scripts/versions.awk
index df08d06..6c96da2 100644
--- a/scripts/versions.awk
+++ b/scripts/versions.awk
@@ -105,6 +105,13 @@ END {
   first_ver_header = real_first_ver_header "T"
   printf("#ifndef _FIRST_VERSIONS_H\n") > first_ver_header;
   printf("#define _FIRST_VERSIONS_H\n") > first_ver_header;
+  real_ldbl_compat_header = buildroot "ldbl-compat-choose.h"
+  ldbl_compat_header = real_ldbl_compat_header "T"
+  printf("#ifndef _LDBL_COMPAT_CHOOSE_H\n") > ldbl_compat_header;
+  printf("#define _LDBL_COMPAT_CHOOSE_H\n") > ldbl_compat_header;
+  printf("#ifndef LONG_DOUBLE_COMPAT\n") > ldbl_compat_header;
+  printf("# error LONG_DOUBLE_COMPAT not defined\n") > ldbl_compat_header;
+  printf("#endif\n") > ldbl_compat_header;
   printf("version-maps =");
   while (getline < tmpfile) {
     if ($1 != oldlib) {
@@ -141,14 +148,25 @@ END {
 	gsub("\\.", "_", ver_val);
 	printf("#define %s %s\n", first_ver_macro, ver_val) > first_ver_header;
 	first_ver_seen[first_ver_macro] = 1;
+	if (oldlib == "libc" || oldlib == "libm") {
+	  printf("#if LONG_DOUBLE_COMPAT (%s, %s)\n", oldlib, ver_val) > ldbl_compat_header;
+	  printf("# define LONG_DOUBLE_COMPAT_CHOOSE_%s_%s(a, b) a\n",
+		 oldlib, sym) > ldbl_compat_header;
+	  printf("#else\n") > ldbl_compat_header;
+	  printf("# define LONG_DOUBLE_COMPAT_CHOOSE_%s_%s(a, b) b\n",
+		 oldlib, sym) > ldbl_compat_header;
+	  printf("#endif\n") > ldbl_compat_header;
+	}
       }
     }
     printf("\n") > outfile;
   }
   printf("\n");
   printf("#endif /* first-versions.h */\n") > first_ver_header;
+  printf("#endif /* ldbl-compat-choose.h */\n") > ldbl_compat_header;
   closeversion(oldver, veryoldver);
   close_and_move(outfile, real_outfile);
   close_and_move(first_ver_header, real_first_ver_header);
+  close_and_move(ldbl_compat_header, real_ldbl_compat_header);
   #system("rm -f " tmpfile);
 }
diff --git a/sysdeps/ieee754/ldbl-opt/math-type-macros-ldouble.h b/sysdeps/ieee754/ldbl-opt/math-type-macros-ldouble.h
index da926da..20873ae 100644
--- a/sysdeps/ieee754/ldbl-opt/math-type-macros-ldouble.h
+++ b/sysdeps/ieee754/ldbl-opt/math-type-macros-ldouble.h
@@ -19,12 +19,19 @@
 #ifndef _MATH_TYPE_MACROS_LDOUBLE
 
 #include <math_ldbl_opt.h>
+#include <ldbl-compat-choose.h>
+
+#define maybe_long_double_symbol(lib, from, to)				\
+  LONG_DOUBLE_COMPAT_CHOOSE_ ## lib ## _ ## to (long_double_symbol (lib, \
+								    from, \
+								    to), \
+						weak_alias (from, to))
 
 /* Use properly versioned symbols for long double on platforms where
    it was not always a distinct type.  */
 #if !defined declare_mgen_alias
 # define declare_mgen_alias(from, to) \
-  long_double_symbol (libm, from ## l, to ## l);
+  maybe_long_double_symbol (libm, from ## l, to ## l);
 #endif
 
 #include_next <math-type-macros-ldouble.h>
diff --git a/sysdeps/ieee754/ldbl-opt/s_canonicalizel.c b/sysdeps/ieee754/ldbl-opt/s_canonicalizel.c
deleted file mode 100644
index d5d67df..0000000
--- a/sysdeps/ieee754/ldbl-opt/s_canonicalizel.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* canonicalizel is not subject to complex aliasing rules.  It was
-   added in glibc 2.25.  */
-#define declare_mgen_alias(from, to) weak_alias (M_SUF (from), M_SUF (to))
-#include <math-type-macros-ldouble.h>
-#include <s_canonicalize_template.c>
diff --git a/sysdeps/ieee754/ldbl-opt/s_fmaxmagl.c b/sysdeps/ieee754/ldbl-opt/s_fmaxmagl.c
deleted file mode 100644
index 7e23761..0000000
--- a/sysdeps/ieee754/ldbl-opt/s_fmaxmagl.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* fmaxmagl is not subject to complex aliasing rules.  It was added in
-   glibc 2.25.  */
-#define declare_mgen_alias(from, to) weak_alias (M_SUF (from), M_SUF (to))
-#include <math-type-macros-ldouble.h>
-#include <s_fmaxmag_template.c>
diff --git a/sysdeps/ieee754/ldbl-opt/s_fminmagl.c b/sysdeps/ieee754/ldbl-opt/s_fminmagl.c
deleted file mode 100644
index 46c1051..0000000
--- a/sysdeps/ieee754/ldbl-opt/s_fminmagl.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* fminmagl is not subject to complex aliasing rules.  It was added in
-   glibc 2.25.  */
-#define declare_mgen_alias(from, to) weak_alias (M_SUF (from), M_SUF (to))
-#include <math-type-macros-ldouble.h>
-#include <s_fminmag_template.c>
diff --git a/sysdeps/ieee754/ldbl-opt/s_nextdownl.c b/sysdeps/ieee754/ldbl-opt/s_nextdownl.c
deleted file mode 100644
index c92c02e..0000000
--- a/sysdeps/ieee754/ldbl-opt/s_nextdownl.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* nextdownl is not subject to complex aliasing rules.  It was
-   added in glibc 2.24.  */
-#define declare_mgen_alias(from, to) weak_alias (M_SUF (from), M_SUF (to))
-#include <math-type-macros-ldouble.h>
-#include <s_nextdown_template.c>
diff --git a/sysdeps/ieee754/ldbl-opt/w_llogbl.c b/sysdeps/ieee754/ldbl-opt/w_llogbl.c
deleted file mode 100644
index 8abe54b..0000000
--- a/sysdeps/ieee754/ldbl-opt/w_llogbl.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* llogbl is not subject to complex aliasing rules.  It was added in
-   glibc 2.25.  */
-#define declare_mgen_alias(from, to) weak_alias (M_SUF (from), M_SUF (to))
-#include <math-type-macros-ldouble.h>
-#include <w_llogb_template.c>
