arphaman created this revision. arphaman added reviewers: ab, t.p.northover, dexonsmith. Herald added subscribers: llvm-commits, danielkiss, ributzka, jkorous, kristof.beyls. Herald added projects: clang, LLVM. arphaman added a comment.
@t.p.northover @ab I noticed that the use of "apple-a12" doesn't infer the right target features when we're passing in a11 or older, so that's why my test file has the `INFER-A12` separate line. Do you think this is a bug? This is decided here: else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features); and CPU value isn't checked here. This change ensures that compiler invocations that target macOS, Mac Catalyst, and the iOS/tvOS/watchOS simulators for arm64 use the "apple-a12" CPU. The `-mcpu` option can still be used to override CPU to a newer variant. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D82699 Files: clang/lib/Driver/ToolChains/Arch/AArch64.cpp clang/test/Driver/aarch64-mac-cpus.c llvm/include/llvm/ADT/Triple.h Index: llvm/include/llvm/ADT/Triple.h =================================================================== --- llvm/include/llvm/ADT/Triple.h +++ llvm/include/llvm/ADT/Triple.h @@ -484,6 +484,12 @@ return getEnvironment() == Triple::MacABI; } + /// Returns true for targets that run on a macOS machine. + bool isTargetMachineMac() const { + return isMacOSX() || (isOSDarwin() && (isSimulatorEnvironment() || + isMacCatalystEnvironment())); + } + bool isOSNetBSD() const { return getOS() == Triple::NetBSD; } Index: clang/test/Driver/aarch64-mac-cpus.c =================================================================== --- /dev/null +++ clang/test/Driver/aarch64-mac-cpus.c @@ -0,0 +1,24 @@ +// arm64 Mac-based targets default to Apple A12. + +// RUN: %clang -target arm64-apple-macos -### -c %s 2>&1 | FileCheck %s +// RUN: %clang -target arm64-apple-ios-macabi -### -c %s 2>&1 | FileCheck %s +// RUN: %clang -target arm64-apple-ios-simulator -### -c %s 2>&1 | FileCheck %s +// RUN: %clang -target arm64-apple-watchos-simulator -### -c %s 2>&1 | FileCheck %s +// RUN: %clang -target arm64-apple-tvos-simulator -### -c %s 2>&1 | FileCheck %s + +// RUN: %clang -target arm64-apple-macos -arch arm64 -### -c %s 2>&1 | FileCheck %s + +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a11 -### -c %s 2>&1 | FileCheck --check-prefix=INFER-A12 %s +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a10 -### -c %s 2>&1 | FileCheck --check-prefix=INFER-A12 %s +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a9 -### -c %s 2>&1 | FileCheck --check-prefix=INFER-A12 %s +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a8 -### -c %s 2>&1 | FileCheck --check-prefix=INFER-A12 %s +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a7 -### -c %s 2>&1 | FileCheck --check-prefix=INFER-A12 %s + +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a13 -### -c %s 2>&1 | FileCheck --check-prefix=EXPLICT-A13 %s + +// CHECK: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a12" +// CHECK-SAME: "-target-feature" "+v8.3a" + +// INFER-A12: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a12" + +// EXPLICT-A13: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a13" Index: clang/lib/Driver/ToolChains/Arch/AArch64.cpp =================================================================== --- clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -25,6 +25,16 @@ return Triple.isOSDarwin(); } +static bool isPreA12AppleCPU(StringRef CPU) { + return llvm::StringSwitch<bool>(CPU) + .Case("apple-a11", true) + .Case("apple-a10", true) + .Case("apple-a9", true) + .Case("apple-a8", true) + .Case("apple-a7", true) + .Default(false); +}; + /// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are /// targeting. Set \p A to the Arg corresponding to the -mcpu argument if it is /// provided, or to nullptr otherwise. @@ -40,7 +50,18 @@ // Handle CPU name is 'native'. if (CPU == "native") return std::string(llvm::sys::getHostCPUName()); - else if (CPU.size()) + + if (Triple.isTargetMachineMac() && + Triple.getArch() == llvm::Triple::aarch64) { + // Honor -mcpu as long it doesn't specify an older CPU than "apple-a12". + if (CPU.size() && !isPreA12AppleCPU(CPU)) + return CPU; + + // Apple Silicon macs default to A12 CPUs. + return "apple-a12"; + } + + if (CPU.size()) return CPU; // Make sure we pick the appropriate Apple CPU if -arch is used or when
Index: llvm/include/llvm/ADT/Triple.h =================================================================== --- llvm/include/llvm/ADT/Triple.h +++ llvm/include/llvm/ADT/Triple.h @@ -484,6 +484,12 @@ return getEnvironment() == Triple::MacABI; } + /// Returns true for targets that run on a macOS machine. + bool isTargetMachineMac() const { + return isMacOSX() || (isOSDarwin() && (isSimulatorEnvironment() || + isMacCatalystEnvironment())); + } + bool isOSNetBSD() const { return getOS() == Triple::NetBSD; } Index: clang/test/Driver/aarch64-mac-cpus.c =================================================================== --- /dev/null +++ clang/test/Driver/aarch64-mac-cpus.c @@ -0,0 +1,24 @@ +// arm64 Mac-based targets default to Apple A12. + +// RUN: %clang -target arm64-apple-macos -### -c %s 2>&1 | FileCheck %s +// RUN: %clang -target arm64-apple-ios-macabi -### -c %s 2>&1 | FileCheck %s +// RUN: %clang -target arm64-apple-ios-simulator -### -c %s 2>&1 | FileCheck %s +// RUN: %clang -target arm64-apple-watchos-simulator -### -c %s 2>&1 | FileCheck %s +// RUN: %clang -target arm64-apple-tvos-simulator -### -c %s 2>&1 | FileCheck %s + +// RUN: %clang -target arm64-apple-macos -arch arm64 -### -c %s 2>&1 | FileCheck %s + +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a11 -### -c %s 2>&1 | FileCheck --check-prefix=INFER-A12 %s +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a10 -### -c %s 2>&1 | FileCheck --check-prefix=INFER-A12 %s +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a9 -### -c %s 2>&1 | FileCheck --check-prefix=INFER-A12 %s +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a8 -### -c %s 2>&1 | FileCheck --check-prefix=INFER-A12 %s +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a7 -### -c %s 2>&1 | FileCheck --check-prefix=INFER-A12 %s + +// RUN: %clang -target arm64-apple-macos -mcpu=apple-a13 -### -c %s 2>&1 | FileCheck --check-prefix=EXPLICT-A13 %s + +// CHECK: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a12" +// CHECK-SAME: "-target-feature" "+v8.3a" + +// INFER-A12: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a12" + +// EXPLICT-A13: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "apple-a13" Index: clang/lib/Driver/ToolChains/Arch/AArch64.cpp =================================================================== --- clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -25,6 +25,16 @@ return Triple.isOSDarwin(); } +static bool isPreA12AppleCPU(StringRef CPU) { + return llvm::StringSwitch<bool>(CPU) + .Case("apple-a11", true) + .Case("apple-a10", true) + .Case("apple-a9", true) + .Case("apple-a8", true) + .Case("apple-a7", true) + .Default(false); +}; + /// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are /// targeting. Set \p A to the Arg corresponding to the -mcpu argument if it is /// provided, or to nullptr otherwise. @@ -40,7 +50,18 @@ // Handle CPU name is 'native'. if (CPU == "native") return std::string(llvm::sys::getHostCPUName()); - else if (CPU.size()) + + if (Triple.isTargetMachineMac() && + Triple.getArch() == llvm::Triple::aarch64) { + // Honor -mcpu as long it doesn't specify an older CPU than "apple-a12". + if (CPU.size() && !isPreA12AppleCPU(CPU)) + return CPU; + + // Apple Silicon macs default to A12 CPUs. + return "apple-a12"; + } + + if (CPU.size()) return CPU; // Make sure we pick the appropriate Apple CPU if -arch is used or when
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits