Reland 2nd attempt:  [lld-macho] Fix bug in reading cpuSubType field.

This reverts commit 52a118d08fbb0a45cba8c34346d9ccb14f599c6a.

New changes:
Fix tests to dump both slices in the fat-archive because otool
isn't deterministic about which slice it prints across different archs.
(It printed x86 on x86 machines but arm64 on arm64, this was why
the test failed on arm64)

Differential Revision: https://reviews.llvm.org/D139572
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index 54a02f2..174ad95 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -231,8 +231,14 @@
       return std::nullopt;
     }
 
-    if (read32be(&arch[i].cputype) != static_cast<uint32_t>(target->cpuType) ||
-        read32be(&arch[i].cpusubtype) != target->cpuSubtype)
+    uint32_t cpuType = read32be(&arch[i].cputype);
+    uint32_t cpuSubtype =
+        read32be(&arch[i].cpusubtype) & ~MachO::CPU_SUBTYPE_MASK;
+
+    // FIXME: LD64 has a more complex fallback logic here.
+    // Consider implementing that as well?
+    if (cpuType != static_cast<uint32_t>(target->cpuType) ||
+        cpuSubtype != target->cpuSubtype)
       continue;
 
     uint32_t offset = read32be(&arch[i].offset);
diff --git a/lld/test/MachO/fat-arch.s b/lld/test/MachO/fat-arch.s
index 33928b1..313b115 100644
--- a/lld/test/MachO/fat-arch.s
+++ b/lld/test/MachO/fat-arch.s
@@ -1,16 +1,38 @@
-# REQUIRES: x86
+# REQUIRES: x86,aarch64
+## FIXME: The tests doesn't run on windows right now because of llvm-mc (can't produce triple=arm64-apple-macos11.0)
+# UNSUPPORTED: system-windows
+
 # RUN: llvm-mc -filetype=obj -triple=i386-apple-darwin %s -o %t.i386.o
 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.x86_64.o
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-macos11.0 %s -o %t.arm64.o
+
 # RUN: llvm-lipo %t.i386.o %t.x86_64.o -create -o %t.fat.o
 # RUN: %lld -o /dev/null %t.fat.o
-
 # RUN: llvm-lipo %t.i386.o -create -o %t.noarch.o
 # RUN: not %lld -o /dev/null %t.noarch.o 2>&1 | \
 # RUN:    FileCheck %s -DFILE=%t.noarch.o
 # CHECK: error: unable to find matching architecture in [[FILE]]
 
+## Validates that we read the cpu-subtype correctly from a fat exec.
+# RUN: %lld -o %t.x86_64.out %t.x86_64.o
+# RUN: %lld -arch arm64 -o %t.arm64.out %t.arm64.o
+# RUN: llvm-lipo %t.x86_64.out %t.arm64.out -create -o %t.fat.exec.out
+# RUN: %lld %t.x86_64.o -bundle_loader %t.fat.exec.out -bundle -o %t.fat.bundle
+
+# RUN: llvm-otool -h %t.fat.bundle -f %t.fat.exec.out | FileCheck %s --check-prefix=CPU-SUB
+# CPU-SUB: Fat headers
+# CPU-SUB: nfat_arch 2
+# CPU-SUB: architecture 0
+# CPU-SUB-NEXT:    cputype 16777223
+# CPU-SUB-NEXT:    cpusubtype 3
+# CPU-SUB: architecture 1
+# CPU-SUB-NEXT:    cputype 16777228
+# CPU-SUB-NEXT:    cpusubtype 0
+
+# CPU-SUB:            magic     cputype      cpusubtype   caps      filetype   ncmds sizeofcmds      flags
+# CPU-SUB-NEXT:  0xfeedfacf     16777223              3  0x{{.+}}    {{.+}}  {{.+}}    {{.+}}      {{.+}}
+
 .text
 .global _main
 _main:
-  mov $0, %eax
   ret