let doInstr stmt (i: instr) (_d: t) =
    let kinstr = !current_stmt
    in
    let add_with_additional_var k j st =
      let deps, looking_for =
        !Value.lval_to_loc_with_deps
          ~with_alarms:CilE.warn_none_mode
          ~deps:j
          kinstr
          k
      in
      let new_inputs =
        Zone.join st.over_inputs (Zone.diff deps st.under_outputs) in
      let new_outputs =
        if Locations.valid_cardinal_zero_or_one
          ~for_writing:true
          looking_for
        then
          (* There is only one modified zone. So, this is an exact output.
             Add it into the under-approximed outputs. *)

          Zone.link
            st.under_outputs
            (Locations.valid_enumerate_bits ~for_writing:true looking_for)
        else st.under_outputs
      in
      { over_inputs = new_inputs;
        under_outputs = new_outputs }
    in
    match i with
    | Set (lv, exp, _) ->
        Dataflow.Post
          (fun state ->
             let exp_inputs_deps =
               !From.find_deps_no_transitivity stmt exp
             in
             add_with_additional_var
               lv
               exp_inputs_deps
               state)
    | Call (lvaloption,funcexp,argl,_) ->
        Dataflow.Post
          (fun state ->
             let funcexp_inputs, called_vinfos =
               resolv_func_vinfo
                 ~with_alarms:CilE.warn_none_mode
                 ~deps:Zone.bottom
                 kinstr
                 funcexp
             in
             let acc_funcexp_arg_inputs =
               (* add the inputs of [argl] to the inputs of the
                  function expression *)

               List.fold_right
                 (fun arg inputs ->
                    let arg_inputs = !From.find_deps_no_transitivity stmt arg
                    in Zone.join inputs arg_inputs)
                 argl
                 funcexp_inputs
             in
             let state =
               catenate
                 state
                 { over_inputs = acc_funcexp_arg_inputs ;
                   under_outputs = Zone.bottom;}
             in
             let for_functions =
               Kernel_function.Hptset.fold
                 (fun called_vinfo acc  ->
                   let { Inout_type.over_inputs_if_termination = called_inputs_term;
                         under_outputs_if_termination = called_outputs ;
                         over_inputs = called_inputs} =
                     !Db.Operational_inputs.get_external called_vinfo
                   in
                   non_terminating_callees_inputs :=
                     Zone.join
                       !non_terminating_callees_inputs
                       (Zone.diff called_inputs state.under_outputs);
                   let for_function =
                     { over_inputs = called_inputs_term;
                       under_outputs = called_outputs }
                   in
                   join for_function acc)
                 called_vinfos
                 bottom
             in
(*           Format.printf "functions: %a@." pretty for_functions; *)
             let result = catenate state for_functions in
             let result =
               (* Treatment for the possible assignment of the call result *)
               (match lvaloption with
                | None -> result
                | Some lv ->
                    add_with_additional_var
                      lv
                      Zone.bottom
                      result)
             in result
          )
    | _ -> Dataflow.Default