Index: include/clang/Basic/TargetInfo.h =================================================================== --- include/clang/Basic/TargetInfo.h +++ include/clang/Basic/TargetInfo.h @@ -753,10 +753,10 @@ return TheCXXABI; } - /// \brief Target the specified CPU. + /// \brief Target the specified CPU, or a generic cpu for Arch. /// /// \return False on error (invalid CPU name). - virtual bool setCPU(const std::string &Name) { + virtual bool setCPU(const std::string &Name, StringRef ArchName) { return false; } Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -793,7 +793,7 @@ // 401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801, // 821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell, // titan, rs64. - bool setCPU(const std::string &Name) override { + bool setCPU(const std::string &Name, StringRef ArchName) override { bool CPUKnown = llvm::StringSwitch(Name) .Case("generic", true) .Case("440", true) @@ -1668,7 +1668,7 @@ // FIXME: implement return TargetInfo::CharPtrBuiltinVaList; } - bool setCPU(const std::string &Name) override { + bool setCPU(const std::string &Name, StringRef ArchName) override { GPU = llvm::StringSwitch(Name) .Case("sm_20", GK_SM20) .Case("sm_21", GK_SM21) @@ -1853,7 +1853,7 @@ return TargetInfo::CharPtrBuiltinVaList; } - bool setCPU(const std::string &Name) override { + bool setCPU(const std::string &Name, StringRef ArchName) override { GPU = llvm::StringSwitch(Name) .Case("r600" , GK_R600) .Case("rv610", GK_R600) @@ -2320,7 +2320,7 @@ return "no-mmx"; return ""; } - bool setCPU(const std::string &Name) override { + bool setCPU(const std::string &Name, StringRef ArchName) override { CPU = llvm::StringSwitch(Name) .Case("i386", CK_i386) .Case("i486", CK_i486) @@ -4246,21 +4246,20 @@ ArchISA = llvm::ARMTargetParser::parseArchISA(ArchName); DefaultCPU = getDefaultCPU(ArchName); - // SubArch is specified by the target triple - if (!DefaultCPU.empty()) - setArchInfo(DefaultCPU); - else - // FIXME ArchInfo should be based on ArchName from triple, not on - // a hard-coded CPU name. Doing so currently causes regressions: - // test/Preprocessor/init.c: __ARM_ARCH_6J__ not defined - setArchInfo(CPU); + StringRef CPUName = !DefaultCPU.empty() ? DefaultCPU : StringRef(CPU); + // FIXME ArchInfo should be based on ArchName from triple, not on + // a hard-coded CPU name. Doing so currently causes regressions: + // test/Preprocessor/init.c: __ARM_ARCH_6J__ not defined + setArchInfo((CPUName != "generic") ? + llvm::ARMTargetParser::parseCPUArch(CPUName): + llvm::ARMTargetParser::parseArch(ArchName)); } - void setArchInfo(StringRef CPU) { + void setArchInfo(unsigned Kind) { StringRef SubArch; // cache TargetParser info - ArchKind = llvm::ARMTargetParser::parseCPUArch(CPU); + ArchKind = Kind; SubArch = llvm::ARMTargetParser::getSubArch(ArchKind); ArchProfile = llvm::ARMTargetParser::parseArchProfile(SubArch); ArchVersion = llvm::ARMTargetParser::parseArchVersion(SubArch); @@ -4557,11 +4556,14 @@ .Default(false); } - bool setCPU(const std::string &Name) override { - unsigned ArchKind = llvm::ARMTargetParser::parseCPUArch(Name); + bool setCPU(const std::string &Name, StringRef ArchName) override { + unsigned ArchKind = (Name != "generic") ? + llvm::ARMTargetParser::parseCPUArch(Name): + llvm::ARMTargetParser::parseArch(ArchName); + if (ArchKind == llvm::ARM::AK_INVALID) return false; - setArchInfo(Name); + setArchInfo(ArchKind); setAtomic(); CPU = Name; return true; @@ -5112,7 +5114,7 @@ return true; } - bool setCPU(const std::string &Name) override { + bool setCPU(const std::string &Name, StringRef ArchName) override { bool CPUKnown = llvm::StringSwitch(Name) .Case("generic", true) .Cases("cortex-a53", "cortex-a57", "cortex-a72", true) @@ -5491,7 +5493,7 @@ .Default(nullptr); } - bool setCPU(const std::string &Name) override { + bool setCPU(const std::string &Name, StringRef ArchName) override { if (!getHexagonCPUSuffix(Name)) return false; @@ -5780,7 +5782,7 @@ } } - bool setCPU(const std::string &Name) override { + bool setCPU(const std::string &Name, StringRef ArchName) override { bool CPUKnown = llvm::StringSwitch(Name) .Case("v9", true) .Case("ultrasparc", true) @@ -5855,7 +5857,7 @@ BuiltinVaListKind getBuiltinVaListKind() const override { return TargetInfo::SystemZBuiltinVaList; } - bool setCPU(const std::string &Name) override { + bool setCPU(const std::string &Name, StringRef ArchName) override { CPU = Name; bool CPUKnown = llvm::StringSwitch(Name) .Case("z10", true) @@ -6209,7 +6211,7 @@ } StringRef getABI() const override { return ABI; } - bool setCPU(const std::string &Name) override { + bool setCPU(const std::string &Name, StringRef ArchName) override { bool IsMips32 = getTriple().getArch() == llvm::Triple::mips || getTriple().getArch() == llvm::Triple::mipsel; CPU = Name; @@ -7507,7 +7509,7 @@ Target->TargetOpts = Opts; // Set the target CPU if specified. - if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) { + if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU, Triple.getArchName())) { Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU; return nullptr; }