aboutsummaryrefslogtreecommitdiff
path: root/math/powf.c
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2018-05-14 10:14:49 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2018-05-16 13:52:13 +0100
commit6c4401ca9ec7bd11efc8ef33e1fb0e3fd1fb6568 (patch)
treebec88c2dc9c1774267ef980153d8d1f4d740d96e /math/powf.c
parentc1adc91f8af052f293a01327be335b66870e24b4 (diff)
downloadarm-optimized-routines-6c4401ca9ec7bd11efc8ef33e1fb0e3fd1fb6568.tar.gz
Fix spurious divbyzero exception with clang
A division is hoisted from behind a check (to use fcsel on the result) by several versions of clang, and it can signal spurious divbyzero exception.
Diffstat (limited to 'math/powf.c')
-rw-r--r--math/powf.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/math/powf.c b/math/powf.c
index 42d3e67..69a57db 100644
--- a/math/powf.c
+++ b/math/powf.c
@@ -182,6 +182,14 @@ powf (float x, float y)
if (2 * ix == 0 && iy & 0x80000000)
return __math_divzerof (sign_bias);
#endif
+#ifdef CLANG_EXCEPTIONS
+ /* Some versions of clang hoist the 1/x2 and thus division
+ by zero exception can be signaled spuriously, this is
+ not a real fix (that would require clang to model fenv
+ correctly), but seems to work in practice. */
+ if (2 * ix == 0 && !(iy & 0x80000000))
+ return x2;
+#endif
return iy & 0x80000000 ? 1 / x2 : x2;
}
/* x and y are non-zero finite. */