diff --git a/src/kernel_services/abstract_interp/ival.ml b/src/kernel_services/abstract_interp/ival.ml
index c6aed4e7b02d279a199745b85bc87a71f96c9905..391bc645b63dc7bf3392a403e1226347821f9544 100644
--- a/src/kernel_services/abstract_interp/ival.ml
+++ b/src/kernel_services/abstract_interp/ival.ml
@@ -795,7 +795,7 @@ let array_filter (f : Int.t -> bool) (a : Int.t array) : t =
   let l = Array.length a in
   let r = Array.make l Int.zero in
   let j = ref 0 in
-  for i = 0 to Array.length a  - 1 do
+  for i = 0 to l  - 1 do
     let x = a.(i) in
     if f x then begin
       r.(!j) <- x;
@@ -2574,7 +2574,7 @@ exception NoBackward
 
 module type BitOperator =
 sig
-  (** Printable version of the operator *)
+  (* Printable version of the operator *)
   val representation : string
   (* forward is given here as the lifted function of some bit operator op
      where op
@@ -2586,12 +2586,11 @@ sig
         we don't know unless one of the operands is negative;
      3. is not constant, otherwise nothing of all of this makes sense.
      forward is defined as
-     forward b1 b2 = { x1 op x2 | x1 \in b1, x2 \in b2 }
-  *)
+     forward b1 b2 = { x1 op x2 | x1 \in b1, x2 \in b2 } *)
   val forward : bit_value -> bit_value -> bit_value
-  (** backward_off b = { x | \exist y \in b . x op y = y op x = 1 } *)
+  (* backward_off b = { x | \exist y \in b . x op y = y op x = 1 } *)
   val backward_off : bit_value -> bit_value
-  (** backward_on b = { x | \exist y \in b . x op y = y op x = 0 } *)
+  (* backward_on b = { x | \exist y \in b . x op y = y op x = 0 } *)
   val backward_on : bit_value -> bit_value
 end
 
@@ -2651,34 +2650,10 @@ end
 
 (* --- Bit extraction and mutation --- *)
 
-module Int =
-struct
-  include Integer
-
-  let significant_bits (i : t) : int =
-    (* shift right until nothing changes *)
-    let rec count i acc =
-      let new_i = shift_right i one in
-      if equal i new_i
-      then acc
-      else count new_i (acc + 1)
-    in
-    count i 0
-
-  let biggest_power_of_two_divider (i : t) : int =
-    let rec aux p acc =
-      if equal (logand i p) zero
-      then aux (shift_left p one) (acc + 1)
-      else acc
-    in
-    aux Int.one 0
-end
-
 let significant_bits (v : t) : int option =
   match min_and_max v with
   | None, _ | _, None -> None
-  | Some l, Some u ->
-    Some (max (Int.significant_bits l) (Int.significant_bits u))
+  | Some l, Some u -> Some (max (Z.numbits l) (Z.numbits u))
 
 let extract_sign (v : t) : bit_value =
   match min_and_max v with
@@ -2687,18 +2662,14 @@ let extract_sign (v : t) : bit_value =
   | _, _ -> Both
 
 let extract_bit (v : t) (i : int) : bit_value =
-  let power = Int.(two_power_of_int i) in
-  let bit_value x =
-    if Int.(is_zero (logand power x)) then Off else On
-  in
+  let bit_value x = if Z.testbit x i then On else Off in
   match v with
   | Float _ -> Both
-  | Set s ->
-    array_map_reduce bit_value Bit.union s
+  | Set s -> array_map_reduce bit_value Bit.union s
   | Top (None, _, _r, _m) | Top (_, None, _r, _m) -> Both
   | Top (Some l, Some u, _r, _m) ->
     (* It does not take modulo into account *)
-    if Int.(ge (sub u power)) l (* u - l >= mask *)
+    if Int.(ge (sub u l) (two_power_of_int i)) (* u - l >= mask *)
     then Both
     else Bit.union (bit_value l) (bit_value u)
 
@@ -2725,24 +2696,21 @@ let reduce_sign (v : t) (b : bit_value) : t =
     end
 
 let reduce_bit (v : t) (i : int) (b : bit_value) : t =
