anchor.diff:      end;
   float_non_guards([]) -> [?BADARG_BLOCK].
   
  -float_opt([{L,Blk0}|Bs], Count, Fs) ->
  -    Blk = float_rename_phis(Blk0, Fs),
  -    case float_need_flush(Blk, Fs) of
  -        true ->
  -            float_flush(L, Blk, Bs, Count, Fs);
  -        false ->
  -            float_opt_1(L, Blk, Bs, Count, Fs)
  -    end;
  -float_opt([], Count, _Fs) ->
  -    {[],Count}.
  -
  -float_opt_1(L, #b_blk{last=#b_br{fail=F}}=Blk, Bs0,
  +float_opt([{L,#b_blk{last=#b_br{fail=F}}=Blk}|Bs0],
               Count0, #fs{non_guards=NonGuards}=Fs) ->
       case gb_sets:is_member(F, NonGuards) of
           true ->
               %% This block is not inside a guard.
               %% We can do the optimization.
  -            float_opt_2(L, Blk, Bs0, Count0, Fs);
  +            float_opt_1(L, Blk, Bs0, Count0, Fs);
           false ->
               %% This block is inside a guard. Don't do
               %% any floating point optimizations.
               {Bs,Count} = float_opt(Bs0, Count0, Fs),
               {[{L,Blk}|Bs],Count}
       end;
  -float_opt_1(L, Blk, Bs, Count, Fs) ->
  -    float_opt_2(L, Blk, Bs, Count, Fs).
  -
  -float_opt_2(L, #b_blk{is=Is0}=Blk0, Bs0, Count0, Fs0) ->
  +float_opt([{L,Blk}|Bs], Count, Fs) ->
  +    float_opt_1(L, Blk, Bs, Count, Fs);
  +float_opt([], Count, _Fs) ->
  +    {[],Count}.
  +
  +float_opt_1(L, #b_blk{is=Is0}=Blk0, Bs0, Count0, Fs0) ->
       case float_opt_is(Is0, Fs0, Count0, []) of
           {Is1,Fs1,Count1} ->
  -            Fs = float_fail_label(Blk0, Fs1),
  -            Split = float_split_conv(Is1, Blk0),
  -            {Blks0,Count2} = float_number(Split, L, Count1),
  -            {Blks,Count3} = float_conv(Blks0, Fs#fs.fail, Count2),
  -            {Bs,Count} = float_opt(Bs0, Count3, Fs),
  -            {Blks++Bs,Count};
  +            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),
  +            {Blks++Flush++Bs,Count};
           none ->
               {Bs,Count} = float_opt(Bs0, Count0, Fs0),
               {[{L,Blk0}|Bs],Count}
  
positive.code: new_reg(Base, Count) ->
      Fr = {Base,Count},
      {Fr,Count+1}.
  
  float_flush(L, Blk, Bs0, Count0, #fs{s=cleared,fail=Fail,ren=Ren0}=Fs0) ->
      {Bool0,Count1} = new_reg('@ssa_bool', Count0),
      Bool = #b_var{name=Bool0},
  
      %% Insert two blocks before the current block. First allocate
      %% block numbers.
      FirstL = L,                                  %For checkerror.
      MiddleL = Count1,                            %For flushed float regs.
      LastL = Count1 + 1,                          %For original block.
      Count2 = Count1 + 2,
  
      %% Build the block with the checkerror instruction.
      CheckIs = [#b_set{op={float,checkerror},dst=Bool}],
      FirstBlk = #b_blk{is=CheckIs,last=#b_br{bool=Bool,succ=MiddleL,fail=Fail}},
  
      %% Build the block that flushes all registers. Note that this must be a
      %% separate block in case the original block begins with a phi instruction,
      %% to avoid embedding a phi instruction in the middle of a block.
      FlushIs = float_flush_regs(Fs0),
      MiddleBlk = #b_blk{is=FlushIs,last=#b_br{bool=#b_literal{val=true},
                                               succ=LastL,fail=LastL}},
  
      %% The last block is the original unmodified block.
      LastBlk = Blk,
  
      %% Update state and blocks.
      Ren = Ren0#{L=>LastL},
      Fs = Fs0#fs{s=undefined,regs=#{},fail=none,ren=Ren},
      Bs1 = [{FirstL,FirstBlk},{MiddleL,MiddleBlk},{LastL,LastBlk}|Bs0],
      float_opt(Bs1, Count2, Fs).
  
  float_fail_label(#b_blk{last=Last}, Fs) ->
      case Last of
  
negative.code:             end
      end.
  
  float_maybe_flush(Blk0, #fs{s=cleared,fail=Fail,bs=Blocks}=Fs0, Count0) ->
      #b_blk{last=#b_br{bool=#b_var{},succ=Succ}=Br} = Blk0,
      #b_blk{is=Is} = maps:get(Succ, Blocks),
      case Is of
          [#b_set{anno=#{float_op:=_}}|_] ->
              %% The next operation is also a floating point operation.
              %% 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},
  
              %% 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}],
              {FlushBs,Blk,Fs,Count}
      end;
  float_maybe_flush(Blk, Fs, Count) ->
      {[],Blk,Fs,Count}.
  
  float_opt_is([#b_set{op=succeeded,args=[Src]}=I0],
               #fs{regs=Rs}=Fs, Count, Acc) ->
  