ref: 15edb78b3e12d2b5c94e2354c91f354c881627de
parent: 4fda6b01424aab5f6c5b13b1bd01697c899b6fcd
author: Jean-Marc Valin <[email protected]>
date: Mon Dec 9 16:56:21 EST 2013
Making NaN detection more robust to -ffast-math.
--- a/celt/arch.h
+++ b/celt/arch.h
@@ -137,6 +137,22 @@
typedef float celt_norm;
typedef float celt_ener;
+#ifdef FLOAT_APPROX
+/* This code should reliably detect NaN/inf even when -ffast-math is used.
+ Assumes IEEE 754 format. */
+static inline int celt_isnan(float x)
+{
+ union {float f; opus_uint32 i;} in;
+ in.f = x;
+ return ((in.i>>23)&0xFF)==0xFF && (in.i&0x007FFFFF)!=0;
+}
+#else
+#ifdef __FAST_MATH__
+#error Cannot build libopus with -ffast-math unless FLOAT_APPROX is defined. This could result in crashes on extreme (e.g. NaN) input
+#endif
+#define celt_isnan(x) ((x)!=(x))
+#endif
+
#define Q15ONE 1.0f
#define NORM_SCALING 1.f
--- a/src/mlp.c
+++ b/src/mlp.c
@@ -75,6 +75,11 @@
return 1;
if (!(x>-8))
return -1;
+#ifndef FIXED_POINT
+ /* Another check in case of -ffast-math */
+ if (celt_isnan(x))
+ return 0;
+#endif
if (x<0)
{
x=-x;
--- a/src/mlp_data.c
+++ b/src/mlp_data.c
@@ -1,6 +1,10 @@
/* The contents of this file was automatically generated by mlp_train.c
It contains multi-layer perceptron (MLP) weights. */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "mlp.h"
/* RMS error was 0.138320, seed was 1361535663 */
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -1452,7 +1452,7 @@
sum = celt_inner_prod(&pcm_buf[total_buffer*st->channels], &pcm_buf[total_buffer*st->channels], frame_size*st->channels);
/* This should filter out both NaNs and ridiculous signals that could
cause NaNs further down. */
- if (!(sum < 1e9))
+ if (!(sum < 1e9) || celt_isnan(sum))
OPUS_CLEAR(&pcm_buf[total_buffer*st->channels], frame_size*st->channels);
}
#endif