diff --git a/src/runner.c b/src/runner.c
index c1bbbf110c622ac4efdc229d3fee233b25f2d187..392bb261bf156441a6baafa8e795c59405eb0082 100644
--- a/src/runner.c
+++ b/src/runner.c
@@ -1857,24 +1857,15 @@ void *runner_main(void *data) {
       /* Different types of tasks... */
       switch (t->type) {
         case task_type_self:
-          if (t->subtype == task_subtype_density) {
-#if defined(WITH_VECTORIZATION) && defined(GADGET2_SPH)
-            runner_doself1_density_vec(r, ci);
-#else
-            runner_doself1_density(r, ci);
-#endif
-          }
+          if (t->subtype == task_subtype_density)
+            runner_doself1_branch_density(r, ci);
 #ifdef EXTRA_HYDRO_LOOP
           else if (t->subtype == task_subtype_gradient)
             runner_doself1_gradient(r, ci);
 #endif
-          else if (t->subtype == task_subtype_force) {
-#if defined(WITH_VECTORIZATION) && defined(GADGET2_SPH)
-            runner_doself2_force_vec(r, ci);
-#else
-            runner_doself2_force(r, ci);
-#endif
-          } else if (t->subtype == task_subtype_grav)
+          else if (t->subtype == task_subtype_force)
+            runner_doself2_branch_force(r, ci);
+          else if (t->subtype == task_subtype_grav)
             runner_doself_grav(r, ci, 1);
           else if (t->subtype == task_subtype_external_grav)
             runner_do_grav_external(r, ci, 1);
diff --git a/src/runner_doiact.h b/src/runner_doiact.h
index 4452cf08012cab63354bed02c2323ba03019cdec..b49e497ad3bdccabbdb2e213eb4a295ce2bdd2c5 100644
--- a/src/runner_doiact.h
+++ b/src/runner_doiact.h
@@ -59,9 +59,15 @@
 #define _DOSELF2_NAIVE(f) PASTE(runner_doself2_naive, f)
 #define DOSELF2_NAIVE _DOSELF2_NAIVE(FUNCTION)
 
+#define _DOSELF1_BRANCH(f) PASTE(runner_doself1_branch, f)
+#define DOSELF1_BRANCH _DOSELF1_BRANCH(FUNCTION)
+
 #define _DOSELF1(f) PASTE(runner_doself1, f)
 #define DOSELF1 _DOSELF1(FUNCTION)
 
+#define _DOSELF2_BRANCH(f) PASTE(runner_doself2_branch, f)
+#define DOSELF2_BRANCH _DOSELF2_BRANCH(FUNCTION)
+
 #define _DOSELF2(f) PASTE(runner_doself2, f)
 #define DOSELF2 _DOSELF2(FUNCTION)
 
@@ -1370,7 +1376,7 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
 
         /* Hit or miss?
            (note that we must avoid the r2 < hig2 cases we already processed) */
-        if (r2 < hjg2 && r2 > hig2) {
+        if (r2 < hjg2 && r2 >= hig2) {
           IACT_NONSYM(r2, dx, hi, hj, pi, pj);
         }
       } /* loop over the active parts in ci. */
@@ -1432,7 +1438,7 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj, const int sid,
 
         /* Hit or miss?
            (note that we must avoid the r2 < hig2 cases we already processed) */
-        if (r2 < hjg2 && r2 > hig2) {
+        if (r2 < hjg2 && r2 >= hig2) {
 
           /* Does pi need to be updated too? */
           if (part_is_active(pi, e))
@@ -1541,17 +1547,8 @@ void DOSELF1(struct runner *r, struct cell *restrict c) {
 
   const struct engine *e = r->e;
 
-#ifdef SWIFT_USE_NAIVE_INTERACTIONS
-  DOSELF1_NAIVE(r, c);
-  return;
-#endif
-
   TIMER_TIC;
 
-  if (!cell_is_active(c, e)) return;
-
-  if (!cell_are_part_drifted(c, e)) error("Interacting undrifted cell.");
-
   struct part *restrict parts = c->parts;
   const int count = c->count;
 
@@ -1668,6 +1665,33 @@ void DOSELF1(struct runner *r, struct cell *restrict c) {
   TIMER_TOC(TIMER_DOSELF);
 }
 
+/**
+ * @brief Determine which version of DOSELF1 needs to be called depending on the
+ * optimisation level.
+ *
+ * @param r #runner
+ * @param c #cell c
+ *
+ */
+void DOSELF1_BRANCH(struct runner *r, struct cell *c) {
+
+  const struct engine *restrict e = r->e;
+
+  /* Anything to do here? */
+  if (!cell_is_active(c, e)) return;
+
+  /* Check that cells are drifted. */
+  if (!cell_are_part_drifted(c, e)) error("Interacting undrifted cell.");
+
+#if defined(SWIFT_USE_NAIVE_INTERACTIONS)
+  DOSELF1_NAIVE(r, c);
+#elif defined(WITH_VECTORIZATION) && defined(GADGET2_SPH)
+  runner_doself1_density_vec(r, c);
+#else
+  DOSELF1(r, c);
+#endif
+}
+
 /**
  * @brief Compute the cell self-interaction (symmetric).
  *
@@ -1678,16 +1702,8 @@ void DOSELF2(struct runner *r, struct cell *restrict c) {
 
   const struct engine *e = r->e;
 
-#ifdef SWIFT_USE_NAIVE_INTERACTIONS
-  DOSELF2_NAIVE(r, c);
-  return;
-#endif
-
   TIMER_TIC;
 
-  if (!cell_is_active(c, e)) return;
-  if (!cell_are_part_drifted(c, e)) error("Cell is not drifted");
-
   struct part *restrict parts = c->parts;
   const int count = c->count;
 
@@ -1796,6 +1812,33 @@ void DOSELF2(struct runner *r, struct cell *restrict c) {
   TIMER_TOC(TIMER_DOSELF);
 }
 
+/**
+ * @brief Determine which version of DOSELF2 needs to be called depending on the
+ * optimisation level.
+ *
+ * @param r #runner
+ * @param c #cell c
+ *
+ */
+void DOSELF2_BRANCH(struct runner *r, struct cell *c) {
+
+  const struct engine *restrict e = r->e;
+
+  /* Anything to do here? */
+  if (!cell_is_active(c, e)) return;
+
+  /* Check that cells are drifted. */
+  if (!cell_are_part_drifted(c, e)) error("Interacting undrifted cell.");
+
+#if defined(SWIFT_USE_NAIVE_INTERACTIONS)
+  DOSELF2_NAIVE(r, c);
+#elif defined(WITH_VECTORIZATION) && defined(GADGET2_SPH)
+  runner_doself2_force_vec(r, c);
+#else
+  DOSELF2(r, c);
+#endif
+}
+
 /**
  * @brief Compute grouped sub-cell interactions for pairs
  *
@@ -2080,12 +2123,7 @@ void DOSUB_SELF1(struct runner *r, struct cell *ci, int gettimer) {
     /* Drift the cell to the current timestep if needed. */
     if (!cell_are_part_drifted(ci, r->e)) error("Interacting undrifted cell.");
 
-#if (DOSELF1 == runner_doself1_density) && defined(WITH_VECTORIZATION) && \
-    defined(GADGET2_SPH)
-    runner_doself1_density_vec(r, ci);
-#else
-    DOSELF1(r, ci);
-#endif
+    DOSELF1_BRANCH(r, ci);
   }
 
   if (gettimer) TIMER_TOC(TIMER_DOSUB_SELF);
@@ -2372,12 +2410,7 @@ void DOSUB_SELF2(struct runner *r, struct cell *ci, int gettimer) {
 
   /* Otherwise, compute self-interaction. */
   else {
-#if (DOSELF2 == runner_doself2_force) && defined(WITH_VECTORIZATION) && \
-    defined(GADGET2_SPH)
-    runner_doself2_force_vec(r, ci);
-#else
-    DOSELF2(r, ci);
-#endif
+    DOSELF2_BRANCH(r, ci);
   }
   if (gettimer) TIMER_TOC(TIMER_DOSUB_SELF);
 }