Index: lib/Basic/Targets/X86.h =================================================================== --- lib/Basic/Targets/X86.h +++ lib/Basic/Targets/X86.h @@ -264,6 +264,8 @@ return checkCPUKind(getCPUKind(Name)); } + void fillValidCPUList(SmallVectorImpl &Values) const override; + bool setCPU(const std::string &Name) override { return checkCPUKind(CPU = getCPUKind(Name)); } Index: lib/Basic/Targets/X86.cpp =================================================================== --- lib/Basic/Targets/X86.cpp +++ lib/Basic/Targets/X86.cpp @@ -15,6 +15,7 @@ #include "clang/Basic/Builtins.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetBuiltins.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/TargetParser.h" @@ -1648,8 +1649,6 @@ bool X86TargetInfo::checkCPUKind(CPUKind Kind) const { // Perform any per-CPU checks necessary to determine if this CPU is // acceptable. - // FIXME: This results in terrible diagnostics. Clang just says the CPU is - // invalid without explaining *why*. switch (Kind) { case CK_Generic: // No processor selected! @@ -1662,6 +1661,18 @@ llvm_unreachable("Unhandled CPU kind"); } +void X86TargetInfo::fillValidCPUList(SmallVectorImpl &Values) const { +#define PROC(ENUM, STRING, IS64BIT) \ + if (IS64BIT || getTriple().getArch() == llvm::Triple::x86) \ + Values.emplace_back(STRING); + // Go through CPUKind checking to ensure that the alias is de-aliased and + // 64 bit-ness is checked. +#define PROC_ALIAS(ENUM, ALIAS) \ + if (checkCPUKind(getCPUKind(ALIAS))) \ + Values.emplace_back(ALIAS); +#include "clang/Basic/X86Target.def" +} + X86TargetInfo::CPUKind X86TargetInfo::getCPUKind(StringRef CPU) const { return llvm::StringSwitch(CPU) #define PROC(ENUM, STRING, IS64BIT) .Case(STRING, CK_##ENUM) Index: test/Misc/target-invalid-cpu-note.c =================================================================== --- test/Misc/target-invalid-cpu-note.c +++ test/Misc/target-invalid-cpu-note.c @@ -7,3 +7,27 @@ // AARCH64: error: unknown target CPU 'not-a-cpu' // AARCH64: note: valid target CPU values are: // AARCH64-SAME: cortex-a35 + +// RUN: not %clang_cc1 -triple i386--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix X86 +// X86: error: unknown target CPU 'not-a-cpu' +// X86: note: valid target CPU values are: i386, i486, winchip-c6, winchip2, c3, +// X86-SAME: i586, pentium, pentium-mmx, pentiumpro, i686, pentium2, pentium3, +// X86-SAME: pentium3m, pentium-m, c3-2, yonah, pentium4, pentium4m, prescott, +// X86-SAME: nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, +// X86-SAME: nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, +// X86-SAME: core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, +// X86-SAME: skx, cannonlake, icelake, knl, knm, lakemont, k6, k6-2, k6-3, +// X86-SAME: athlon, athlon-tbird, athlon-xp, athlon-mp, athlon-4, k8, athlon64, +// X86-SAME: athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, +// X86-SAME: barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, +// X86-SAME: x86-64, geode + +// RUN: not %clang_cc1 -triple x86_64--- -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix X86_64 +// X86_64: error: unknown target CPU 'not-a-cpu' +// X86_64: note: valid target CPU values are: nocona, core2, penryn, bonnell, +// X86_64-SAME: atom, silvermont, slm, goldmont, nehalem, corei7, westmere, +// X86_64-SAME: sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, +// X86_64-SAME: core-avx2, broadwell, skylake, skylake-avx512, skx, cannonlake, +// X86_64-SAME: icelake, knl, knm, k8, athlon64, athlon-fx, opteron, k8-sse3, +// X86_64-SAME: athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, +// X86_64-SAME: btver2, bdver1, bdver2, bdver3, bdver4, znver1, x86-64