Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
3271-compiler-Stop-emitting-the-fclearerror-and...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 3271-compiler-Stop-emitting-the-fclearerror-and-fcheckerr.patch of Package erlang
From 07a5ebafff7d0a4fe85e8eb2b41e11c56118a214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org> Date: Mon, 25 Jan 2021 14:19:42 +0100 Subject: [PATCH] compiler: Stop emitting the fclearerror and fcheckerror instructions The fclearerror and fcheckerror instructions have been ignored by the BEAM loader for many releases. Therefore, update the compiler to stop emitting them. This also eliminates the bug reported in ERL-1471. While at it, take the opportunity to clean up and simplify the floating point optimizations. --- lib/compiler/src/beam_block.erl | 2 - lib/compiler/src/beam_flatten.erl | 2 - lib/compiler/src/beam_jump.erl | 2 - lib/compiler/src/beam_ssa_codegen.erl | 4 - lib/compiler/src/beam_ssa_opt.erl | 168 +++++++----------- lib/compiler/src/beam_ssa_pre_codegen.erl | 1 - lib/compiler/src/beam_validator.erl | 19 +- lib/compiler/src/compile.erl | 2 +- lib/compiler/src/genop.tab | 3 + lib/compiler/test/beam_validator_SUITE.erl | 12 +- .../beam_validator_SUITE_data/freg_range.S | 4 - .../beam_validator_SUITE_data/freg_uninit.S | 3 - 12 files changed, 80 insertions(+), 142 deletions(-) diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl index 4f2b2ff6d6..f5860bf93c 100644 --- a/lib/compiler/src/beam_block.erl +++ b/lib/compiler/src/beam_block.erl @@ -130,8 +130,6 @@ collect({get_tl,S,D}) -> {set,[D],[S],get_tl}; collect(remove_message) -> {set,[],[],remove_message}; collect({put_map,{f,0},Op,S,D,R,{list,Puts}}) -> {set,[D],[S|Puts],{alloc,R,{put_map,Op,{f,0}}}}; -collect(fclearerror) -> {set,[],[],fclearerror}; -collect({fcheckerror,{f,0}}) -> {set,[],[],fcheckerror}; collect({fmove,S,D}) -> {set,[D],[S],fmove}; collect({fconv,S,D}) -> {set,[D],[S],fconv}; collect(_) -> error. diff --git a/lib/compiler/src/beam_flatten.erl b/lib/compiler/src/beam_flatten.erl index e532831a91..a6673d2abc 100644 --- a/lib/compiler/src/beam_flatten.erl +++ b/lib/compiler/src/beam_flatten.erl @@ -65,8 +65,6 @@ norm({set,[D],[S],get_tl}) -> {get_tl,S,D}; norm({set,[D],[S|Puts],{alloc,R,{put_map,Op,F}}}) -> {put_map,F,Op,S,D,R,{list,Puts}}; norm({set,[],[],remove_message}) -> remove_message; -norm({set,[],[],fclearerror}) -> fclearerror; -norm({set,[],[],fcheckerror}) -> {fcheckerror,{f,0}}; norm({set,[],[],{line,_}=Line}) -> Line. norm_allocate({_Zero,nostack,Nh,[]}, Regs) -> diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl index 2382861ef0..56ffc8c949 100644 --- a/lib/compiler/src/beam_jump.erl +++ b/lib/compiler/src/beam_jump.erl @@ -856,8 +856,6 @@ instr_labels({put_map,Lbl,_Op,_Src,_Dst,_Live,_List}) -> do_instr_labels(Lbl); instr_labels({recv_set,Lbl}) -> do_instr_labels(Lbl); -instr_labels({fcheckerror,Lbl}) -> - do_instr_labels(Lbl); instr_labels({bs_start_match4,Fail,_,_,_}) -> case Fail of {f,L} -> [L]; diff --git a/lib/compiler/src/beam_ssa_codegen.erl b/lib/compiler/src/beam_ssa_codegen.erl index 2c51829a6d..2a0069c282 100644 --- a/lib/compiler/src/beam_ssa_codegen.erl +++ b/lib/compiler/src/beam_ssa_codegen.erl @@ -1206,8 +1206,6 @@ cg_block([#cg_set{op=bs_put,dst=Bool,args=Args0}], {Bool,Fail}, St) -> cg_block([#cg_set{op=bs_test_tail,dst=Bool,args=Args0}], {Bool,Fail}, St) -> [Ctx,{integer,Bits}] = beam_args(Args0, St), {[{test,bs_test_tail2,bif_fail(Fail),[Ctx,Bits]}],St}; -cg_block([#cg_set{op={float,checkerror},dst=Bool}], {Bool,Fail}, St) -> - {[{fcheckerror,bif_fail(Fail)}],St}; cg_block([#cg_set{op=is_tagged_tuple,dst=Bool,args=Args0}], {Bool,Fail}, St) -> [Src,{integer,Arity},Tag] = beam_args(Args0, St), {[{test,is_tagged_tuple,ensure_label(Fail, St),[Src,Arity,Tag]}],St}; @@ -1691,8 +1689,6 @@ cg_instr(build_stacktrace, Args, Dst) -> setup_args(Args) ++ [build_stacktrace|copy({x,0}, Dst)]; cg_instr(set_tuple_element=Op, [New,Tuple,{integer,Index}], _Dst) -> [{Op,New,Tuple,Index}]; -cg_instr({float,clearerror}, [], _Dst) -> - [fclearerror]; cg_instr({float,get}, [Src], Dst) -> [{fmove,Src,Dst}]; cg_instr({float,put}, [Src], Dst) -> diff --git a/lib/compiler/src/beam_ssa_opt.erl b/lib/compiler/src/beam_ssa_opt.erl index 2ebd3b1ab6..fe7510a828 100644 --- a/lib/compiler/src/beam_ssa_opt.erl +++ b/lib/compiler/src/beam_ssa_opt.erl @@ -1029,15 +1029,11 @@ cse_suitable(#b_set{}) -> false. %%% them in guards would require a new version of the 'fconv' %%% instruction that would take a failure label. Since it is unlikely %%% that using float instructions in guards would be beneficial, why -%%% bother implementing a new instruction? Also, implementing float -%%% instructions in guards in HiPE could turn out to be a lot of work. +%%% bother implementing a new instruction? %%% -record(fs, - {s=undefined :: 'undefined' | 'cleared', - regs=#{} :: #{beam_ssa:b_var():=beam_ssa:b_var()}, - vars=sets:new([{version, 2}]) :: sets:set(), - fail=none :: 'none' | beam_ssa:label(), + {regs=#{} :: #{beam_ssa:b_var():=beam_ssa:b_var()}, non_guards :: gb_sets:set(beam_ssa:label()), bs :: beam_ssa:block_map() }). @@ -1074,22 +1070,30 @@ float_opt([], Count, _Fs) -> float_opt_1(L, #b_blk{is=Is0}=Blk0, Bs0, Count0, Fs0) -> case float_opt_is(Is0, Fs0, Count0, []) of {Is1,Fs1,Count1} -> - Fs2 = float_fail_label(Blk0, Fs1), - Fail = Fs2#fs.fail, - {Flush,Blk,Fs,Count2} = float_maybe_flush(Blk0, Fs2, Count1), - Split = float_split_conv(Is1, Blk), - {Blks0,Count3} = float_number(Split, L, Count2), - {Blks,Count4} = float_conv(Blks0, Fail, Count3), - {Bs,Count} = float_opt(Bs0, Count4, Fs), + {Flush,Blk,Fs,Count2} = float_maybe_flush(Blk0, Fs1, Count1), + {Blks,Count3} = float_fixup_conv(L, Is1, Blk, Count2), + {Bs,Count} = float_opt(Bs0, Count3, Fs), {Blks++Flush++Bs,Count}; none -> {Bs,Count} = float_opt(Bs0, Count0, Fs0), {[{L,Blk0}|Bs],Count} end. +%% Split out {float,convert} instructions into separate blocks, number +%% the blocks, and add {succeded,body} in each {float,convert} block. +float_fixup_conv(L, Is, Blk, Count0) -> + Split = float_split_conv(Is, Blk), + {Blks,Count} = float_number(Split, L, Count0), + #b_blk{last=#b_br{bool=#b_var{},fail=Fail}} = Blk, + float_conv(Blks, Fail, Count). + %% Split {float,convert} instructions into individual blocks. float_split_conv(Is0, Blk) -> Br = #b_br{bool=#b_literal{val=true},succ=0,fail=0}, + + %% Note that there may be other instructions such as + %% remove_message before the floating point instructions; + %% therefore, it is essential that we don't reorder instructions. case splitwith(fun(#b_set{op=Op}) -> Op =/= {float,convert} end, Is0) of @@ -1102,85 +1106,77 @@ float_split_conv(Is0, Blk) -> [#b_blk{is=[Conv],last=Br}|float_split_conv(Is1, Blk)] end. -%% Number the blocks that were split. -float_number([B|Bs0], FirstL, Count0) -> - {Bs,Count} = float_number(Bs0, Count0), - {[{FirstL,B}|Bs],Count}. +%% Number and chain the blocks that were split. +float_number(Bs0, FirstL, Count0) -> + {[{_,FirstBlk}|Bs],Count} = float_number(Bs0, Count0), + {[{FirstL,FirstBlk}|Bs],Count}. +float_number([B], Count) -> + {[{Count,B}],Count}; float_number([B|Bs0], Count0) -> - {Bs,Count} = float_number(Bs0, Count0+1), - {[{Count0,B}|Bs],Count}; -float_number([], Count) -> - {[],Count}. + Next = Count0 + 1, + {Bs,Count} = float_number(Bs0, Next), + Br = #b_br{bool=#b_literal{val=true},succ=Next,fail=Next}, + {[{Count0,B#b_blk{last=Br}}|Bs],Count}. %% Insert 'succeeded' instructions after each {float,convert} %% instruction. -float_conv([{L,#b_blk{is=Is0}=Blk0}|Bs0], Fail, Count0) -> +float_conv([{L,#b_blk{is=Is0,last=Last}=Blk0}|Bs0], Fail, Count0) -> case Is0 of [#b_set{op={float,convert}}=Conv] -> - {Bool0,Count1} = new_reg('@ssa_bool', Count0), - Bool = #b_var{name=Bool0}, + {Bool,Count1} = new_var('@ssa_bool', Count0), Succeeded = #b_set{op={succeeded,body},dst=Bool, args=[Conv#b_set.dst]}, Is = [Conv,Succeeded], - [{NextL,_}|_] = Bs0, - Br = #b_br{bool=Bool,succ=NextL,fail=Fail}, + Br = Last#b_br{bool=Bool,fail=Fail}, Blk = Blk0#b_blk{is=Is,last=Br}, {Bs,Count} = float_conv(Bs0, Fail, Count1), {[{L,Blk}|Bs],Count}; [_|_] -> - case Bs0 of - [{NextL,_}|_] -> - Br = #b_br{bool=#b_literal{val=true}, - succ=NextL,fail=NextL}, - Blk = Blk0#b_blk{last=Br}, - {Bs,Count} = float_conv(Bs0, Fail, Count0), - {[{L,Blk}|Bs],Count}; - [] -> - {[{L,Blk0}],Count0} - end - end. + {Bs,Count} = float_conv(Bs0, Fail, Count0), + {[{L,Blk0}|Bs],Count} + end; +float_conv([], _, Count) -> + {[],Count}. -float_maybe_flush(Blk0, #fs{s=cleared,fail=Fail,bs=Blocks}=Fs0, Count0) -> +float_maybe_flush(Blk0, Fs0, Count0) -> #b_blk{last=#b_br{bool=#b_var{},succ=Succ}=Br} = Blk0, - %% If the success block starts with a floating point operation, we can - %% defer flushing to that block as long as it's suitable for optimization. - #b_blk{is=Is} = SuccBlk = map_get(Succ, Blocks), - CanOptimizeSucc = float_can_optimize_blk(SuccBlk, Fs0), - - case Is of - [#b_set{anno=#{float_op:=_}}|_] when CanOptimizeSucc -> + %% If the success block has an optimizable floating point instruction, + %% it is safe to defer flushing. + case float_safe_to_skip_flush(Succ, Fs0) of + true -> %% No flush needed. {[],Blk0,Fs0,Count0}; - _ -> - %% Flush needed. - {Bool0,Count1} = new_reg('@ssa_bool', Count0), - Bool = #b_var{name=Bool0}, - - %% Allocate block numbers. - CheckL = Count1, %For checkerror. - FlushL = Count1 + 1, %For flushing of float regs. - Count = Count1 + 2, - Blk = Blk0#b_blk{last=Br#b_br{succ=CheckL}}, - - %% Build the block with the checkerror instruction. - CheckIs = [#b_set{op={float,checkerror},dst=Bool}], - CheckBr = #b_br{bool=Bool,succ=FlushL,fail=Fail}, - CheckBlk = #b_blk{is=CheckIs,last=CheckBr}, + false -> + %% Flush needed. Allocate block numbers. + FlushL = Count0, %For flushing of float regs. + Count = Count0 + 1, + Blk = Blk0#b_blk{last=Br#b_br{succ=FlushL}}, %% Build the block that flushes all registers. FlushIs = float_flush_regs(Fs0), FlushBr = #b_br{bool=#b_literal{val=true},succ=Succ,fail=Succ}, FlushBlk = #b_blk{is=FlushIs,last=FlushBr}, - %% Update state and blocks. - Fs = Fs0#fs{s=undefined,regs=#{},fail=none}, - FlushBs = [{CheckL,CheckBlk},{FlushL,FlushBlk}], + %% Update state record and blocks. + Fs = Fs0#fs{regs=#{}}, + FlushBs = [{FlushL,FlushBlk}], {FlushBs,Blk,Fs,Count} - end; -float_maybe_flush(Blk, Fs, Count) -> - {[],Blk,Fs,Count}. + end. + +float_safe_to_skip_flush(L, #fs{bs=Blocks}=Fs) -> + #b_blk{is=Is} = Blk = map_get(L, Blocks), + float_can_optimize_blk(Blk, Fs) andalso float_optimizable_is(Is). + +float_optimizable_is([#b_set{anno=#{float_op:=_}}|_]) -> + true; +float_optimizable_is([#b_set{op=get_tuple_element}|Is]) -> + %% The tuple sinking optimization can sink get_tuple_element instruction + %% into a sequence of floating point operations. + float_optimizable_is(Is); +float_optimizable_is(_) -> + false. float_opt_is([#b_set{op={succeeded,_},args=[Src]}=I0], #fs{regs=Rs}=Fs, Count, Acc) -> @@ -1189,7 +1185,7 @@ float_opt_is([#b_set{op={succeeded,_},args=[Src]}=I0], I = I0#b_set{args=[Fr]}, {reverse(Acc, [I]),Fs,Count}; #{} -> - {reverse(Acc, [I0]),Fs,Count} + none end; float_opt_is([#b_set{anno=Anno0}=I0|Is0], Fs0, Count0, Acc) -> case Anno0 of @@ -1199,30 +1195,20 @@ float_opt_is([#b_set{anno=Anno0}=I0|Is0], Fs0, Count0, Acc) -> {Is,Fs,Count} = float_make_op(I1, FTypes, Fs0, Count0), float_opt_is(Is0, Fs, Count, reverse(Is, Acc)); #{} -> - float_opt_is(Is0, Fs0#fs{regs=#{}}, Count0, [I0|Acc]) + float_opt_is(Is0, Fs0, Count0, [I0|Acc]) end; -float_opt_is([], Fs, _Count, _Acc) -> - #fs{s=undefined} = Fs, %Assertion. +float_opt_is([], _Fs, _Count, _Acc) -> none. float_make_op(#b_set{op={bif,Op},dst=Dst,args=As0,anno=Anno}=I0, - Ts, #fs{s=S,regs=Rs0,vars=Vs0}=Fs, Count0) -> + Ts, #fs{regs=Rs0}=Fs, Count0) -> {As1,Rs1,Count1} = float_load(As0, Ts, Anno, Rs0, Count0, []), {As,Is0} = unzip(As1), - {Fr,Count2} = new_reg('@fr', Count1), - FrDst = #b_var{name=Fr}, + {FrDst,Count2} = new_var('@fr', Count1), I = I0#b_set{op={float,Op},dst=FrDst,args=As}, - Vs = sets:add_element(Dst, Vs0), Rs = Rs1#{Dst=>FrDst}, Is = append(Is0) ++ [I], - case S of - undefined -> - {Ignore,Count} = new_reg('@ssa_ignore', Count2), - C = #b_set{op={float,clearerror},dst=#b_var{name=Ignore}}, - {[C|Is],Fs#fs{s=cleared,regs=Rs,vars=Vs},Count}; - cleared -> - {Is,Fs#fs{regs=Rs,vars=Vs},Count2} - end. + {Is,Fs#fs{regs=Rs},Count2}. float_load([A|As], [T|Ts], Anno, Rs0, Count0, Acc) -> {Load,Rs,Count} = float_reg_arg(A, T, Anno, Rs0, Count0), @@ -1235,8 +1221,7 @@ float_reg_arg(A, T, Anno, Rs, Count0) -> #{A:=Fr} -> {{Fr,[]},Rs,Count0}; #{} -> - {Fr,Count} = new_float_copy_reg(Count0), - Dst = #b_var{name=Fr}, + {Dst,Count} = new_var('@fr_copy', Count0), I0 = float_load_reg(T, A, Dst), I = I0#b_set{anno=Anno}, {{Dst,[I]},Rs#{A=>Dst},Count} @@ -1256,21 +1241,6 @@ float_load_reg(convert, #b_literal{val=Val}=Src, Dst) -> float_load_reg(float, Src, Dst) -> #b_set{op={float,put},dst=Dst,args=[Src]}. -new_float_copy_reg(Count) -> - new_reg('@fr_copy', Count). - -new_reg(Base, Count) -> - Fr = {Base,Count}, - {Fr,Count+1}. - -float_fail_label(#b_blk{last=Last}, Fs) -> - case Last of - #b_br{bool=#b_var{},fail=Fail} -> - Fs#fs{fail=Fail}; - _ -> - Fs - end. - float_flush_regs(#fs{regs=Rs}) -> maps:fold(fun(_, #b_var{name={'@fr_copy',_}}, Acc) -> Acc; diff --git a/lib/compiler/src/beam_ssa_pre_codegen.erl b/lib/compiler/src/beam_ssa_pre_codegen.erl index 25eef27bdc..2c12a73903 100644 --- a/lib/compiler/src/beam_ssa_pre_codegen.erl +++ b/lib/compiler/src/beam_ssa_pre_codegen.erl @@ -2630,7 +2630,6 @@ use_zreg(bs_match_string) -> yes; use_zreg(bs_save) -> yes; use_zreg(bs_restore) -> yes; use_zreg(bs_set_position) -> yes; -use_zreg({float,clearerror}) -> yes; use_zreg(kill_try_tag) -> yes; use_zreg(landingpad) -> yes; use_zreg(put_tuple_elements) -> yes; diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 02eecea29c..233167b536 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -687,8 +687,6 @@ vi(return, Vst) -> vi({bif,Op,{f,Fail},Ss,Dst}, Vst0) -> case is_float_arith_bif(Op, Ss) of true -> - %% Float arithmetic BIFs neither fail nor throw an exception; - %% errors are postponed until the next fcheckerror instruction. ?EXCEPTION_LABEL = Fail, %Assertion. validate_float_arith_bif(Ss, Dst, Vst0); false -> @@ -964,16 +962,11 @@ vi({bs_set_position, Ctx, Pos}, Vst0) -> %% vi({fconv,Src,{fr,_}=Dst}, Vst) -> assert_term(Src, Vst), - branch(?EXCEPTION_LABEL, Vst, fun(SuccVst0) -> SuccVst = update_type(fun meet/2, number, Src, SuccVst0), set_freg(Dst, SuccVst) end); -vi(fclearerror, Vst) -> - Vst; -vi({fcheckerror, _}, Vst) -> - branch(?EXCEPTION_LABEL, Vst); %% %% Exception-raising instructions @@ -1790,14 +1783,6 @@ assert_arities([Arity,{f,_}|T]) when is_integer(Arity) -> assert_arities([]) -> ok; assert_arities(_) -> error(bad_tuple_arity_list). - -%%% -%%% Floating point helpers. -%%% -%%% fconv Src {fr,_} -%%% fmove Src {fr,_} %% Move known float INTO floating point register. -%%% - is_float_arith_bif(fadd, [_, _]) -> true; is_float_arith_bif(fdiv, [_, _]) -> true; is_float_arith_bif(fmul, [_, _]) -> true; @@ -2925,9 +2910,7 @@ will_bif_succeed(raise, [_,_], _Vst) -> will_bif_succeed(Op, Ss, Vst) -> case is_float_arith_bif(Op, Ss) of true -> - %% Float arithmetic BIFs can't fail; their error checking is - %% deferred until fcheckerror. - yes; + maybe; false -> Args = [normalize(get_term_type(Arg, Vst)) || Arg <- Ss], beam_call_types:will_succeed(erlang, Op, Args) diff --git a/lib/compiler/src/genop.tab b/lib/compiler/src/genop.tab index 26eaebe1d1..fafffdc03f 100755 --- a/lib/compiler/src/genop.tab +++ b/lib/compiler/src/genop.tab @@ -397,6 +397,9 @@ BEAM_FORMAT_NUMBER=0 # # Floating point arithmetic (R8). # +# The fclearerror and fcheckerror instructions are not used in OTP 24 +# and later. +# 94: fclearerror/0 95: fcheckerror/1 96: fmove/2 diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index 8295e09d36..49731f9137 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -262,19 +262,19 @@ freg_range(Config) when is_list(Config) -> Errors = do_val(freg_range, Config), [{{t,sum_1,2}, {{bif,fadd,{f,0},[{fr,-1},{fr,1}],{fr,0}}, - 5, + 4, {bad_source,{fr,-1}}}}, {{t,sum_2,2}, {{bif,fadd,{f,0},[{fr,0},{fr,1024}],{fr,0}}, - 6, + 5, {uninitialized_reg,{fr,1024}}}}, {{t,sum_3,2}, {{bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,-1}}, - 7, + 6, {bad_register,{fr,-1}}}}, {{t,sum_4,2}, {{bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,1024}}, - 7, + 6, limit}}] = Errors, ok. @@ -282,11 +282,11 @@ freg_uninit(Config) when is_list(Config) -> Errors = do_val(freg_uninit, Config), [{{t,sum_1,2}, {{bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,0}}, - 6, + 5, {uninitialized_reg,{fr,1}}}}, {{t,sum_2,2}, {{bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,0}}, - 10, + 8, {uninitialized_reg,{fr,0}}}}] = Errors, ok. diff --git a/lib/compiler/test/beam_validator_SUITE_data/freg_range.S b/lib/compiler/test/beam_validator_SUITE_data/freg_range.S index b3ebff3ade..5ae96e8e8b 100644 --- a/lib/compiler/test/beam_validator_SUITE_data/freg_range.S +++ b/lib/compiler/test/beam_validator_SUITE_data/freg_range.S @@ -11,7 +11,6 @@ {label,1}. {func_info,{atom,t},{atom,sum_1},2}. {label,2}. - fclearerror. {bif,fadd,{f,0},[{fr,-1},{fr,1}],{fr,0}}. {'%live',1}. return. @@ -22,7 +21,6 @@ {func_info,{atom,t},{atom,sum_2},2}. {label,4}. {fconv,{x,0},{fr,0}}. - fclearerror. {bif,fadd,{f,0},[{fr,0},{fr,1024}],{fr,0}}. {'%live',1}. return. @@ -34,7 +32,6 @@ {label,6}. {fconv,{x,0},{fr,0}}. {fconv,{x,1},{fr,1}}. - fclearerror. {bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,-1}}. {'%live',1}. return. @@ -46,7 +43,6 @@ {label,8}. {fconv,{x,0},{fr,0}}. {fconv,{x,1},{fr,1}}. - fclearerror. {bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,1024}}. {'%live',1}. return. diff --git a/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S b/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S index 2d4cbc9388..79fceb24d0 100644 --- a/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S +++ b/lib/compiler/test/beam_validator_SUITE_data/freg_uninit.S @@ -12,7 +12,6 @@ {func_info,{atom,t},{atom,sum_1},2}. {label,2}. {fconv,{x,0},{fr,0}}. - fclearerror. {bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,0}}. return. @@ -24,8 +23,6 @@ {allocate,0,2}. {fconv,{x,0},{fr,0}}. {fconv,{x,1},{fr,1}}. - fclearerror. - {fcheckerror,{f,0}}. {call,2,{f,6}}. {bif,fadd,{f,0},[{fr,0},{fr,1}],{fr,0}}. {deallocate,0}. -- 2.31.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor