diff --git a/src/ispc.cpp b/src/ispc.cpp index d520c191ff5..0b9cbd50ba9 100644 --- a/src/ispc.cpp +++ b/src/ispc.cpp @@ -2351,6 +2351,7 @@ std::string Target::SupportedCPUs() { std::string Target::GetTripleString() const { llvm::Triple triple; + llvm::VersionTuple darwinVersionMin = g->darwinVersionMin; switch (g->target_os) { case TargetOS::windows: if (m_arch == Arch::x86) { @@ -2443,7 +2444,15 @@ std::string Target::GetTripleString() const { exit(1); } triple.setVendor(llvm::Triple::VendorType::Apple); - triple.setOS(llvm::Triple::OSType::MacOSX); + if (darwinVersionMin.empty()) { + darwinVersionMin = (m_arch == Arch::x86_64) ? llvm::VersionTuple(10, 12) : llvm::VersionTuple(11, 0); + } + if (darwinVersionMin != llvm::VersionTuple(INT_MAX)) { + triple.setOSName(llvm::Triple::getOSTypeName(llvm::Triple::OSType::MacOSX).str() + + darwinVersionMin.getAsString()); + } else { + triple.setOS(llvm::Triple::OSType::MacOSX); + } break; case TargetOS::android: if (m_arch == Arch::x86) { @@ -2472,7 +2481,15 @@ std::string Target::GetTripleString() const { // "arm64-apple-ios" triple.setArchName("arm64"); triple.setVendor(llvm::Triple::VendorType::Apple); - triple.setOS(llvm::Triple::OSType::IOS); + if (darwinVersionMin.empty()) { + darwinVersionMin = llvm::VersionTuple(11, 0); + } + if (darwinVersionMin != llvm::VersionTuple(INT_MAX)) { + triple.setOSName(llvm::Triple::getOSTypeName(llvm::Triple::OSType::IOS).str() + + darwinVersionMin.getAsString()); + } else { + triple.setOS(llvm::Triple::OSType::IOS); + } break; case TargetOS::ps4: if (m_arch != Arch::x86_64) { @@ -2861,6 +2878,7 @@ Globals::Globals() { enableLLVMIntrinsics = false; mangleFunctionsWithTarget = false; isMultiTargetCompilation = false; + darwinVersionMin = llvm::VersionTuple(); errorLimit = -1; enableTimeTrace = false; diff --git a/src/ispc.h b/src/ispc.h index 770be156c01..f588599e343 100644 --- a/src/ispc.h +++ b/src/ispc.h @@ -34,6 +34,7 @@ #include #include +#include /** @def ISPC_MAX_NVEC maximum vector size of any of the compliation targets. @@ -901,6 +902,11 @@ struct Globals { /* When compile time tracing is enabled, set time granularity. */ int timeTraceGranularity; + + /* Set macOS/iOS deployment target. The version will be propagated to the triple. + This is required with new linker starting Xcode 15. + https://github.com/ispc/ispc/issues/3143 */ + llvm::VersionTuple darwinVersionMin; }; enum { diff --git a/src/main.cpp b/src/main.cpp index 2153b0daa59..b02bec91cbe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -67,6 +67,10 @@ static void lPrintVersion() { #endif printf(" [--cpu=]\t\t\tAn alias for [--device=] switch\n"); printf(" [-D]\t\t\t\t#define given value when running preprocessor\n"); +#if defined(ISPC_MACOS_TARGET_ON) || defined(ISPC_IOS_TARGET_ON) + printf(" [--darwin-version-min=]\tSet the minimum macOS/iOS version required for the " + "deployment.\n"); +#endif printf(" [--dev-stub ]\t\tEmit device-side offload stub functions to file\n"); printf(" "); char cpuHelp[2048]; @@ -790,6 +794,19 @@ int main(int Argc, char *Argv[]) { "only 2, 3, 4 and 5 are allowed.", argv[i] + 16); } + } else if (!strncmp(argv[i], "--darwin-version-min=", 21)) { + const char *version = argv[i] + 21; + // Validate the version format + std::string versionStr(version); + llvm::VersionTuple versionTuple; + if (!versionStr.empty()) { + if (versionTuple.tryParse(versionStr)) { + errorHandler.AddError("Invalid version format: \"%s\". Use .", version); + } + } else { + versionTuple = llvm::VersionTuple(INT_MAX); // is reserved for "none" version + } + g->darwinVersionMin = versionTuple; } else if (!strcmp(argv[i], "--print-target")) { g->printTarget = true; } else if (!strcmp(argv[i], "--no-omit-frame-pointer")) { diff --git a/tests/lit-tests/darwin-minos-ver-1.ispc b/tests/lit-tests/darwin-minos-ver-1.ispc new file mode 100644 index 00000000000..4ec1be9bce1 --- /dev/null +++ b/tests/lit-tests/darwin-minos-ver-1.ispc @@ -0,0 +1,17 @@ +// The test checks that the triple contain minimum OS version if provided. + +// RUN: %{ispc} %s --nostdlib --target-os=macos --target=avx2 --arch=x86-64 --emit-llvm-text --nowrap -o - | FileCheck %s --check-prefix=CHECK-MACOS-DEFAULT +// RUN: %{ispc} %s --nostdlib --target-os=macos --target=avx2 --arch=x86-64 --emit-llvm-text --nowrap --darwin-version-min=15.0 -o - | FileCheck %s --check-prefix=CHECK-MACOS-VER +// RUN: %{ispc} %s --nostdlib --target-os=macos --target=avx2 --arch=x86-64 --emit-llvm-text --nowrap --darwin-version-min="" -o - | FileCheck %s --check-prefix=CHECK-MACOS-VER-UNSET +// RUN: not %{ispc} %s --nostdlib --target-os=macos --emit-llvm-text --nowrap --target=host --darwin-version-min=a.b -o - 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR-VER + +// REQUIRES: MACOS_HOST && X86_ENABLED + +// CHECK-MACOS-DEFAULT: target triple = {{.*}}-apple-macosx10.12" +// CHECK-MACOS-VER: target triple = {{.*}}-apple-macosx15.0" +// CHECK-MACOS-VER-UNSET: target triple = {{.*}}-apple-macosx" + +// CHECK-ERROR-VER: Error: Invalid version format: "a.b". Use . +uniform int j; + +int foo(int i) { return i + 1; } diff --git a/tests/lit-tests/darwin-minos-ver-2.ispc b/tests/lit-tests/darwin-minos-ver-2.ispc new file mode 100644 index 00000000000..852c83e673f --- /dev/null +++ b/tests/lit-tests/darwin-minos-ver-2.ispc @@ -0,0 +1,26 @@ +// The test checks that the triple contain minimum OS version if provided. +// Note: iOS target is enabled one ARM platforms only. + +// RUN: %{ispc} %s --nostdlib --target-os=ios --arch=aarch64 --emit-llvm-text --nowrap --target=neon-i32x4 -o - | FileCheck %s --check-prefix=CHECK-IOS-DEFAULT +// RUN: %{ispc} %s --nostdlib --target-os=ios --arch=aarch64 --emit-llvm-text --nowrap --target=neon-i32x4 --darwin-version-min=15.0 -o - | FileCheck %s --check-prefix=CHECK-IOS-VER +// RUN: %{ispc} %s --nostdlib --target-os=ios --arch=aarch64 --emit-llvm-text --nowrap --target=neon-i32x4 --darwin-version-min="" -o - | FileCheck %s --check-prefix=CHECK-IOS-VER-UNSET +// RUN: %{ispc} %s --nostdlib --target-os=macos --arch=aarch64 --emit-llvm-text --nowrap --target=neon-i32x4 -o - | FileCheck %s --check-prefix=CHECK-MACOS-DEFAULT +// RUN: %{ispc} %s --nostdlib --target-os=macos --arch=aarch64 --emit-llvm-text --nowrap --target=neon-i32x4 --darwin-version-min=15.0 -o - | FileCheck %s --check-prefix=CHECK-MACOS-VER +// RUN: %{ispc} %s --nostdlib --target-os=macos --arch=aarch64 --emit-llvm-text --nowrap --target=neon-i32x4 --darwin-version-min="" -o - | FileCheck %s --check-prefix=CHECK-MACOS-VER-UNSET + +// RUN: not %{ispc} %s --nostdlib --target-os=ios --arch=aarch64 --emit-llvm-text --nowrap --target=neon-i32x4 --darwin-version-min=a.b -o - 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR-VER + +// REQUIRES: MACOS_HOST && MACOS_ARM_ENABLED + +// CHECK-IOS-DEFAULT: target triple = {{.*}}-apple-ios11.0" +// CHECK-IOS-VER: target triple = {{.*}}-apple-ios15.0" +// CHECK-IOS-VER-UNSET: target triple = {{.*}}-apple-ios" + +// CHECK-MACOS-DEFAULT: target triple = {{.*}}-apple-macosx11.0" +// CHECK-MACOS-VER: target triple = {{.*}}-apple-macosx15.0" +// CHECK-MACOS-VER-UNSET: target triple = {{.*}}-apple-macosx" + +// CHECK-ERROR-VER: Error: Invalid version format: "a.b". Use . +uniform int j; + +int foo(int i) { return i + 1; }