Skip to content

Commit 2bc14f2

Browse files
SixWeiningtru
authored andcommitted
[LoongArch] Support -march=native and -mtune=
As described in [1][2], `-mtune=` is used to select the type of target microarchitecture, defaults to the value of `-march`. The set of possible values should be a superset of `-march` values. Currently possible values of `-march=` and `-mtune=` are `native`, `loongarch64` and `la464`. D136146 has supported `-march={loongarch64,la464}` and this patch adds support for `-march=native` and `-mtune=`. A new ProcessorModel called `loongarch64` is defined in LoongArch.td to support `-mtune=loongarch64`. `llvm::sys::getHostCPUName()` returns `generic` on unknown or future LoongArch CPUs, e.g. the not yet added `la664`, leading to `llvm::LoongArch::isValidArchName()` failing to parse the arch name. In this case, use `loongarch64` as the default arch name for 64-bit CPUs. Two preprocessor macros are defined based on user-provided `-march=` and `-mtune=` options and the defaults. - __loongarch_arch - __loongarch_tune Note that, to work with `-fno-integrated-cc1` we leverage cc1 options `-target-cpu` and `-tune-cpu` to pass driver options `-march=` and `-mtune=` respectively because cc1 needs these information to define macros in `LoongArchTargetInfo::getTargetDefines`. [1]: https://github.com/loongson/LoongArch-Documentation/blob/2023.04.20/docs/LoongArch-toolchain-conventions-EN.adoc [2]: https://github.com/loongson/la-softdev-convention/blob/v0.1/la-softdev-convention.adoc Reviewed By: xen0n, wangleiat, steven_wu, MaskRay Differential Revision: https://reviews.llvm.org/D155824 (cherry picked from commit f62c925)
1 parent d92613e commit 2bc14f2

File tree

15 files changed

+194
-29
lines changed

15 files changed

+194
-29
lines changed

clang/lib/Basic/Targets/LoongArch.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include "clang/Basic/MacroBuilder.h"
1616
#include "clang/Basic/TargetBuiltins.h"
1717
#include "llvm/Support/raw_ostream.h"
18-
#include "llvm/TargetParser/TargetParser.h"
18+
#include "llvm/TargetParser/LoongArchTargetParser.h"
1919

2020
using namespace clang;
2121
using namespace clang::targets;
@@ -198,7 +198,15 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts,
198198
else
199199
Builder.defineMacro("__loongarch_frlen", "0");
200200

201-
// TODO: define __loongarch_arch and __loongarch_tune.
201+
// Define __loongarch_arch.
202+
StringRef ArchName = getCPU();
203+
Builder.defineMacro("__loongarch_arch", Twine('"') + ArchName + Twine('"'));
204+
205+
// Define __loongarch_tune.
206+
StringRef TuneCPU = getTargetOpts().TuneCPU;
207+
if (TuneCPU.empty())
208+
TuneCPU = ArchName;
209+
Builder.defineMacro("__loongarch_tune", Twine('"') + TuneCPU + Twine('"'));
202210

203211
StringRef ABI = getABI();
204212
if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s")
@@ -270,3 +278,12 @@ bool LoongArchTargetInfo::handleTargetFeatures(
270278
}
271279
return true;
272280
}
281+
282+
bool LoongArchTargetInfo::isValidCPUName(StringRef Name) const {
283+
return llvm::LoongArch::isValidCPUName(Name);
284+
}
285+
286+
void LoongArchTargetInfo::fillValidCPUList(
287+
SmallVectorImpl<StringRef> &Values) const {
288+
llvm::LoongArch::fillValidCPUList(Values);
289+
}

clang/lib/Basic/Targets/LoongArch.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ namespace targets {
2424
class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
2525
protected:
2626
std::string ABI;
27+
std::string CPU;
2728
bool HasFeatureD;
2829
bool HasFeatureF;
2930

@@ -40,6 +41,15 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
4041
WIntType = UnsignedInt;
4142
}
4243

44+
bool setCPU(const std::string &Name) override {
45+
if (!isValidCPUName(Name))
46+
return false;
47+
CPU = Name;
48+
return true;
49+
}
50+
51+
StringRef getCPU() const { return CPU; }
52+
4353
StringRef getABI() const override { return ABI; }
4454

4555
void getTargetDefines(const LangOptions &Opts,
@@ -80,6 +90,9 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
8090
const std::vector<std::string> &FeaturesVec) const override;
8191

8292
bool hasFeature(StringRef Feature) const override;
93+
94+
bool isValidCPUName(StringRef Name) const override;
95+
void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
8396
};
8497

8598
class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo

