anchor.diff:  	_ -> error({illegal_restore,SavePoint,range})
       end.
   
  -select_val_branches(Fail, Src, Choices, Vst0) ->
  -    Vst = svb_1(Choices, Src, Vst0),
  -    kill_state(branch_state(Fail, Vst)).
  -
  -svb_1([Val,{f,L}|T], Src, Vst0) ->
  -    Vst = complex_test(L,
  -                       fun(BranchVst) ->
  -                               update_eq_types(Src, Val, BranchVst)
  -                       end,
  -                       fun(FailVst) ->
  -                               update_ne_types(Src, Val, FailVst)
  -                       end, Vst0),
  -    svb_1(T, Src, Vst);
  -svb_1([], _, Vst) ->
  +select_val_branches([Val,{f,L}|T], Src, Vst0) ->
  +    Vst = branch(L, Vst0,
  +                 fun(BranchVst) ->
  +                         update_eq_types(Src, Val, BranchVst)
  +                 end,
  +                 fun(FailVst) ->
  +                         update_ne_types(Src, Val, FailVst)
  +                 end),
  +    select_val_branches(T, Src, Vst);
  +select_val_branches([], _, Vst) ->
       Vst.
   
  -select_arity_branches(Fail, List, Tuple, Vst0) ->
  -    Type = get_term_type(Tuple, Vst0),
  -    Vst = sab_1(List, Tuple, Type, Vst0),
  -    kill_state(branch_state(Fail, Vst)).
  -
  -sab_1([Sz,{f,L}|T], Tuple, {tuple,[_],Es}=Type0, Vst0) ->
  -    #vst{current=St0} = Vst0,
  -    Vst1 = update_type(fun meet/2, {tuple,Sz,Es}, Tuple, Vst0),
  -    Vst2 = branch_state(L, Vst1),
  -    Vst = Vst2#vst{current=St0},
  -
  -    sab_1(T, Tuple, Type0, Vst);
  -sab_1([Sz,{f,L}|T], Tuple, {tuple,Sz,_Es}=Type, Vst0) ->
  -    %% The type is already correct. (This test is redundant.)
  -    Vst = branch_state(L, Vst0),
  -    sab_1(T, Tuple, Type, Vst);
  -sab_1([_,{f,_}|T], Tuple, Type, Vst) ->
  -    %% We already have an established different exact size for the tuple.
  -    %% This label can't possibly be reached.
  -    sab_1(T, Tuple, Type, Vst);
  -sab_1([], _, _, #vst{}=Vst) ->
  +select_arity_branches([SzA,{f,L}|T], Tuple, Vst0) ->
  +    Vst = branch(L, Vst0,
  +                 fun(BranchVst) ->
  +                         update_type(fun meet/2, {tuple,SzA,#{}},
  +                                     Tuple, BranchVst)
  +                 end,
  +                 fun(FailVst) ->
  +                         FailVst
  +                 end),
  +    select_arity_branches(T, Tuple, Vst);
  +select_arity_branches([], _, #vst{}=Vst) ->
       Vst.
   
   infer_types({Kind,_}=Reg, Vst) when Kind =:= x; Kind =:= y ->
  
positive.code: valfun_4({make_fun2,_,_,_,Live}, Vst) ->
      call(make_fun, Live, Vst);
  %% Other BIFs
  valfun_4({bif,element,{f,Fail},[Pos,Tuple],Dst}, Vst0) ->
      Vst1 = branch_state(Fail, Vst0),
  
      PosType = get_term_type(Pos, Vst0),
      InferredType = {tuple,[get_tuple_size(PosType)],#{}},
  
      Vst2 = update_type(fun meet/2, InferredType, Tuple, Vst1),
      Vst = update_type(fun meet/2, {integer,[]}, Pos, Vst2),
  
      ElementType = get_element_type(PosType, Tuple, Vst),
      extract_term(ElementType, {bif,element}, [Pos,Tuple], Dst, Vst);
  valfun_4({bif,raise,{f,0},Src,_Dst}, Vst) ->
      validate_src(Src, Vst),
      kill_state(Vst);
  valfun_4(raw_raise=I, Vst) ->
      call(I, 3, Vst);
  valfun_4({bif,Op,{f,Fail},[Cons]=Ss,Dst}, Vst0)
    when Op =:= hd; Op =:= tl ->
      validate_src(Ss, Vst0),
      Vst = type_test(Fail, cons, Cons, Vst0),
      Type = bif_return_type(Op, Ss, Vst),
      extract_term(Type, {bif,Op}, Ss, Dst, Vst);
  valfun_4({bif,Op,{f,Fail},Ss,Dst}, Vst0) ->
      validate_src(Ss, Vst0),
      Vst1 = branch_state(Fail, Vst0),
  
      %% Infer argument types. Note that we can't type_test in the general case
      %% as the BIF could fail for reasons other than bad argument types.
      ArgTypes = bif_arg_types(Op, Ss),
      Vst = foldl(fun({Arg, T}, Vsti) ->
                          update_type(fun meet/2, T, Arg, Vsti)
                  end, Vst1, zip(Ss, ArgTypes)),
  
      Type = bif_return_type(Op, Ss, Vst),
      extract_term(Type, {bif,Op}, Ss, Dst, Vst);
  valfun_4({gc_bif,Op,{f,Fail},Live,Ss,Dst}, #vst{current=St0}=Vst0) ->
      validate_src(Ss, Vst0),
      verify_live(Live, Vst0),
      verify_y_init(Vst0),
      St = kill_heap_allocation(St0),
      Vst1 = Vst0#vst{current=St},
      Vst2 = branch_state(Fail, Vst1),
  
      ArgTypes = bif_arg_types(Op, Ss),
      Vst3 = foldl(fun({Arg, T}, Vsti) ->
                           update_type(fun meet/2, T, Arg, Vsti)
                   end, Vst2, zip(Ss, ArgTypes)),
  
      Type = bif_return_type(Op, Ss, Vst3),
      Vst = prune_x_regs(Live, Vst3),
      extract_term(Type, {gc_bif,Op}, Ss, Dst, Vst, Vst0);
  valfun_4(return, #vst{current=#st{numy=none}}=Vst) ->
      assert_durable_term({x,0}, Vst),
      kill_state(Vst);
  valfun_4(return, #vst{current=#st{numy=NumY}}) ->
      error({stack_frame,NumY});
  valfun_4({loop_rec,{f,Fail},Dst}, Vst0) ->
      %% This term may not be part of the root set until
      %% remove_message/0 is executed. If control transfers
      %% to the loop_rec_end/1 instruction, no part of
      %% this term must be stored in a Y register.
      Vst1 = branch_state(Fail, Vst0),
      {Ref, Vst} = new_value(term, loop_rec, [], Vst1),
      mark_fragile(Dst, set_reg_vref(Ref, Dst, Vst));
  valfun_4({wait,_}, Vst) ->
      verify_y_init(Vst),
      kill_state(Vst);
  
negative.code: init_catch_handler_1(_, _, Vst) ->
      Vst.
  
  valfun_2(I, #vst{current=#st{ct=[[Fail]|_]}}=Vst) when is_integer(Fail) ->
      %% We have an active try/catch tag and we can jump there from this
      %% instruction, so we need to update the branched state of the try/catch
      %% handler.
      valfun_3(I, branch_state(Fail, Vst));
  valfun_2(I, #vst{current=#st{ct=[]}}=Vst) ->
      valfun_3(I, Vst);
  valfun_2(_, _) ->
      error(ambiguous_catch_try_state).
  
  %% Handle the remaining floating point instructions here.
  %% Floating point.
  valfun_3({fconv,Src,{fr,_}=Dst}, Vst) ->
      assert_term(Src, Vst),
  
      %% An exception is raised on error, hence branching to 0.
      branch(0, Vst,
             fun(SuccVst0) ->
                 SuccVst = update_type(fun meet/2, number, Src, SuccVst0),
                 set_freg(Dst, SuccVst)
             end);
  valfun_3({bif,fadd,_,[_,_]=Ss,Dst}, Vst) ->
      float_op(Ss, Dst, Vst);
  valfun_3({bif,fdiv,_,[_,_]=Ss,Dst}, Vst) ->
  