If built with -ffast-math, clang replaces the call to pow(2, x) with
exp2(x) directly, making the implementation of exp2() an infinite
recursion. This can be either avoided by building these object files
with -fno-builtin, -fno-builtin-pow, or by implementing the function
in assembly.

For aarch64, the same already happens even without -ffast-math,
and due to that, the aarch64 exp2 function wrapper already is
implemented in assembly.

While building with -ffast-math can break certain math routines and
thus can be considered a self-inflicted issue, it's safest to avoid
constructs that potentially can be optimized into an infinite self
recursion.

Signed-off-by: Martin Storsjö <mar...@martin.st>
---
 mingw-w64-crt/Makefile.am      |  3 +-
 mingw-w64-crt/math/arm/exp2.S  | 19 ++++++++++
 mingw-w64-crt/math/arm/exp2.c  | 64 ----------------------------------
 mingw-w64-crt/math/arm/exp2f.S | 16 +++++++++
 4 files changed, 37 insertions(+), 65 deletions(-)
 create mode 100644 mingw-w64-crt/math/arm/exp2.S
 delete mode 100644 mingw-w64-crt/math/arm/exp2.c
 create mode 100644 mingw-w64-crt/math/arm/exp2f.S

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index 7b1b7433d..3feaa447b 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -276,7 +276,8 @@ src_msvcrtarm32=\
 
 if !ENABLE_SOFTMATH
 src_msvcrtarm32+=\
-  math/arm/exp2.c \
+  math/arm/exp2.S \
+  math/arm/exp2f.S \
   math/arm/nearbyint.S \
   math/arm/nearbyintf.S \
   math/arm/nearbyintl.S \
diff --git a/mingw-w64-crt/math/arm/exp2.S b/mingw-w64-crt/math/arm/exp2.S
new file mode 100644
index 000000000..6918ce19d
--- /dev/null
+++ b/mingw-w64-crt/math/arm/exp2.S
@@ -0,0 +1,19 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+#include <_mingw_mac.h>
+
+       .file   "exp2.S"
+       .text
+       .align 2
+       .globl __MINGW_USYMBOL(exp2)
+       .globl __MINGW_USYMBOL(exp2l)
+       .def    __MINGW_USYMBOL(exp2);  .scl    2;      .type   32;     .endef
+       .def    __MINGW_USYMBOL(exp2l); .scl    2;      .type   32;     .endef
+__MINGW_USYMBOL(exp2):
+__MINGW_USYMBOL(exp2l):
+       vmov.f64 d1, d0
+       vmov.f64 d0, #2.0
+       b pow
diff --git a/mingw-w64-crt/math/arm/exp2.c b/mingw-w64-crt/math/arm/exp2.c
deleted file mode 100644
index 77e914d98..000000000
--- a/mingw-w64-crt/math/arm/exp2.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- This Software is provided under the Zope Public License (ZPL) Version 2.1.
-
- Copyright (c) 2014 by the mingw-w64 project
-
- See the AUTHORS file for the list of contributors to the mingw-w64 project.
-
- This license has been certified as open source. It has also been designated
- as GPL compatible by the Free Software Foundation (FSF).
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
-   1. Redistributions in source code must retain the accompanying copyright
-      notice, this list of conditions, and the following disclaimer.
-   2. Redistributions in binary form must reproduce the accompanying
-      copyright notice, this list of conditions, and the following disclaimer
-      in the documentation and/or other materials provided with the
-      distribution.
-   3. Names of the copyright holders must not be used to endorse or promote
-      products derived from this software without prior written permission
-      from the copyright holders.
-   4. The right to distribute this software or to use it for any purpose does
-      not give you the right to use Servicemarks (sm) or Trademarks (tm) of
-      the copyright holders.  Use of them is covered by separate agreement
-      with the copyright holders.
-   5. If any files are modified, you must cause the modified files to carry
-      prominent notices stating that you changed the files and the date of
-      any change.
-
- Disclaimer
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
- OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#include <math.h>
-
-double exp2(double x)
-{
-    return pow(2, x);
-}
-
-float exp2f(float x)
-{
-    return powf(2, x);
-}
-
-long double exp2l(long double x)
-{
-#if defined(__arm__) || defined(_ARM_)
-    return exp2(x);
-#else
-#error Not supported on your platform yet
-#endif
-}
diff --git a/mingw-w64-crt/math/arm/exp2f.S b/mingw-w64-crt/math/arm/exp2f.S
new file mode 100644
index 000000000..452cd9a95
--- /dev/null
+++ b/mingw-w64-crt/math/arm/exp2f.S
@@ -0,0 +1,16 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the mingw-w64 runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+#include <_mingw_mac.h>
+
+       .file   "exp2f.S"
+       .text
+       .align 2
+       .globl __MINGW_USYMBOL(exp2f)
+       .def    __MINGW_USYMBOL(exp2f); .scl    2;      .type   32;     .endef
+__MINGW_USYMBOL(exp2f):
+       vmov s1, s0
+       vmov.f32 s0, #2.0
+       b powf
-- 
2.17.1



_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to