diff --git a/lld/MachO/ConcatOutputSection.cpp b/lld/MachO/ConcatOutputSection.cpp
--- a/lld/MachO/ConcatOutputSection.cpp
+++ b/lld/MachO/ConcatOutputSection.cpp
@@ -241,8 +241,6 @@
     }
     // Process relocs by ascending address, i.e., ascending offset within isec
     std::vector<Reloc> &relocs = isec->relocs;
-    assert(is_sorted(relocs,
-                     [](Reloc &a, Reloc &b) { return a.offset > b.offset; }));
     for (Reloc &r : reverse(relocs)) {
       ++relocCount;
       if (!target->hasAttr(r.type, RelocAttrBits::BRANCH))
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -366,6 +366,7 @@
   ArrayRef<relocation_info> relInfos(
       reinterpret_cast<const relocation_info *>(buf + sec.reloff), sec.nreloc);
 
+  auto subsecIt = subsecMap.rbegin();
   for (size_t i = 0; i < relInfos.size(); i++) {
     // Paired relocations serve as Mach-O's method for attaching a
     // supplemental datum to a primary relocation record. ELF does not
@@ -442,7 +443,19 @@
       r.addend = referentOffset;
     }
 
-    InputSection *subsec = findContainingSubsection(subsecMap, &r.offset);
+    // Find the subsection that this relocation belongs to.
+    // Though not required by the Mach-O format, clang and gcc seem to emit
+    // relocations in order, so let's take advantage of it.
+    while (subsecIt != subsecMap.rend() && subsecIt->offset > r.offset)
+      ++subsecIt;
+    if (subsecIt == subsecMap.rend() ||
+        subsecIt->offset + subsecIt->isec->getSize() <= r.offset) {
+      error(toString(this) +
+            ": relocations not sorted in reverse order of address");
+      break;
+    }
+    InputSection *subsec = subsecIt->isec;
+    r.offset -= subsecIt->offset;
     subsec->relocs.push_back(r);
 
     if (isSubtrahend) {
diff --git a/lld/test/MachO/invalid/unsorted-relocations.yaml b/lld/test/MachO/invalid/unsorted-relocations.yaml
new file mode 100644
--- /dev/null
+++ b/lld/test/MachO/invalid/unsorted-relocations.yaml
@@ -0,0 +1,96 @@
+# RUN: yaml2obj %s -o %t.o
+# RUN: not %lld -dylib -o %t %t.o 2>&1 | FileCheck %s -DFILE=%t.o
+#
+# CHECK:       error: [[FILE]]: relocations not sorted in reverse order of address
+# CHECk-EMPTY:
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x1000007
+  cpusubtype:      0x3
+  filetype:        0x1
+  ncmds:           2
+  sizeofcmds:      280
+  flags:           0x2000
+  reserved:        0x0
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         152
+    segname:         ''
+    vmaddr:          0
+    vmsize:          24
+    fileoff:         312
+    filesize:        24
+    maxprot:         7
+    initprot:        7
+    nsects:          1
+    flags:           0
+    Sections:
+      - sectname:        __data
+        segname:         __DATA
+        addr:            0x0
+        size:            24
+        offset:          0x138
+        align:           0
+        reloff:          0x150
+        nreloc:          3
+        flags:           0x80000000
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         '000000000000000000000000000000000000000000000000'
+        relocations:
+          - address:         0x0
+            symbolnum:       1
+            pcrel:           false
+            length:          3
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+          - address:         0x10
+            symbolnum:       0
+            pcrel:           false
+            length:          3
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+          - address:         0x8
+            symbolnum:       2
+            pcrel:           false
+            length:          3
+            extern:          true
+            type:            0
+            scattered:       false
+            value:           0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          360
+    nsyms:           3
+    stroff:          408
+    strsize:         16
+LinkEditData:
+  NameList:
+    - n_strx:          11
+      n_type:          0xE
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+    - n_strx:          1
+      n_type:          0xE
+      n_sect:          1
+      n_desc:          0
+      n_value:         16
+    - n_strx:          6
+      n_type:          0xE
+      n_sect:          1
+      n_desc:          0
+      n_value:         8
+  StringTable:
+    - ''
+    - _baz
+    - _bar
+    - _foo
+...