clang/lib/Driver/ToolChains/Arch/LoongArch.cpp

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "clang/Driver/Driver.h"
1313
#include "clang/Driver/DriverDiagnostic.h"
1414
#include "clang/Driver/Options.h"
15+
#include "llvm/TargetParser/Host.h"
1516
#include "llvm/TargetParser/LoongArchTargetParser.h"
1617

1718
using namespace clang::driver;
@@ -126,23 +127,11 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D,
126127
const llvm::Triple &Triple,
127128
const ArgList &Args,
128129
std::vector<StringRef> &Features) {
129-
StringRef ArchName;
130-
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) {
131-
if (!llvm::LoongArch::isValidArchName(A->getValue())) {
132-
D.Diag(clang::diag::err_drv_invalid_arch_name) << A->getAsString(Args);
133-
return;
134-
}
130+
std::string ArchName;
131+
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
135132
ArchName = A->getValue();
136-
}
137-
138-
// TODO: handle -march=native and -mtune=xx.
139-
140-
// Select a default arch name.
141-
if (ArchName.empty() && Triple.isLoongArch64())
142-
ArchName = "loongarch64";
143-
144-
if (!ArchName.empty())
145-
llvm::LoongArch::getArchFeatures(ArchName, Features);
133+
ArchName = postProcessTargetCPUString(ArchName, Triple);
134+
llvm::LoongArch::getArchFeatures(ArchName, Features);
146135

147136
// Select floating-point features determined by -mdouble-float,
148137
// -msingle-float, -msoft-float and -mfpu.
@@ -187,3 +176,25 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D,
187176
if (Arg *A = Args.getLastArgNoClaim(options::OPT_mfpu_EQ))
188177
A->ignoreTargetSpecific();
189178
}
179+
180+
std::string loongarch::postProcessTargetCPUString(const std::string &CPU,
181+
const llvm::Triple &Triple) {
182+
std::string CPUString = CPU;
183+
if (CPUString == "native") {
184+
CPUString = llvm::sys::getHostCPUName();
185+
if (CPUString == "generic")
186+
CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64());
187+
}
188+
if (CPUString.empty())
189+
CPUString = llvm::LoongArch::getDefaultArch(Triple.isLoongArch64());
190+
return CPUString;
191+
}
192+
193+
std::string loongarch::getLoongArchTargetCPU(const llvm::opt::ArgList &Args,
194+
const llvm::Triple &Triple) {
195+
std::string CPU;
196+
// If we have -march, use that.
197+
if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
198+
CPU = A->getValue();
199+
return postProcessTargetCPUString(CPU, Triple);
200+
}

clang/lib/Driver/ToolChains/Arch/LoongArch.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ void getLoongArchTargetFeatures(const Driver &D, const llvm::Triple &Triple,
2323

2424
StringRef getLoongArchABI(const Driver &D, const llvm::opt::ArgList &Args,
2525
const llvm::Triple &Triple);
26+
27+
std::string postProcessTargetCPUString(const std::string &CPU,
28+
const llvm::Triple &Triple);
29+
30+
std::string getLoongArchTargetCPU(const llvm::opt::ArgList &Args,
31+
const llvm::Triple &Triple);
2632
} // end namespace loongarch
2733
} // end namespace tools
2834
} // end namespace driver

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include "llvm/Support/YAMLParser.h"
5757
#include "llvm/TargetParser/ARMTargetParserCommon.h"
5858
#include "llvm/TargetParser/Host.h"
59+
#include "llvm/TargetParser/LoongArchTargetParser.h"
5960
#include "llvm/TargetParser/RISCVTargetParser.h"
6061
#include <cctype>
6162

@@ -1853,10 +1854,20 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
18531854

18541855
void Clang::AddLoongArchTargetArgs(const ArgList &Args,
18551856
ArgStringList &CmdArgs) const {
1857+
const llvm::Triple &Triple = getToolChain().getTriple();
1858+
18561859
CmdArgs.push_back("-target-abi");
1857-
CmdArgs.push_back(loongarch::getLoongArchABI(getToolChain().getDriver(), Args,
1858-
getToolChain().getTriple())
1859-
.data());
1860+
CmdArgs.push_back(
1861+
loongarch::getLoongArchABI(getToolChain().getDriver(), Args, Triple)
1862+
.data());
1863+
1864+
// Handle -mtune.
1865+
if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
1866+
std::string TuneCPU = A->getValue();
1867+
TuneCPU = loongarch::postProcessTargetCPUString(TuneCPU, Triple);
1868+
CmdArgs.push_back("-tune-cpu");
1869+
CmdArgs.push_back(Args.MakeArgString(TuneCPU));
1870+
}
18601871
}
18611872

