anchor.diff:              I
       end;
   simplify(I, _Ts) -> I.
  +
  +will_succeed(#b_set{args=[Src]}, Ts, Ds, Sub) ->
  +    case {Ds, Ts} of
  +        {#{}, #{ Src := none }} ->
  +            %% Checked operation never returns.
  +            no;
  +        {#{ Src := I }, #{}} ->
  +            will_succeed_1(I, Src, Ts, Sub);
  +        {#{}, #{}} ->
  +            %% The checked instruction has been removed and substituted, so we
  +            %% can assume it always succeeds.
  +            true = is_map_key(Src, Sub),        %Assertion.
  +            yes
  +    end.
  +
  +will_succeed_1(#b_set{op=bs_get_tail}, _Src, _Ts, _Sub) ->
  +    yes;
  +will_succeed_1(#b_set{op=bs_start_match,args=[_, Arg]}, _Src, Ts, _Sub) ->
  +    ArgType = raw_type(Arg, Ts),
  +    case beam_types:is_bs_matchable_type(ArgType) of
  +        true ->
  +            %% In the future we may be able to remove this instruction
  +            %% altogether when we have a #t_bs_context{}, but for now we need
  +            %% to keep it for compatibility with older releases of OTP.
  +            yes;
  +        false ->
  +            %% Is it at all possible to match?
  +            case beam_types:meet(ArgType, #t_bs_matchable{}) of
  +                none -> no;
  +                _ -> maybe
  +            end
  +    end;
  +
  +will_succeed_1(#b_set{op={bif,Bif},args=BifArgs}, _Src, Ts, _Sub) ->
  +    ArgTypes = normalized_types(BifArgs, Ts),
  +    beam_call_types:will_succeed(erlang, Bif, ArgTypes);
  +will_succeed_1(#b_set{op=call,
  +                      args=[#b_remote{mod=#b_literal{val=Mod},
  +                            name=#b_literal{val=Func}} |
  +                            CallArgs]},
  +               _Src, Ts, _Sub) ->
  +            ArgTypes = normalized_types(CallArgs, Ts),
  +            beam_call_types:will_succeed(Mod, Func, ArgTypes);
  +
  +will_succeed_1(#b_set{op=get_hd}, _Src, _Ts, _Sub) ->
  +    yes;
  +will_succeed_1(#b_set{op=get_tl}, _Src, _Ts, _Sub) ->
  +    yes;
  +will_succeed_1(#b_set{op=get_tuple_element}, _Src, _Ts, _Sub) ->
  +    yes;
  +will_succeed_1(#b_set{op=put_tuple}, _Src, _Ts, _Sub) ->
  +    yes;
  +
  +%% These operations may fail even though we know their return value on success.
  +will_succeed_1(#b_set{op=call}, _Src, _Ts, _Sub) ->
  +    maybe;
  +
  +will_succeed_1(#b_set{op=wait}, _Src, _Ts, _Sub) ->
  +    no;
  +
  +will_succeed_1(#b_set{}, Src, Ts, Sub) ->
  +    case simplify_arg(Src, Ts, Sub) of
  +        #b_var{}=Src ->
  +            %% No substitution; might fail at runtime.
  +            maybe;
  +        _ ->
  +            %% Substituted with literal or other variable; always succeeds.
  +            yes
  +    end.
   
   simplify_is_record(I, #t_tuple{exact=Exact,
                                  size=Size,
  
positive.code:             Ds = Ds0#{Dst=>I},
              {I, Ts, Ds, Sub0}
      end;
  simplify(#b_set{op=succeeded,dst=Dst,args=[Arg],anno=Anno}=I,
           Ts0, Ds0, _Ls, Sub0) ->
      Type = case Ds0 of
                 #{ Arg := #b_set{op=call} } ->
                     %% Calls can always throw exceptions and their return types
                     %% are what they return on success, so we must avoid
                     %% simplifying arguments in case `Arg` would become a
                     %% literal, which would trick 'succeeded' into thinking it
                     %% can't fail.
                     type(succeeded, [Arg], Anno, Ts0, Ds0);
                 #{ Arg := _ } ->
                     Args = simplify_args([Arg], Ts0, Sub0),
                     type(succeeded, Args, Anno, Ts0, Ds0);
                 #{} ->
                     %% The checked instruction has been removed and substituted,
                     %% so we can assume it always succeeds.
                     #{ Arg := _ } = Sub0,        %Assertion.
                     beam_types:make_atom(true)
             end,
      case beam_types:get_singleton_value(Type) of
          {ok, Lit} ->
              Sub = Sub0#{ Dst => #b_literal{val=Lit} },
              {Lit, Sub};
          error ->
              Ts = Ts0#{ Dst => Type },
              Ds = Ds0#{ Dst => I },
              {I, Ts, Ds, Sub0}
      end;
  
negative.code:                             {Es, Index + 1}
                      end, {#{}, 1}, Args),
      #t_tuple{exact=true,size=length(Args),elements=Es};
  type(_, _, _, _, _) -> any.
  
  %% We seldom know how far a match operation may advance, but we can often tell
  