if (vm_flags & VM_SPECIAL)
                return NULL;
 
-       curr = find_vma(mm, prev ? prev->vm_end : 0);
-       if (curr && curr->vm_end == end)                /* cases 6, 7, 8 */
-               next = find_vma(mm, curr->vm_end);
-       else
-               next = curr;
+       /* Does the input range span an existing VMA? (cases 5 - 8) */
+       curr = find_vma_intersection(mm, prev ? prev->vm_end : 0, end);
 
-       /* In cases 1 - 4 there's no CCCC vma */
-       if (curr && end <= curr->vm_start)
-               curr = NULL;
+       if (!curr ||                    /* cases 1 - 4 */
+           end == curr->vm_end)        /* cases 6 - 8, adjacent VMA */
+               next = vma_lookup(mm, end);
+       else
+               next = NULL;            /* case 5 */
 
        /* verify some invariant that must be enforced by the caller */
        VM_WARN_ON(prev && addr <= prev->vm_start);
                }
        }
        /* Can we merge the successor? */
-       if (next && end == next->vm_start &&
-                       mpol_equal(policy, vma_policy(next)) &&
-                       can_vma_merge_before(next, vm_flags,
-                                            anon_vma, file, pgoff+pglen,
-                                            vm_userfaultfd_ctx, anon_name)) {
+       if (next && mpol_equal(policy, vma_policy(next)) &&
+           can_vma_merge_before(next, vm_flags,
+                                anon_vma, file, pgoff+pglen,
+                                vm_userfaultfd_ctx, anon_name)) {
                merge_next = true;
        }