18621873
void Clang::AddMIPSTargetArgs(const ArgList &Args,

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,10 @@ std::string tools::getCPUName(const Driver &D, const ArgList &Args,
474474
case llvm::Triple::wasm32:
475475
case llvm::Triple::wasm64:
476476
return std::string(getWebAssemblyTargetCPU(Args));
477+
478+
case llvm::Triple::loongarch32:
479+
case llvm::Triple::loongarch64:
480+
return loongarch::getLoongArchTargetCPU(Args, T);
477481
}
478482
}
479483

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: not %clang --target=loongarch64 -march=loongarch -fsyntax-only %s 2>&1 | \
2-
// RUN: FileCheck --check-prefix=LOONGARCH %s
3-
// LOONGARCH: error: invalid arch name '-march=loongarch'
4-
2+
// RUN: FileCheck -DCPU=loongarch %s
53
// RUN: not %clang --target=loongarch64 -march=LA464 -fsyntax-only %s 2>&1 | \
6-
// RUN: FileCheck --check-prefix=LA464-UPPER %s
7-
// LA464-UPPER: error: invalid arch name '-march=LA464'
4+
// RUN: FileCheck -DCPU=LA464 %s
5+
6+
// CHECK: error: unknown target CPU '[[CPU]]'
7+
// CHECK-NEXT: note: valid target CPU values are: {{.*}}

clang/test/Driver/loongarch-march.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@
77
// RUN: %clang --target=loongarch64 -march=la464 -S -emit-llvm %s -o - | \
88
// RUN: FileCheck %s --check-prefix=IR-LA464
99

10+
// CC1-LOONGARCH64: "-target-cpu" "loongarch64"
1011
// CC1-LOONGARCH64-NOT: "-target-feature"
1112
// CC1-LOONGARCH64: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+ual"
1213
// CC1-LOONGARCH64-NOT: "-target-feature"
1314
// CC1-LOONGARCH64: "-target-abi" "lp64d"
1415

16+
// CC1-LA464: "-target-cpu" "la464"
1517
// CC1-LA464-NOT: "-target-feature"
1618
// CC1-LA464: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual"
1719
// CC1-LA464-NOT: "-target-feature"
1820
// CC1-LA464: "-target-abi" "lp64d"
1921

20-
// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-features"="+64bit,+d,+f,+ual"
21-
// IR-LA464: attributes #[[#]] ={{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual"
22+
// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+f,+ual"
23+
// IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" {{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual"
2224

2325
int foo(void) {
2426
return 3;

clang/test/Driver/loongarch-mtune.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %clang --target=loongarch64 -mtune=loongarch64 -fsyntax-only %s -### 2>&1 | \
2+
// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=loongarch64
3+
// RUN: %clang --target=loongarch64 -mtune=loongarch64 -S -emit-llvm %s -o - | \
4+
// RUN: FileCheck %s --check-prefix=IRATTR -DCPU=loongarch64
5+
6+
// RUN: %clang --target=loongarch64 -mtune=la464 -fsyntax-only %s -### 2>&1 | \
7+
// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=la464
8+
// RUN: %clang --target=loongarch64 -mtune=la464 -S -emit-llvm %s -o - | \
9+
// RUN: FileCheck %s --check-prefix=IRATTR -DCPU=la464
10+
11+
// RUN: %clang --target=loongarch64 -mtune=invalidcpu -fsyntax-only %s -### 2>&1 | \
12+
// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=invalidcpu
13+
// RUN: not %clang --target=loongarch64 -mtune=invalidcpu -S -emit-llvm %s -o /dev/null 2>&1 | \
14+
// RUN: FileCheck %s --check-prefix=ERROR -DCPU=invalidcpu
15+
16+
// RUN: %clang --target=loongarch64 -mtune=generic -fsyntax-only %s -### 2>&1 | \
17+
// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=generic
18+
// RUN: not %clang --target=loongarch64 -mtune=generic -S -emit-llvm %s -o /dev/null 2>&1 | \
19+
// RUN: FileCheck %s --check-prefix=ERROR -DCPU=generic
20+
21+
// RUN: %clang --target=loongarch64 -mtune=generic-la64 -fsyntax-only %s -### 2>&1 | \
22+
// RUN: FileCheck %s --check-prefix=CC1ARG -DCPU=generic-la64
23+
// RUN: not %clang --target=loongarch64 -mtune=generic-la64 -S -emit-llvm %s -o /dev/null 2>&1 | \
24+
// RUN: FileCheck %s --check-prefix=ERROR -DCPU=generic-la64
25+
26+
// CC1ARG: "-tune-cpu" "[[CPU]]"
27+
// IRATTR: "tune-cpu"="[[CPU]]"
28+
29+
// ERROR: error: unknown target CPU '[[CPU]]'
30+
// ERROR-NEXT: note: valid target CPU values are: {{.*}}
31+
32+
int foo(void) {
33+
return 3;
34+
}

clang/test/Preprocessor/init-loongarch.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,3 +787,23 @@
787787
// LA64-FPU0-LP64S: #define __loongarch_lp64 1
788788
// LA64-FPU0-LP64S-NOT: #define __loongarch_single_float
789789
// LA64-FPU0-LP64S: #define __loongarch_soft_float 1
790+
791+
/// Check __loongarch_arch and __loongarch_tune.
792+
793+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - | \
794+
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s
795+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 | \
796+
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s
797+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la464 | \
798+
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la464 -DTUNE=la464 %s
799+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=loongarch64 | \
800+
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=loongarch64 %s
801+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=la464 | \
802+
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la464 %s
803+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -mtune=la464 | \
804+
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la464 %s
805+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la464 -mtune=loongarch64 | \
806+
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la464 -DTUNE=loongarch64 %s
807+
808+
// ARCH-TUNE: #define __loongarch_arch "[[ARCH]]"
809+
// ARCH-TUNE: #define __loongarch_tune "[[TUNE]]"

llvm/include/llvm/TargetParser/LoongArchTargetParser.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,12 @@ struct ArchInfo {
6666

6767
bool isValidArchName(StringRef Arch);
6868
bool getArchFeatures(StringRef Arch, std::vector<StringRef> &Features);
69+
bool isValidCPUName(StringRef TuneCPU);
70+
void fillValidCPUList(SmallVectorImpl<StringRef> &Values);
71+
StringRef getDefaultArch(bool Is64Bit);
6972

7073
} // namespace LoongArch
7174

7275
} // namespace llvm
7376

