diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -1128,6 +1128,79 @@ return Sym; } +static VersionTuple +targetVersionOrMinimumSupportedOSVersion(const Triple &Target, + VersionTuple TargetVersion) { + VersionTuple Min = Target.getMinimumSupportedOSVersion(); + return !Min.empty() && Min > TargetVersion ? Min : TargetVersion; +} + +static MCVersionMinType +getMachoVersionMinLoadCommandType(const Triple &Target) { + assert(Target.isOSDarwin() && "expected a darwin OS"); + switch (Target.getOS()) { + case Triple::MacOSX: + case Triple::Darwin: + return MCVM_OSXVersionMin; + case Triple::IOS: + assert(!Target.isMacCatalystEnvironment() && + "mac Catalyst should use LC_BUILD_VERSION"); + return MCVM_IOSVersionMin; + case Triple::TvOS: + return MCVM_TvOSVersionMin; + case Triple::WatchOS: + return MCVM_WatchOSVersionMin; + default: + break; + } + llvm_unreachable("unexpected OS type"); +} + +static VersionTuple getMachoBuildVersionSupportedOS(const Triple &Target) { + assert(Target.isOSDarwin() && "expected a darwin OS"); + switch (Target.getOS()) { + case Triple::MacOSX: + case Triple::Darwin: + return VersionTuple(10, 14); + case Triple::IOS: + // Mac Catalyst always uses the build version load command. + if (Target.isMacCatalystEnvironment()) + return VersionTuple(); + LLVM_FALLTHROUGH; + case Triple::TvOS: + return VersionTuple(12); + case Triple::WatchOS: + return VersionTuple(5); + default: + break; + } + llvm_unreachable("unexpected OS type"); +} + +static MachO::PlatformType +getMachoBuildVersionPlatformType(const Triple &Target) { + assert(Target.isOSDarwin() && "expected a darwin OS"); + switch (Target.getOS()) { + case Triple::MacOSX: + case Triple::Darwin: + return MachO::PLATFORM_MACOS; + case Triple::IOS: + if (Target.isMacCatalystEnvironment()) + return MachO::PLATFORM_MACCATALYST; + return Target.isSimulatorEnvironment() ? MachO::PLATFORM_IOSSIMULATOR + : MachO::PLATFORM_IOS; + case Triple::TvOS: + return Target.isSimulatorEnvironment() ? MachO::PLATFORM_TVOSSIMULATOR + : MachO::PLATFORM_TVOS; + case Triple::WatchOS: + return Target.isSimulatorEnvironment() ? MachO::PLATFORM_WATCHOSSIMULATOR + : MachO::PLATFORM_WATCHOS; + default: + break; + } + llvm_unreachable("unexpected OS type"); +} + void MCStreamer::emitVersionForTarget(const Triple &Target, const VersionTuple &SDKVersion) { if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin()) @@ -1136,33 +1209,37 @@ if (Target.getOSMajorVersion() == 0) return; - unsigned Major; - unsigned Minor; - unsigned Update; - if (Target.isMacCatalystEnvironment()) { - // Mac Catalyst always uses the build version load command. + unsigned Major = 0; + unsigned Minor = 0; + unsigned Update = 0; + switch (Target.getOS()) { + case Triple::MacOSX: + case Triple::Darwin: + Target.getMacOSXVersion(Major, Minor, Update); + break; + case Triple::IOS: + case Triple::TvOS: Target.getiOSVersion(Major, Minor, Update); - assert(Major && "A non-zero major version is expected"); - emitBuildVersion(MachO::PLATFORM_MACCATALYST, Major, Minor, Update, - SDKVersion); - return; - } - - MCVersionMinType VersionType; - if (Target.isWatchOS()) { - VersionType = MCVM_WatchOSVersionMin; + break; + case Triple::WatchOS: Target.getWatchOSVersion(Major, Minor, Update); - } else if (Target.isTvOS()) { - VersionType = MCVM_TvOSVersionMin; - Target.getiOSVersion(Major, Minor, Update); - } else if (Target.isMacOSX()) { - VersionType = MCVM_OSXVersionMin; - if (!Target.getMacOSXVersion(Major, Minor, Update)) - Major = 0; - } else { - VersionType = MCVM_IOSVersionMin; - Target.getiOSVersion(Major, Minor, Update); + break; + default: + llvm_unreachable("unexpected OS type"); } - if (Major != 0) - emitVersionMin(VersionType, Major, Minor, Update, SDKVersion); + assert(Major != 0 && "A non-zero major version is expected"); + auto LinkedTargetVersion = targetVersionOrMinimumSupportedOSVersion( + Target, VersionTuple(Major, Minor, Update)); + auto BuildVersionOSVersion = getMachoBuildVersionSupportedOS(Target); + if (BuildVersionOSVersion.empty() || + LinkedTargetVersion >= BuildVersionOSVersion) + return emitBuildVersion(getMachoBuildVersionPlatformType(Target), + LinkedTargetVersion.getMajor(), + *LinkedTargetVersion.getMinor(), + *LinkedTargetVersion.getSubminor(), SDKVersion); + + emitVersionMin(getMachoVersionMinLoadCommandType(Target), + LinkedTargetVersion.getMajor(), + *LinkedTargetVersion.getMinor(), + *LinkedTargetVersion.getSubminor(), SDKVersion); } diff --git a/llvm/lib/Support/Triple.cpp b/llvm/lib/Support/Triple.cpp --- a/llvm/lib/Support/Triple.cpp +++ b/llvm/lib/Support/Triple.cpp @@ -1627,11 +1627,29 @@ VersionTuple Triple::getMinimumSupportedOSVersion() const { if (getVendor() != Triple::Apple || getArch() != Triple::aarch64) return VersionTuple(); - /// ARM64 slice is supported starting from macOS 11.0+. - if (getOS() == Triple::MacOSX) + switch (getOS()) { + case Triple::MacOSX: + // ARM64 slice is supported starting from macOS 11.0+. return VersionTuple(11, 0, 0); - if (getOS() == Triple::IOS && isMacCatalystEnvironment()) - return VersionTuple(14, 0, 0); + case Triple::IOS: + // ARM64 slice is supported starting from Mac Catalyst 14 (macOS 11). + // ARM64 simulators are supported for iOS 14+. + if (isMacCatalystEnvironment() || isSimulatorEnvironment()) + return VersionTuple(14, 0, 0); + break; + case Triple::TvOS: + // ARM64 simulators are supported for tvOS 14+. + if (isSimulatorEnvironment()) + return VersionTuple(14, 0, 0); + break; + case Triple::WatchOS: + // ARM64 simulators are supported for watchOS 7+. + if (isSimulatorEnvironment()) + return VersionTuple(7, 0, 0); + break; + default: + break; + } return VersionTuple(); } diff --git a/llvm/test/MC/MachO/darwin-sdk-version.ll b/llvm/test/MC/MachO/darwin-sdk-version.ll --- a/llvm/test/MC/MachO/darwin-sdk-version.ll +++ b/llvm/test/MC/MachO/darwin-sdk-version.ll @@ -1,7 +1,7 @@ ; RUN: llc %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s ; RUN: llc %s -filetype=asm -o - | FileCheck --check-prefix=ASM %s -target triple = "x86_64-apple-macos10.14"; +target triple = "x86_64-apple-macos10.13"; !llvm.module.flags = !{!0}; !0 = !{i32 2, !"SDK Version", [3 x i32] [ i32 10, i32 14, i32 2 ] }; @@ -12,7 +12,7 @@ ; CHECK: cmd LC_VERSION_MIN_MACOSX ; CHECK-NEXT: cmdsize 16 -; CHECK-NEXT: version 10.14 +; CHECK-NEXT: version 10.13 ; CHECK-NEXT: sdk 10.14.2 -; ASM: .macosx_version_min 10, 14 sdk_version 10, 14, 2 +; ASM: .macosx_version_min 10, 13 sdk_version 10, 14, 2 diff --git a/llvm/test/MC/MachO/darwin-version-min-load-command.s b/llvm/test/MC/MachO/darwin-version-min-load-command.s --- a/llvm/test/MC/MachO/darwin-version-min-load-command.s +++ b/llvm/test/MC/MachO/darwin-version-min-load-command.s @@ -3,6 +3,28 @@ // RUN: llvm-mc -triple x86_64-apple-darwin %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-DARWIN // RUN: llvm-mc -triple x86_64-apple-ios13.0-macabi %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-MACCATALYST +// RUN: llvm-mc -triple x86_64-apple-macos10.14 %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-MACOS +// RUN: llvm-mc -triple x86_64-apple-ios12 %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-IOS +// RUN: llvm-mc -triple x86_64-apple-tvos12 %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-TVOS +// RUN: llvm-mc -triple x86_64-apple-watchos5 %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-WATCHOS +// RUN: llvm-mc -triple x86_64-apple-ios12-simulator %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-IOSSIM +// RUN: llvm-mc -triple x86_64-apple-tvos12-simulator %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-TVOSSIM +// RUN: llvm-mc -triple x86_64-apple-watchos5-simulator %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-WATCHOSSIM + +// RUN: llvm-mc -triple arm64-apple-macos10.10.2 %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-MACOS-ARM64 +// RUN: llvm-mc -triple arm64-apple-macos11 %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-MACOS-ARM64 +// RUN: llvm-mc -triple arm64-apple-macos11.1 %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-MACOS-ARM64_1 +// RUN: llvm-mc -triple arm64-apple-ios13.0-macabi %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-MACCATALYST-ARM64 +// RUN: llvm-mc -triple arm64-apple-ios14.1-macabi %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-MACCATALYST-ARM64_1 + +// RUN: llvm-mc -triple arm64-apple-ios10-simulator %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-IOSSIM2 +// RUN: llvm-mc -triple arm64-apple-ios13-simulator %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-IOSSIM2 +// RUN: llvm-mc -triple arm64-apple-ios14-simulator %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-IOSSIM2 +// RUN: llvm-mc -triple arm64-apple-ios14.1-simulator %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-IOSSIM3 +// RUN: llvm-mc -triple arm64-apple-tvos10-simulator %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-TVOSSIM2 +// RUN: llvm-mc -triple arm64-apple-watchos3-simulator %s -filetype=obj -o - | llvm-objdump --macho --private-headers - | FileCheck %s --check-prefix=CHECK-BUILD-WATCHOSSIM2 + + // Test version-min load command should be inferred from triple and should always be generated on Darwin // CHECK: Load command // CHECK: cmd LC_VERSION_MIN_MACOSX @@ -41,3 +63,120 @@ // CHECK-MACCATALYST-NEXT: sdk n/a // CHECK-MACCATALYST-NEXT: minos 13.0 // CHECK-MACCATALYST-NEXT: ntools 0 + +// CHECK-BUILD-MACOS: cmd LC_BUILD_VERSION +// CHECK-BUILD-MACOS-NEXT: cmdsize 24 +// CHECK-BUILD-MACOS-NEXT: platform macos +// CHECK-BUILD-MACOS-NEXT: sdk n/a +// CHECK-BUILD-MACOS-NEXT: minos 10.14 +// CHECK-BUILD-MACOS-NEXT: ntools 0 +// CHECK-BUILD-MACOS-NOT: LC_VERSION_MIN + +// CHECK-BUILD-IOS: cmd LC_BUILD_VERSION +// CHECK-BUILD-IOS-NEXT: cmdsize 24 +// CHECK-BUILD-IOS-NEXT: platform ios +// CHECK-BUILD-IOS-NEXT: sdk n/a +// CHECK-BUILD-IOS-NEXT: minos 12.0 +// CHECK-BUILD-IOS-NEXT: ntools 0 +// CHECK-BUILD-IOS-NOT: LC_VERSION_MIN + +// CHECK-BUILD-TVOS: cmd LC_BUILD_VERSION +// CHECK-BUILD-TVOS-NEXT: cmdsize 24 +// CHECK-BUILD-TVOS-NEXT: platform tvos +// CHECK-BUILD-TVOS-NEXT: sdk n/a +// CHECK-BUILD-TVOS-NEXT: minos 12.0 +// CHECK-BUILD-TVOS-NEXT: ntools 0 +// CHECK-BUILD-TVOS-NOT: LC_VERSION_MIN + +// CHECK-BUILD-WATCHOS: cmd LC_BUILD_VERSION +// CHECK-BUILD-WATCHOS-NEXT: cmdsize 24 +// CHECK-BUILD-WATCHOS-NEXT: platform watchos +// CHECK-BUILD-WATCHOS-NEXT: sdk n/a +// CHECK-BUILD-WATCHOS-NEXT: minos 5.0 +// CHECK-BUILD-WATCHOS-NEXT: ntools 0 +// CHECK-BUILD-WATCHOS-NOT: LC_VERSION_MIN + +// CHECK-BUILD-IOSSIM: cmd LC_BUILD_VERSION +// CHECK-BUILD-IOSSIM-NEXT: cmdsize 24 +// CHECK-BUILD-IOSSIM-NEXT: platform iossim +// CHECK-BUILD-IOSSIM-NEXT: sdk n/a +// CHECK-BUILD-IOSSIM-NEXT: minos 12.0 +// CHECK-BUILD-IOSSIM-NEXT: ntools 0 +// CHECK-BUILD-IOSSIM-NOT: LC_VERSION_MIN + +// CHECK-BUILD-IOSSIM2: cmd LC_BUILD_VERSION +// CHECK-BUILD-IOSSIM2-NEXT: cmdsize 24 +// CHECK-BUILD-IOSSIM2-NEXT: platform iossim +// CHECK-BUILD-IOSSIM2-NEXT: sdk n/a +// CHECK-BUILD-IOSSIM2-NEXT: minos 14.0 +// CHECK-BUILD-IOSSIM2-NEXT: ntools 0 +// CHECK-BUILD-IOSSIM2-NOT: LC_VERSION_MIN + +// CHECK-BUILD-IOSSIM3: cmd LC_BUILD_VERSION +// CHECK-BUILD-IOSSIM3-NEXT: cmdsize 24 +// CHECK-BUILD-IOSSIM3-NEXT: platform iossim +// CHECK-BUILD-IOSSIM3-NEXT: sdk n/a +// CHECK-BUILD-IOSSIM3-NEXT: minos 14.1 +// CHECK-BUILD-IOSSIM3-NEXT: ntools 0 +// CHECK-BUILD-IOSSIM3-NOT: LC_VERSION_MIN + +// CHECK-BUILD-TVOSSIM: cmd LC_BUILD_VERSION +// CHECK-BUILD-TVOSSIM-NEXT: cmdsize 24 +// CHECK-BUILD-TVOSSIM-NEXT: platform tvossim +// CHECK-BUILD-TVOSSIM-NEXT: sdk n/a +// CHECK-BUILD-TVOSSIM-NEXT: minos 12.0 +// CHECK-BUILD-TVOSSIM-NEXT: ntools 0 +// CHECK-BUILD-TVOSSIM-NOT: LC_VERSION_MIN + +// CHECK-BUILD-TVOSSIM2: cmd LC_BUILD_VERSION +// CHECK-BUILD-TVOSSIM2-NEXT: cmdsize 24 +// CHECK-BUILD-TVOSSIM2-NEXT: platform tvossim +// CHECK-BUILD-TVOSSIM2-NEXT: sdk n/a +// CHECK-BUILD-TVOSSIM2-NEXT: minos 14.0 +// CHECK-BUILD-TVOSSIM2-NEXT: ntools 0 +// CHECK-BUILD-TVOSSIM2-NOT: LC_VERSION_MIN + +// CHECK-BUILD-WATCHOSSIM: cmd LC_BUILD_VERSION +// CHECK-BUILD-WATCHOSSIM-NEXT: cmdsize 24 +// CHECK-BUILD-WATCHOSSIM-NEXT: platform watchossim +// CHECK-BUILD-WATCHOSSIM-NEXT: sdk n/a +// CHECK-BUILD-WATCHOSSIM-NEXT: minos 5.0 +// CHECK-BUILD-WATCHOSSIM-NEXT: ntools 0 +// CHECK-BUILD-WATCHOSSIM-NOT: LC_VERSION_MIN + +// CHECK-BUILD-WATCHOSSIM2: cmd LC_BUILD_VERSION +// CHECK-BUILD-WATCHOSSIM2-NEXT: cmdsize 24 +// CHECK-BUILD-WATCHOSSIM2-NEXT: platform watchossim +// CHECK-BUILD-WATCHOSSIM2-NEXT: sdk n/a +// CHECK-BUILD-WATCHOSSIM2-NEXT: minos 7.0 +// CHECK-BUILD-WATCHOSSIM2-NEXT: ntools 0 +// CHECK-BUILD-WATCHOSSIM2-NOT: LC_VERSION_MIN + +// CHECK-BUILD-MACOS-ARM64: cmd LC_BUILD_VERSION +// CHECK-BUILD-MACOS-ARM64-NEXT: cmdsize 24 +// CHECK-BUILD-MACOS-ARM64-NEXT: platform macos +// CHECK-BUILD-MACOS-ARM64-NEXT: sdk n/a +// CHECK-BUILD-MACOS-ARM64-NEXT: minos 11.0 +// CHECK-BUILD-MACOS-ARM64-NEXT: ntools 0 +// CHECK-BUILD-MACOS-ARM64-NOT: LC_VERSION_MIN + +// CHECK-BUILD-MACOS-ARM64_1: cmd LC_BUILD_VERSION +// CHECK-BUILD-MACOS-ARM64_1-NEXT: cmdsize 24 +// CHECK-BUILD-MACOS-ARM64_1-NEXT: platform macos +// CHECK-BUILD-MACOS-ARM64_1-NEXT: sdk n/a +// CHECK-BUILD-MACOS-ARM64_1-NEXT: minos 11.1 +// CHECK-BUILD-MACOS-ARM64_1-NEXT: ntools 0 + +// CHECK-MACCATALYST-ARM64: cmd LC_BUILD_VERSION +// CHECK-MACCATALYST-ARM64-NEXT: cmdsize 24 +// CHECK-MACCATALYST-ARM64-NEXT: platform macCatalyst +// CHECK-MACCATALYST-ARM64-NEXT: sdk n/a +// CHECK-MACCATALYST-ARM64-NEXT: minos 14.0 +// CHECK-MACCATALYST-ARM64-NEXT: ntools 0 + +// CHECK-MACCATALYST-ARM64_1: cmd LC_BUILD_VERSION +// CHECK-MACCATALYST-ARM64_1-NEXT: cmdsize 24 +// CHECK-MACCATALYST-ARM64_1-NEXT: platform macCatalyst +// CHECK-MACCATALYST-ARM64_1-NEXT: sdk n/a +// CHECK-MACCATALYST-ARM64_1-NEXT: minos 14.1 +// CHECK-MACCATALYST-ARM64_1-NEXT: ntools 0