aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2011-11-18 17:42:28 +0100
committerSverker Eriksson <[email protected]>2011-11-18 17:42:28 +0100
commit7d9ef0fdde8119e1be0a47e3e45c9cdb85f926d8 (patch)
treef9cbbd41ccf67517b8d9c7423ee2b3d64c6bba31
parentb130455e73b0bcacee2bfd3dfe6bafa9dd497886 (diff)
parent327c072661840f671fc0041bc5e88bc69691d5aa (diff)
downloadotp-7d9ef0fdde8119e1be0a47e3e45c9cdb85f926d8.tar.gz
otp-7d9ef0fdde8119e1be0a47e3e45c9cdb85f926d8.tar.bz2
otp-7d9ef0fdde8119e1be0a47e3e45c9cdb85f926d8.zip
Merge branch 'sverk/hipe-without-fpe/OTP-9724'
* sverk/hipe-without-fpe/OTP-9724: otp_build: Disable FPE by default on Linux stdlib: Make sure qlc_SUITE:otp_6964 restores backtrace_depth erts: Add test for inf/NaN intermediate float results hipe,erts: Allow hipe without floating point exceptions hipe: Fix bug in hipe_rtl_lcm:calc_killed_expr_bb erts: Rename macros used by float instructions without FPE
-rw-r--r--erts/configure.in2
-rw-r--r--erts/emulator/beam/beam_emu.c29
-rw-r--r--erts/emulator/beam/erl_process.c4
-rw-r--r--erts/emulator/beam/erl_process.h2
-rw-r--r--erts/emulator/hipe/hipe_amd64_bifs.m42
-rw-r--r--erts/emulator/hipe/hipe_amd64_primops.h2
-rw-r--r--erts/emulator/hipe/hipe_bif0.c20
-rw-r--r--erts/emulator/hipe/hipe_bif0.tab2
-rw-r--r--erts/emulator/hipe/hipe_bif_list.m44
-rw-r--r--erts/emulator/hipe/hipe_mkliterals.c16
-rw-r--r--erts/emulator/hipe/hipe_native_bif.c2
-rw-r--r--erts/emulator/hipe/hipe_native_bif.h5
-rw-r--r--erts/emulator/hipe/hipe_primops.h4
-rw-r--r--erts/emulator/hipe/hipe_process.h3
-rw-r--r--erts/emulator/hipe/hipe_x86.h2
-rw-r--r--erts/emulator/hipe/hipe_x86_bifs.m42
-rw-r--r--erts/emulator/hipe/hipe_x86_primops.h3
-rw-r--r--erts/emulator/test/float_SUITE.erl27
-rw-r--r--lib/hipe/rtl/hipe_rtl.erl5
-rw-r--r--lib/hipe/rtl/hipe_rtl_arch.erl27
-rw-r--r--lib/hipe/rtl/hipe_rtl_lcm.erl21
-rw-r--r--lib/stdlib/test/qlc_SUITE.erl7
-rwxr-xr-xotp_build4
23 files changed, 158 insertions, 37 deletions
diff --git a/erts/configure.in b/erts/configure.in
index d865e675c4..8f30ae3850 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -3076,8 +3076,6 @@ dnl done up where floating point is checked, need to descide there already...
if test X${enable_hipe} = Xyes; then
if test X$ac_cv_sizeof_void_p != X4 -a X$ARCH != Xamd64 -a X$ARCH != Xppc64; then
AC_MSG_WARN([HiPE is not supported in 64-bit builds])
- elif test X$FPE != Xreliable -a X$ARCH != Xarm; then
- AC_MSG_WARN([HiPE is not supported on $ARCH without reliable floating-point exceptions])
else
HIPE_ENABLED=yes
AC_DEFINE(HIPE,[1],[Define to enable HiPE])
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 9c5450bd48..028a532b4c 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -4747,7 +4747,12 @@ void process_main(void)
OpCase(fclearerror):
OpCase(i_fcheckerror):
erl_exit(1, "fclearerror/i_fcheckerror without fpe signals (beam_emu)");
+# define ERTS_NO_FPE_CHECK_INIT ERTS_FP_CHECK_INIT
+# define ERTS_NO_FPE_ERROR ERTS_FP_ERROR
#else
+# define ERTS_NO_FPE_CHECK_INIT(p)
+# define ERTS_NO_FPE_ERROR(p, a, b)
+
OpCase(fclearerror): {
BeamInstr *next;
@@ -4763,10 +4768,6 @@ void process_main(void)
ERTS_FP_ERROR(c_p, freg[0].fd, goto fbadarith);
NextPF(0, next);
}
-# undef ERTS_FP_CHECK_INIT
-# undef ERTS_FP_ERROR
-# define ERTS_FP_CHECK_INIT(p)
-# define ERTS_FP_ERROR(p, a, b)
#endif
@@ -4774,45 +4775,45 @@ void process_main(void)
BeamInstr *next;
PreFetch(3, next);
- ERTS_FP_CHECK_INIT(c_p);
+ ERTS_NO_FPE_CHECK_INIT(c_p);
fb(Arg(2)) = fb(Arg(0)) + fb(Arg(1));
- ERTS_FP_ERROR(c_p, fb(Arg(2)), goto fbadarith);
+ ERTS_NO_FPE_ERROR(c_p, fb(Arg(2)), goto fbadarith);
NextPF(3, next);
}
OpCase(i_fsub_lll): {
BeamInstr *next;
PreFetch(3, next);
- ERTS_FP_CHECK_INIT(c_p);
+ ERTS_NO_FPE_CHECK_INIT(c_p);
fb(Arg(2)) = fb(Arg(0)) - fb(Arg(1));
- ERTS_FP_ERROR(c_p, fb(Arg(2)), goto fbadarith);
+ ERTS_NO_FPE_ERROR(c_p, fb(Arg(2)), goto fbadarith);
NextPF(3, next);
}
OpCase(i_fmul_lll): {
BeamInstr *next;
PreFetch(3, next);
- ERTS_FP_CHECK_INIT(c_p);
+ ERTS_NO_FPE_CHECK_INIT(c_p);
fb(Arg(2)) = fb(Arg(0)) * fb(Arg(1));
- ERTS_FP_ERROR(c_p, fb(Arg(2)), goto fbadarith);
+ ERTS_NO_FPE_ERROR(c_p, fb(Arg(2)), goto fbadarith);
NextPF(3, next);
}
OpCase(i_fdiv_lll): {
BeamInstr *next;
PreFetch(3, next);
- ERTS_FP_CHECK_INIT(c_p);
+ ERTS_NO_FPE_CHECK_INIT(c_p);
fb(Arg(2)) = fb(Arg(0)) / fb(Arg(1));
- ERTS_FP_ERROR(c_p, fb(Arg(2)), goto fbadarith);
+ ERTS_NO_FPE_ERROR(c_p, fb(Arg(2)), goto fbadarith);
NextPF(3, next);
}
OpCase(i_fnegate_ll): {
BeamInstr *next;
PreFetch(2, next);
- ERTS_FP_CHECK_INIT(c_p);
+ ERTS_NO_FPE_CHECK_INIT(c_p);
fb(Arg(1)) = -fb(Arg(0));
- ERTS_FP_ERROR(c_p, fb(Arg(1)), goto fbadarith);
+ ERTS_NO_FPE_ERROR(c_p, fb(Arg(1)), goto fbadarith);
NextPF(2, next);
fbadarith:
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index a1f5069b2d..84c0ded016 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -7140,7 +7140,7 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
p->pending_exit.bp = NULL;
#endif
-#if !defined(NO_FPE_SIGNALS)
+#if !defined(NO_FPE_SIGNALS) || defined(HIPE)
p->fp_exception = 0;
#endif
@@ -7314,7 +7314,7 @@ void erts_init_empty_process(Process *p)
p->run_queue = ERTS_RUNQ_IX(0);
#endif
-#if !defined(NO_FPE_SIGNALS)
+#if !defined(NO_FPE_SIGNALS) || defined(HIPE)
p->fp_exception = 0;
#endif
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index f0c86a0851..69ff423133 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -618,7 +618,7 @@ struct process {
Uint min_heap_size; /* Minimum size of heap (in words). */
Uint min_vheap_size; /* Minimum size of virtual heap (in words). */
-#if !defined(NO_FPE_SIGNALS)
+#if !defined(NO_FPE_SIGNALS) || defined(HIPE)
volatile unsigned long fp_exception;
#endif
diff --git a/erts/emulator/hipe/hipe_amd64_bifs.m4 b/erts/emulator/hipe/hipe_amd64_bifs.m4
index 97a8267647..ec25c0b9b7 100644
--- a/erts/emulator/hipe/hipe_amd64_bifs.m4
+++ b/erts/emulator/hipe/hipe_amd64_bifs.m4
@@ -549,7 +549,9 @@ ASYM($1):
/*
* AMD64-specific primops.
*/
+#ifndef NO_FPE_SIGNALS
noproc_primop_interface_0(nbif_handle_fp_exception, erts_restore_fpu)
+#endif /* NO_FPE_SIGNALS */
/*
* Implement gc_bif_interface_0 as nofail_primop_interface_0.
diff --git a/erts/emulator/hipe/hipe_amd64_primops.h b/erts/emulator/hipe/hipe_amd64_primops.h
index e3c7111997..55cb0eadb8 100644
--- a/erts/emulator/hipe/hipe_amd64_primops.h
+++ b/erts/emulator/hipe/hipe_amd64_primops.h
@@ -19,5 +19,7 @@
PRIMOP_LIST(am_inc_stack_0, &nbif_inc_stack_0)
+#ifndef NO_FPE_SIGNALS
PRIMOP_LIST(am_handle_fp_exception, &nbif_handle_fp_exception)
+#endif
PRIMOP_LIST(am_sse2_fnegate_mask, &sse2_fnegate_mask)
diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c
index e7fb850530..cec22b3836 100644
--- a/erts/emulator/hipe/hipe_bif0.c
+++ b/erts/emulator/hipe/hipe_bif0.c
@@ -985,6 +985,26 @@ BIF_RETTYPE hipe_conv_big_to_float(BIF_ALIST_1)
BIF_RET(res);
}
+#ifdef NO_FPE_SIGNALS
+
+/*
+ This is the current solution to make hipe run without FPE.
+ The native code is the same except that a call to this primop
+ is made after _every_ float operation to check the result.
+ The native fcheckerror still done later will detect if an
+ "emulated" FPE has occured.
+ We use p->hipe.float_result to avoid passing a 'double' argument,
+ which has its own calling convention (on amd64 at least).
+ Simple and slow...
+*/
+void hipe_emulate_fpe(Process* p)
+{
+ if (!finite(p->hipe.float_result)) {
+ p->fp_exception = 1;
+ }
+}
+#endif
+
#if 0 /* XXX: unused */
/*
* At least parts of this should be inlined in native code.
diff --git a/erts/emulator/hipe/hipe_bif0.tab b/erts/emulator/hipe/hipe_bif0.tab
index b6c6bede23..ce641365e9 100644
--- a/erts/emulator/hipe/hipe_bif0.tab
+++ b/erts/emulator/hipe/hipe_bif0.tab
@@ -140,3 +140,5 @@ atom bs_put_utf16le
atom bs_get_utf16
atom bs_validate_unicode
atom bs_validate_unicode_retract
+atom emulate_fpe
+
diff --git a/erts/emulator/hipe/hipe_bif_list.m4 b/erts/emulator/hipe/hipe_bif_list.m4
index 48c7c1bc9b..942fa0c5cb 100644
--- a/erts/emulator/hipe/hipe_bif_list.m4
+++ b/erts/emulator/hipe/hipe_bif_list.m4
@@ -245,6 +245,10 @@ noproc_primop_interface_5(nbif_bs_put_big_integer, hipe_bs_put_big_integer)
gc_bif_interface_0(nbif_check_get_msg, hipe_check_get_msg)
+#ifdef NO_FPE_SIGNALS
+nocons_nofail_primop_interface_0(nbif_emulate_fpe, hipe_emulate_fpe)
+#endif
+
/*
* SMP-specific stuff
*/
diff --git a/erts/emulator/hipe/hipe_mkliterals.c b/erts/emulator/hipe/hipe_mkliterals.c
index 61e15f1d58..d07d14028c 100644
--- a/erts/emulator/hipe/hipe_mkliterals.c
+++ b/erts/emulator/hipe/hipe_mkliterals.c
@@ -293,6 +293,11 @@ static const struct literal {
{ "P_NRA", offsetof(struct process, hipe.nra) },
#endif
{ "P_NARITY", offsetof(struct process, hipe.narity) },
+ { "P_FLOAT_RESULT",
+# ifdef NO_FPE_SIGNALS
+ offsetof(struct process, hipe.float_result)
+# endif
+ },
# if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP)
{ "P_BIF_CALLEE", offsetof(struct process, hipe.bif_callee) },
# endif
@@ -491,7 +496,7 @@ static const struct rts_param {
#endif
},
{ 14, "P_FP_EXCEPTION",
-#if !defined(NO_FPE_SIGNALS)
+#if !defined(NO_FPE_SIGNALS) || defined(HIPE)
1, offsetof(struct process, fp_exception)
#endif
},
@@ -504,6 +509,15 @@ static const struct rts_param {
0
#endif
},
+ /* This flag is always defined, but its value is configuration-dependent. */
+ { 16, "ERTS_NO_FPE_SIGNALS",
+ 1,
+#if defined(NO_FPE_SIGNALS)
+ 1
+#else
+ 0
+#endif
+ },
/* This parameter is always defined, but its value depends on ERTS_SMP. */
{ 19, "MSG_MESSAGE",
1, offsetof(struct erl_mesg, m[0])
diff --git a/erts/emulator/hipe/hipe_native_bif.c b/erts/emulator/hipe/hipe_native_bif.c
index 77dee6f9e9..3be821f8f7 100644
--- a/erts/emulator/hipe/hipe_native_bif.c
+++ b/erts/emulator/hipe/hipe_native_bif.c
@@ -189,6 +189,8 @@ void hipe_fclearerror_error(Process *p)
{
#if !defined(NO_FPE_SIGNALS)
erts_fp_check_init_error(&p->fp_exception);
+#else
+ erl_exit(ERTS_ABORT_EXIT, "Emulated FPE not cleared by HiPE");
#endif
}
diff --git a/erts/emulator/hipe/hipe_native_bif.h b/erts/emulator/hipe/hipe_native_bif.h
index 8c9dec180e..9e3a156fbc 100644
--- a/erts/emulator/hipe/hipe_native_bif.h
+++ b/erts/emulator/hipe/hipe_native_bif.h
@@ -93,6 +93,11 @@ BIF_RETTYPE hipe_bs_validate_unicode(BIF_ALIST_1);
struct erl_bin_match_buffer;
int hipe_bs_validate_unicode_retract(struct erl_bin_match_buffer*, Eterm);
+#ifdef NO_FPE_SIGNALS
+AEXTERN(void,nbif_emulate_fpe,(Process*));
+void hipe_emulate_fpe(Process*);
+#endif
+
/*
* Stuff that is different in SMP and non-SMP.
*/
diff --git a/erts/emulator/hipe/hipe_primops.h b/erts/emulator/hipe/hipe_primops.h
index 94113ffcd8..38509c105b 100644
--- a/erts/emulator/hipe/hipe_primops.h
+++ b/erts/emulator/hipe/hipe_primops.h
@@ -77,6 +77,10 @@ PRIMOP_LIST(am_nonclosure_address, &nbif_nonclosure_address)
PRIMOP_LIST(am_conv_big_to_float, &nbif_conv_big_to_float)
PRIMOP_LIST(am_fclearerror_error, &nbif_fclearerror_error)
+#ifdef NO_FPE_SIGNALS
+PRIMOP_LIST(am_emulate_fpe, &nbif_emulate_fpe)
+#endif
+
#if defined(__sparc__)
#include "hipe_sparc_primops.h"
#endif
diff --git a/erts/emulator/hipe/hipe_process.h b/erts/emulator/hipe/hipe_process.h
index 43f47d1a28..4ee99d78a2 100644
--- a/erts/emulator/hipe/hipe_process.h
+++ b/erts/emulator/hipe/hipe_process.h
@@ -42,6 +42,9 @@ struct hipe_process_state {
void (*nra)(void); /* Native code return address. */
#endif
unsigned int narity; /* Arity of BIF call, for stack walks. */
+#ifdef NO_FPE_SIGNALS
+ double float_result; /* to be checked for inf/NaN by hipe_emulate_fpe */
+#endif
#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP)
void (*bif_callee)(void); /* When calling BIF's via debug wrapper */
#endif
diff --git a/erts/emulator/hipe/hipe_x86.h b/erts/emulator/hipe/hipe_x86.h
index f0f3c158af..97f09e38cd 100644
--- a/erts/emulator/hipe/hipe_x86.h
+++ b/erts/emulator/hipe/hipe_x86.h
@@ -49,7 +49,9 @@ static __inline__ int hipe_word32_address_ok(void *address)
#define hipe_arch_name am_x86
extern void nbif_inc_stack_0(void);
+#ifndef NO_FPE_SIGNALS
extern void nbif_handle_fp_exception(void);
+#endif
/* for hipe_bifs_enter_code_2 */
extern void *hipe_alloc_code(Uint nrbytes, Eterm callees, Eterm *trampolines, Process *p);
diff --git a/erts/emulator/hipe/hipe_x86_bifs.m4 b/erts/emulator/hipe/hipe_x86_bifs.m4
index 2ea69bde3c..3cb7d67be0 100644
--- a/erts/emulator/hipe/hipe_x86_bifs.m4
+++ b/erts/emulator/hipe/hipe_x86_bifs.m4
@@ -621,7 +621,9 @@ ASYM($1):
/*
* x86-specific primops.
*/
+#ifndef NO_FPE_SIGNALS
noproc_primop_interface_0(nbif_handle_fp_exception, erts_restore_fpu)
+#endif /* NO_FPE_SIGNALS */
/*
* Implement gc_bif_interface_0 as nofail_primop_interface_0.
diff --git a/erts/emulator/hipe/hipe_x86_primops.h b/erts/emulator/hipe/hipe_x86_primops.h
index 96d2336bc5..111b1fa8bd 100644
--- a/erts/emulator/hipe/hipe_x86_primops.h
+++ b/erts/emulator/hipe/hipe_x86_primops.h
@@ -19,4 +19,7 @@
PRIMOP_LIST(am_inc_stack_0, &nbif_inc_stack_0)
+#ifndef NO_FPE_SIGNALS
PRIMOP_LIST(am_handle_fp_exception, &nbif_handle_fp_exception)
+#endif
+
diff --git a/erts/emulator/test/float_SUITE.erl b/erts/emulator/test/float_SUITE.erl
index 46466427c5..8e6923ce9f 100644
--- a/erts/emulator/test/float_SUITE.erl
+++ b/erts/emulator/test/float_SUITE.erl
@@ -27,6 +27,7 @@
fpe/1,fp_drv/1,fp_drv_thread/1,denormalized/1,match/1,
bad_float_unpack/1,cmp_zero/1, cmp_integer/1, cmp_bignum/1]).
-export([otp_7178/1]).
+-export([hidden_inf/1]).
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
@@ -41,7 +42,9 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[fpe, fp_drv, fp_drv_thread, otp_7178, denormalized,
- match, bad_float_unpack, {group, comparison}].
+ match, bad_float_unpack, {group, comparison}
+ ,hidden_inf
+ ].
groups() ->
[{comparison, [parallel], [cmp_zero, cmp_integer, cmp_bignum]}].
@@ -300,3 +303,25 @@ start_node(Config) when is_list(Config) ->
stop_node(Node) ->
?t:stop_node(Node).
+
+
+%% Test that operations that might hide infinite intermediate results
+%% do not supress the badarith.
+hidden_inf(Config) when is_list(Config) ->
+ ZeroP = 0.0,
+ ZeroN = id(ZeroP) * (-1),
+ [hidden_inf_1(A, B, Z, 9.23e307)
+ || A <- [1.0, -1.0, 3.1415, -0.00001000131, 3.57e257, ZeroP, ZeroN],
+ B <- [1.0, -1.0, 3.1415, -0.00001000131, 3.57e257, ZeroP, ZeroN],
+ Z <- [ZeroP, ZeroN]],
+ ok.
+
+hidden_inf_1(A, B, Zero, Huge) ->
+ {'EXIT',{badarith,_}} = (catch (B / (A / Zero))),
+ {'EXIT',{badarith,_}} = (catch (B * (A / Zero))),
+ {'EXIT',{badarith,_}} = (catch (B / (Huge * Huge))),
+ {'EXIT',{badarith,_}} = (catch (B * (Huge * Huge))),
+ {'EXIT',{badarith,_}} = (catch (B / (Huge + Huge))),
+ {'EXIT',{badarith,_}} = (catch (B * (Huge + Huge))),
+ {'EXIT',{badarith,_}} = (catch (B / (-Huge - Huge))),
+ {'EXIT',{badarith,_}} = (catch (B * (-Huge - Huge))).
diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl
index 29e9c8c8fe..4bf4eb6bd7 100644
--- a/lib/hipe/rtl/hipe_rtl.erl
+++ b/lib/hipe/rtl/hipe_rtl.erl
@@ -781,8 +781,11 @@ fstore_src_update(F, NewSrc) -> F#fstore{src=NewSrc}.
%% fp
%%
+
mk_fp(Dst, Src1, Op, Src2) ->
- #fp{dst=Dst, src1=Src1, op=Op, src2=Src2}.
+ [#fp{dst=Dst, src1=Src1, op=Op, src2=Src2}
+ | hipe_rtl_arch:mk_fp_check_result(Dst)].
+
fp_dst(#fp{dst=Dst}) -> Dst.
fp_dst_update(Fp, NewDst) -> Fp#fp{dst=NewDst}.
fp_src1(#fp{src1=Src1}) -> Src1.
diff --git a/lib/hipe/rtl/hipe_rtl_arch.erl b/lib/hipe/rtl/hipe_rtl_arch.erl
index 22cda57a3a..99eb80f3d1 100644
--- a/lib/hipe/rtl/hipe_rtl_arch.erl
+++ b/lib/hipe/rtl/hipe_rtl_arch.erl
@@ -65,7 +65,8 @@
%% alignment/0,
nr_of_return_regs/0,
log2_word_size/0,
- word_size/0
+ word_size/0,
+ mk_fp_check_result/1
]).
-include("hipe_literals.hrl").
@@ -558,6 +559,12 @@ eval_cond_bits(Cond, N, Z, V, C) ->
%%----------------------------------------------------------------------
fwait() ->
+ case ?ERTS_NO_FPE_SIGNALS of
+ 1 -> [];
+ 0 -> fwait_real()
+ end.
+
+fwait_real() ->
case get(hipe_target_arch) of
x86 -> [hipe_rtl:mk_call([], 'fwait', [], [], [], not_remote)];
amd64 -> [hipe_rtl:mk_call([], 'fwait', [], [], [], not_remote)];
@@ -573,6 +580,12 @@ fwait() ->
%% Returns RTL code to restore the FPU after a floating-point exception.
%% @end
handle_fp_exception() ->
+ case ?ERTS_NO_FPE_SIGNALS of
+ 1 -> [];
+ 0 -> handle_real_fp_exception()
+ end.
+
+handle_real_fp_exception() ->
case get(hipe_target_arch) of
x86 ->
ContLbl = hipe_rtl:mk_new_label(),
@@ -655,3 +668,15 @@ nr_of_return_regs() ->
1
%% hipe_amd64_registers:nr_rets();
end.
+
+
+mk_fp_check_result(Result) ->
+ case ?ERTS_NO_FPE_SIGNALS of
+ 0 ->
+ [];
+ 1 ->
+ [hipe_rtl:mk_fstore(proc_pointer(),
+ hipe_rtl:mk_imm(?P_FLOAT_RESULT),
+ Result),
+ hipe_rtl:mk_call([], emulate_fpe, [], [], [], not_remote)]
+ end.
diff --git a/lib/hipe/rtl/hipe_rtl_lcm.erl b/lib/hipe/rtl/hipe_rtl_lcm.erl
index 9224623c8b..262aedb409 100644
--- a/lib/hipe/rtl/hipe_rtl_lcm.erl
+++ b/lib/hipe/rtl/hipe_rtl_lcm.erl
@@ -486,7 +486,7 @@ lcm_precalc(CFG, Options) ->
?option_time(NodeInfo2 = calc_down_exp(CFG, ExprMap, NodeInfo1, Labels),
"RTL LCM calc_down_exp", Options),
?option_time(NodeInfo3 = calc_killed_expr(CFG, NodeInfo2, UseMap, AllExpr,
- Labels),
+ IdMap, Labels),
"RTL LCM calc_killed_exp", Options),
?option_time(NodeInfo4 = calc_avail(CFG, NodeInfo3),
"RTL LCM calc_avail", Options),
@@ -815,19 +815,19 @@ exp_kill_expr(Instr, [CheckedExpr|Exprs]) ->
%%=============================================================================
%% Calculates the killed expression sets for all given labels.
-calc_killed_expr(_, NodeInfo, _, _, []) ->
+calc_killed_expr(_, NodeInfo, _, _, _, []) ->
NodeInfo;
-calc_killed_expr(CFG, NodeInfo, UseMap, AllExpr, [Label|Labels]) ->
+calc_killed_expr(CFG, NodeInfo, UseMap, AllExpr, IdMap, [Label|Labels]) ->
Code = hipe_bb:code(hipe_rtl_cfg:bb(CFG, Label)),
- KilledExprs = calc_killed_expr_bb(Code, UseMap, AllExpr, ?SETS:new()),
+ KilledExprs = calc_killed_expr_bb(Code, UseMap, AllExpr, IdMap, ?SETS:new()),
NewNodeInfo = set_killed_expr(NodeInfo, Label, KilledExprs),
- calc_killed_expr(CFG, NewNodeInfo, UseMap, AllExpr, Labels).
+ calc_killed_expr(CFG, NewNodeInfo, UseMap, AllExpr, IdMap, Labels).
%%=============================================================================
%% Calculates the killed expressions set for one basic block.
-calc_killed_expr_bb([], _UseMap, _AllExpr, KilledExprs) ->
+calc_killed_expr_bb([], _UseMap, _AllExpr, _IdMap, KilledExprs) ->
KilledExprs;
-calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) ->
+calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, IdMap, KilledExprs) ->
%% Calls, gctests and stores potentially clobber everything
case Instr of
#call{} -> AllExpr;
@@ -837,7 +837,8 @@ calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) ->
%% Kill all float expressions
%% FIXME: Make separate function is_fp_expr
?SETS:from_list
- (lists:foldl(fun(Expr, Fexprs) ->
+ (lists:foldl(fun(ExprId, Fexprs) ->
+ Expr = expr_id_map_get_expr(IdMap, ExprId),
[Define|_] = hipe_rtl:defines(Expr),
case hipe_rtl:is_fpreg(Define) of
true ->
@@ -849,10 +850,10 @@ calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) ->
_ ->
case hipe_rtl:defines(Instr) of
[] ->
- calc_killed_expr_bb(Instrs, UseMap, AllExpr, KilledExprs);
+ calc_killed_expr_bb(Instrs, UseMap, AllExpr, IdMap, KilledExprs);
[Define|_] ->
NewKilledExprs = use_map_get_expr_uses(UseMap, Define),
- calc_killed_expr_bb(Instrs, UseMap, AllExpr,
+ calc_killed_expr_bb(Instrs, UseMap, AllExpr, IdMap,
?SETS:union(NewKilledExprs, KilledExprs))
end
end.
diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl
index 8a9d8f7883..9be547c690 100644
--- a/lib/stdlib/test/qlc_SUITE.erl
+++ b/lib/stdlib/test/qlc_SUITE.erl
@@ -6118,6 +6118,7 @@ otp_6964(Config) when is_list(Config) ->
qlc:e(Q, [{max_list_size,64*1024},{tmpdir_usage,Use}])
end,
D = erlang:system_flag(backtrace_depth, 0),
+ try
20000 = length(F(allowed)),
ErrReply = F(not_allowed),
{error, qlc, {tmpdir_usage,joining}} = ErrReply,
@@ -6129,8 +6130,10 @@ otp_6964(Config) when is_list(Config) ->
20000 = length(F(info_msg)),
{info, joining} = qlc_SUITE:read_error_logger(),
20000 = length(F(error_msg)),
- {error, joining} = qlc_SUITE:read_error_logger(),
- _ = erlang:system_flag(backtrace_depth, D),
+ {error, joining} = qlc_SUITE:read_error_logger()
+ after
+ _ = erlang:system_flag(backtrace_depth, D)
+ end,
qlc_SUITE:uninstall_error_logger()">>],
?line run(Config, T1),
diff --git a/otp_build b/otp_build
index 76f1d20ff7..164e0b5f4e 100755
--- a/otp_build
+++ b/otp_build
@@ -174,9 +174,9 @@ set_config_flags ()
# the cross configuration have been moved here).
if target_contains linux; then
- XX=`echo $* | grep -v able-hipe`
+ XX=`echo $* | grep -v able-fp-exceptions`
if [ "$*" = "$XX" ]; then
- CONFIG_FLAGS="$CONFIG_FLAGS --disable-hipe"
+ CONFIG_FLAGS="$CONFIG_FLAGS --disable-fp-exceptions"
fi
fi
if target_contains "univel-sysv4"; then