74-
#endif // LLVM_SUPPORT_LOONGARCHTARGETPARSER_H
77+
#endif // LLVM_TARGETPARSER_LOONGARCHTARGETPARSER_H

llvm/lib/Target/LoongArch/LoongArch.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ include "LoongArchInstrInfo.td"
117117
def : ProcessorModel<"generic-la32", NoSchedModel, [Feature32Bit]>;
118118
def : ProcessorModel<"generic-la64", NoSchedModel, [Feature64Bit, FeatureUAL]>;
119119

120+
// Generic 64-bit processor with double-precision floating-point support.
121+
def : ProcessorModel<"loongarch64", NoSchedModel, [Feature64Bit,
122+
FeatureUAL,
123+
FeatureBasicD]>;
124+
120125
// Support generic for compatibility with other targets. The triple will be used
121126
// to change to the appropriate la32/la64 version.
122127
def : ProcessorModel<"generic", NoSchedModel, []>;

llvm/lib/TargetParser/LoongArchTargetParser.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,15 @@ bool LoongArch::getArchFeatures(StringRef Arch,
4646
}
4747
return false;
4848
}
49+
50+
bool LoongArch::isValidCPUName(StringRef Name) { return isValidArchName(Name); }
51+
52+
void LoongArch::fillValidCPUList(SmallVectorImpl<StringRef> &Values) {
53+
for (const auto A : AllArchs)
54+
Values.emplace_back(A.Name);
55+
}
56+
57+
StringRef LoongArch::getDefaultArch(bool Is64Bit) {
58+
// TODO: use a real 32-bit arch name.
59+
return Is64Bit ? "loongarch64" : "";
60+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
; RUN: llc < %s --mtriple=loongarch64 --mattr=+64bit --mcpu=invalidcpu 2>&1 | FileCheck %s
2+
3+
; CHECK: {{.*}} is not a recognized processor for this target
4+
5+
define void @f() {
6+
ret void
7+
}

llvm/test/CodeGen/LoongArch/cpus.ll

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
;; This tests that llc accepts all valid LoongArch CPUs.
2+
;; Note the 'generic' names have been tested in cpu-name-generic.ll.
3+
4+
; RUN: llc < %s --mtriple=loongarch64 --mcpu=loongarch64 2>&1 | FileCheck %s
5+
; RUN: llc < %s --mtriple=loongarch64 --mcpu=la464 2>&1 | FileCheck %s
6+
; RUN: llc < %s --mtriple=loongarch64 2>&1 | FileCheck %s
7+
8+
; CHECK-NOT: {{.*}} is not a recognized processor for this target
9+
10+
define void @f() {
11+
ret void
12+
}
13+
14+
define void @tune_cpu_loongarch64() "tune-cpu"="loongarch64" {
15+
ret void
16+
}
17+
18+
define void @tune_cpu_la464() "tune-cpu"="la464" {
19+
ret void
20+
}

0 commit comments

Comments
 (0)