anchor.diff:              Xs = reserve_call_args(tl(Args)),
               reserve_xregs_is(Is, Res, Xs, Used);
           _ ->
  -            reserve_xregs_is(Is, Res, Xs1, Used)
  -    end;
  -reserve_xregs_is([], Res, _Xs, _Used) -> Res.
  -
  -reserve_terminator(L, #b_br{bool=#b_literal{val=true},succ=Succ}, Blocks, Res) ->
  -    case maps:get(Succ, Blocks) of
  +            reserve_xregs_is(Is, Res, Xs0, Used)
  +    end;
  +reserve_xregs_is([], Res, Xs, _Used) ->
  +    {Res,Xs}.
  +
  +%% Pick up register hints from the successors of this blocks.
  +reserve_terminator(_L, _Is, #b_br{bool=#b_var{},succ=Succ,fail=?BADARG_BLOCK},
  +                   _Blocks, XsMap, _Res) ->
  +    %% We know that no variables are used at ?BADARG_BLOCK, so
  +    %% any register hints from the success blocks are safe to use.
  +    map_get(Succ, XsMap);
  +reserve_terminator(L, Is, #b_br{bool=#b_var{},succ=Succ,fail=Fail},
  +                   Blocks, XsMap, Res) when Succ =/= Fail ->
  +    #{Succ:=SuccBlk,Fail:=FailBlk} = Blocks,
  +    case {SuccBlk,FailBlk} of
  +        {#b_blk{is=[],last=#b_br{succ=PhiL,fail=PhiL}},
  +         #b_blk{is=[],last=#b_br{succ=PhiL,fail=PhiL}}} ->
  +            %% Both branches ultimately transfer to the same
  +            %% block (via two blocks with no instructions).
  +            %% Pick up register hints from the phi nodes
  +            %% in the common block.
  +            #{PhiL:=#b_blk{is=PhiIs}} = Blocks,
  +            Xs = res_xregs_from_phi(PhiIs, Succ, Res, #{}),
  +            res_xregs_from_phi(PhiIs, Fail, Res, Xs);
  +        {_,_} when Is =/= [] ->
  +            case last(Is) of
  +                #b_set{op=succeeded,args=[Arg]} ->
  +                    %% We know that Arg will not be used at the failure
  +                    %% label, so we can pick up register hints from the
  +                    %% success label.
  +                    Br = #b_br{bool=#b_literal{val=true},succ=Succ,fail=Succ},
  +                    case reserve_terminator(L, [], Br, Blocks, XsMap, Res) of
  +                        #{Arg:=Reg} -> #{Arg=>Reg};
  +                        #{} -> #{}
  +                    end;
  +                _ ->
  +                    %% Register hints from the success block may not
  +                    %% be safe at the failure block, and vice versa.
  +                    #{}
  +            end;
  +        {_,_} ->
  +            %% Register hints from the success block may not
  +            %% be safe at the failure block, and vice versa.
  +            #{}
  +    end;
  +reserve_terminator(L, Is, #b_br{bool=#b_literal{val=true},succ=Succ},
  +                   Blocks, XsMap, Res) ->
  +    case map_get(Succ, Blocks) of
           #b_blk{is=[],last=Last} ->
  -            reserve_terminator(Succ, Last, Blocks, Res);
  -        #b_blk{is=[_|_]=Is} ->
  -            {res_xregs_from_phi(Is, L, Res, #{}),[]}
  -    end;
  -reserve_terminator(_, Last, _, _) ->
  -    {#{},beam_ssa:used(Last)}.
  -
  +            reserve_terminator(Succ, Is, Last, Blocks, XsMap, Res);
  +        #b_blk{is=[_|_]=PhiIs} ->
  +            res_xregs_from_phi(PhiIs, L, Res, #{})
  +    end;
  +reserve_terminator(_, _, _, _, _, _) -> #{}.
  +
  +%% Pick up a reservation from a phi node.
   res_xregs_from_phi([#b_set{op=phi,dst=Dst,args=Args}|Is],
                      Pred, Res, Acc) ->
       case [V || {#b_var{}=V,L} <- Args, L =:= Pred] of
           [] ->
  +            %% The value of the phi node for this predecessor
  +            %% is a literal. Nothing to do here.
               res_xregs_from_phi(Is, Pred, Res, Acc);
           [V] ->
               case Res of
                   #{Dst:={prefer,Reg}} ->
  +                    %% Try placing V in the same register as for
  +                    %% the phi node.
                       res_xregs_from_phi(Is, Pred, Res, Acc#{V=>Reg});
                   #{Dst:=_} ->
                       res_xregs_from_phi(Is, Pred, Res, Acc)
  
positive.code:             end
      end.
  
  is_gc_safe(#b_set{op=phi}) ->
      false;
  is_gc_safe(#b_set{op=Op,args=Args}) ->
      case beam_ssa_codegen:classify_heap_need(Op, Args) of
          neutral -> true;
          {put,_} -> true;
          _ -> false
      end.
  
  %% res_xregs_prune(PreferredRegs, Used, Res) -> PreferredRegs.
  %%  Prune the list of preferred to only include X registers that
  %%  are guaranteed to survice a garbage collection.
  
  res_xregs_prune(Xs, Used, Res) ->
      %% The number of safe registers is the number of the X registers
      %% used after this point. The actual number of safe registers may
      %% be highter than this number, but this is a conservative safe
      %% estimate.
      NumSafe = foldl(fun(V, N) ->
                              case Res of
  
negative.code: reserve_xreg(V, Xs, Res) ->
      case Res of
          #{V:=_} ->
              %% Already reserved (but not as an X register).
              Res;
          #{} ->
              case Xs of
                  #{V:=X} ->
                      %% Add a hint that this specific X register is
                      %% preferred, unless it is already in use.
                      Res#{V=>{prefer,X}};
                  #{} ->
  