diff --git a/src/plugins/eva/domains/octagons.ml b/src/plugins/eva/domains/octagons.ml
index 8c0272ba68317a3f6d20c8c3a0eefed3d9e3cda0..af3696fcc78a80854971ad6e1e00d7f8eac53a56 100644
--- a/src/plugins/eva/domains/octagons.ml
+++ b/src/plugins/eva/domains/octagons.ml
@@ -1015,7 +1015,7 @@ module State = struct
     with Not_found -> `Value state
 
   let add_octagon state octagon =
-    if is_redundant state.intervals octagon
+    if Ival.(equal top octagon.value) || is_redundant state.intervals octagon
     then `Value state
     else
       let state =
@@ -1036,6 +1036,11 @@ module State = struct
       let relations = Relations.relate octagon.variables state.relations in
       { state with octagons; relations }
 
+  let add_diamond state variables diamond =
+    add_octagon state { variables; operation = Add; value = diamond.add }
+    >>- fun state ->
+    add_octagon state { variables; operation = Sub; value = diamond.sub }
+
   let remove state x =
     let intervals = Intervals.remove x state.intervals in
     let state = { state with intervals } in
@@ -1381,7 +1386,7 @@ module Domain = struct
       let relations = Relations.filter mem_var state.relations in
       { state with octagons; intervals; relations; }
 
-  let reuse =
+  let interprocedural_reuse =
     let cache = Hptmap_sig.PersistentCache "Octagons.reuse"
     and symmetric = false
     and idempotent = true
@@ -1389,17 +1394,38 @@ module Domain = struct
     let join_oct = Octagons.internal_join ~cache ~symmetric ~idempotent ~decide
     and join_itv = Intervals.internal_join ~cache ~symmetric ~idempotent ~decide
     and join_rel = Relations.union in
-    fun _kf _bases ~current_input ~previous_output ->
-      if intraprocedural ()
-      then previous_output
+    fun ~current_input ~previous_output ->
+      let current_input = kill previous_output.modified current_input in
+      (* We use [add_diamond] to add each relation from the previous output
+         into the current input, in order to benefit from the (partial)
+         saturation of octagons performed by this function. For a maximum
+         precision, a complete saturation would be required.
+         Otherwise, we use instead a more efficient (but less precise) merge
+         of the maps from the previous output and the current input. *)
+      if saturate_octagons
+      then
+        let intervals =
+          join_itv previous_output.intervals current_input.intervals
+        in
+        let state = { current_input with intervals } in
+        let add_diamond variables diamond acc =
+          Bottom.non_bottom (add_diamond acc variables diamond)
+        in
+        Octagons.fold add_diamond previous_output.octagons state
       else
-        let current_input = kill previous_output.modified current_input in
-        let prev_output = previous_output in
-        check "reuse result"
-          { octagons = join_oct prev_output.octagons current_input.octagons;
-            intervals = join_itv prev_output.intervals current_input.intervals;
-            relations = join_rel prev_output.relations current_input.relations;
-            modified = current_input.modified }
+        { octagons = join_oct previous_output.octagons current_input.octagons;
+          intervals = join_itv previous_output.intervals current_input.intervals;
+          relations = join_rel previous_output.relations current_input.relations;
+          modified = current_input.modified }
+
+  let reuse _kf _bases ~current_input ~previous_output =
+    if intraprocedural ()
+    then previous_output
+    else
+      let t = interprocedural_reuse ~current_input ~previous_output in
+      check "reuse result" t
+
+
 
 end