-  let power = Int.(two_power_of_int i) in (* 001000 *)
-  let mask = Int.(pred (two_power_of_int (i+1))) in (* 001111 *)
-  let bit_value (x : Int.t) =
-    if Int.(is_zero (logand power x)) then Off else On
-  in
+  let bit_value x = if Z.testbit x i then On else Off in
   if b = Both
   then v
   else match v with
     | Float _ -> v
-    | Set s ->
-      array_filter (fun x -> bit_value x = b) s
+    | Set s -> array_filter (fun x -> bit_value x = b) s
     | Top (l, u, r, modu) ->
+      let power = Int.(two_power_of_int i) in (* 001000 *)
+      let mask = Int.(pred (two_power_of_int (i+1))) in (* 001111 *)
       (* Reduce bounds to the nearest satisfying bound *)
       let l' = match l with
         | Some l when bit_value l <> b ->
           let min = match b with
             | On ->  Int.(logor (logand l (lognot mask)) power) (* ll1000 *)
-            | Off -> Int.(succ (logor l mask)) (* ll0000 *)
+            | Off -> Int.(succ (logor l mask)) (* ll1111 + 1 *)
             | Both -> assert false
           in
           Some (Int.round_up_to_r ~min ~r ~modu)
@@ -2750,8 +2718,8 @@ let reduce_bit (v : t) (i : int) (b : bit_value) : t =
       and u' = match u with
         | Some u when bit_value u <> b ->
           let max = match b with
-            | On ->  Int.(pred (logand u (lognot mask))) (* ll1111 *)
-            | Off -> Int.(logand (logor u mask) (lognot power)) (* ll0111 *)
+            | On ->  Int.(pred (logand u (lognot mask))) (* uu0000 - 1 *)
+            | Off -> Int.(logand (logor u mask) (lognot power)) (* uu0111 *)
             | Both -> assert false
           in
           Some (Int.round_down_to_r ~max ~r ~modu)
@@ -2768,14 +2736,8 @@ let reduce_bit (v : t) (i : int) (b : bit_value) : t =
 type bit_mask = bit_value array * bit_value
 
 let int_to_bit_array n (x : Int.t) =
-  let a = Array.make n On in
-  let p = ref Int.one in
-  for i = 0 to n-1 do
-    if Int.(equal (logand x !p) zero) then
-      a.(i) <- Off;
-    p := Int.(shift_left !p one)
-  done;
-  a
+  let make i = if Z.testbit x i then On else Off in
+  Array.init n make
 
 (** Compute a mask only precise for low bits, overapproximating the high ones.
     More precisely, bit values are computed until an uncertainty appears
@@ -2784,27 +2746,23 @@ let low_bit_mask (v : t) =
   match v with
   | Set [| |] -> raise Error_Bottom
   | Set [| x |] -> (* singleton : build a full mask  *)
-    let n = Int.significant_bits x in
+    let n = Z.numbits x in
     int_to_bit_array n x, if Int.(ge x zero) then Off else On
   | _ ->
     let _,_,r,modu = min_max_r_mod v in (* requires cardinal > 1 *)
     (* Find how much modu can be divided by two *)
-    let n = Int.biggest_power_of_two_divider modu in
-    (* Recompute rest *)
-    let r = Int.(logand (sub (two_power_of_int n) one) r) in
+    let n = Z.trailing_zeros modu in
     int_to_bit_array n r, Both
 
 let combine_masks (op : bit_value -> bit_value -> bit_value)
     (b1,s1 : bit_mask) (b2,s2 : bit_mask) : bit_mask =
   let n = max (Array.length b1) (Array.length b2) in
-  let r = Array.make n Both in
-  for i = 0 to n-1 do
+  let make i =
     let b1 = try b1.(i) with _ -> s1
-    and b2 = try b2.(i) with _ -> s2
-    in
-    r.(i) <- op b1 b2
-  done;
-  r, op s1 s2
+    and b2 = try b2.(i) with _ -> s2 in
+    op b1 b2
+  in
+  Array.init n make, op s1 s2
 
 let mask_to_r_modu (b,_s : bit_mask) : Int.t * Int.t =
   let n = Array.length b in