Skip to content

Commit 481211f

Browse files
committed
Support amcas[_db].{b/h/w/d} instructions.
1 parent facdae6 commit 481211f

File tree

16 files changed

+5654
-28
lines changed

16 files changed

+5654
-28
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5414,6 +5414,10 @@ def mlam_bh : Flag<["-"], "mlam-bh">, Group<m_loongarch_Features_Group>,
54145414
HelpText<"Enable amswap[_db].{b/h} and amadd[_db].{b/h}">;
54155415
def mno_lam_bh : Flag<["-"], "mno-lam-bh">, Group<m_loongarch_Features_Group>,
54165416
HelpText<"Disable amswap[_db].{b/h} and amadd[_db].{b/h}">;
5417+
def mlamcas : Flag<["-"], "mlamcas">, Group<m_loongarch_Features_Group>,
5418+
HelpText<"Enable amcas[_db].{b/h/w/d}">;
5419+
def mno_lamcas : Flag<["-"], "mno-lamcas">, Group<m_loongarch_Features_Group>,
5420+
HelpText<"Disable amcas[_db].{b/h/w/d}">;
54175421
def mannotate_tablejump : Flag<["-"], "mannotate-tablejump">, Group<m_loongarch_Features_Group>,
54185422
HelpText<"Enable annotate table jump instruction to correlate it with the jump table.">;
54195423
def mno_annotate_tablejump : Flag<["-"], "mno-annotate-tablejump">, Group<m_loongarch_Features_Group>,

clang/lib/Basic/Targets/LoongArch.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts,
205205
// TODO: As more features of the V1.1 ISA are supported, a unified "v1.1"
206206
// arch feature set will be used to include all sub-features belonging to
207207
// the V1.1 ISA version.
208-
if (HasFeatureFrecipe && HasFeatureLAM_BH)
208+
if (HasFeatureFrecipe && HasFeatureLAM_BH && HasFeatureLAMCAS)
209209
Builder.defineMacro("__loongarch_arch",
210210
Twine('"') + "la64v1.1" + Twine('"'));
211211
else
@@ -239,6 +239,9 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts,
239239
if (HasFeatureLAM_BH)
240240
Builder.defineMacro("__loongarch_lam_bh", Twine(1));
241241

242+
if (HasFeatureLAMCAS)
243+
Builder.defineMacro("__loongarch_lamcas", Twine(1));
244+
242245
StringRef ABI = getABI();
243246
if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s")
244247
Builder.defineMacro("__loongarch_lp64");
@@ -317,6 +320,8 @@ bool LoongArchTargetInfo::handleTargetFeatures(
317320
HasFeatureFrecipe = true;
318321
else if (Feature == "+lam-bh")
319322
HasFeatureLAM_BH = true;
323+
else if (Feature == "+lamcas")
324+
HasFeatureLAMCAS = true;
320325
}
321326
return true;
322327
}

clang/lib/Basic/Targets/LoongArch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
3131
bool HasFeatureLASX;
3232
bool HasFeatureFrecipe;
3333
bool HasFeatureLAM_BH;
34+
bool HasFeatureLAMCAS;
3435

3536
public:
3637
LoongArchTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
@@ -41,6 +42,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
4142
HasFeatureLASX = false;
4243
HasFeatureFrecipe = false;
4344
HasFeatureLAM_BH = false;
45+
HasFeatureLAMCAS = false;
4446
LongDoubleWidth = 128;
4547
LongDoubleAlign = 128;
4648
LongDoubleFormat = &llvm::APFloat::IEEEquad();

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,15 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D,
269269
else
270270
Features.push_back("-lam-bh");
271271
}
272+
273+
// Select lamcas feature determined by -m[no-]lamcas.
274+
if (const Arg *A =
275+
Args.getLastArg(options::OPT_mlamcas, options::OPT_mno_lamcas)) {
276+
if (A->getOption().matches(options::OPT_mlamcas))
277+
Features.push_back("+lamcas");
278+
else
279+
Features.push_back("-lamcas");
280+
}
272281
}
273282

274283
std::string loongarch::postProcessTargetCPUString(const std::string &CPU,

clang/test/Driver/loongarch-march.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,21 @@
3939

4040
// CC1-LA64V1P1: "-target-cpu" "loongarch64"
4141
// CC1-LA64V1P1-NOT: "-target-feature"
42-
// CC1-LA64V1P1: "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual" "-target-feature" "+frecipe" "-target-feature" "+lam-bh"
42+
// CC1-LA64V1P1: "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual" "-target-feature" "+frecipe" "-target-feature" "+lam-bh" "-target-feature" "+lamcas"
4343
// CC1-LA64V1P1-NOT: "-target-feature"
4444
// CC1-LA64V1P1: "-target-abi" "lp64d"
4545

4646
// CC1-LA664: "-target-cpu" "la664"
4747
// CC1-LA664-NOT: "-target-feature"
48-
// CC1-LA664: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual" "-target-feature" "+frecipe" "-target-feature" "+lam-bh"
48+
// CC1-LA664: "-target-feature" "+64bit" "-target-feature" "+f" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+lasx" "-target-feature" "+ual" "-target-feature" "+frecipe" "-target-feature" "+lam-bh" "-target-feature" "+lamcas"
4949
// CC1-LA664-NOT: "-target-feature"
5050
// CC1-LA664: "-target-abi" "lp64d"
5151

5252
// IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+f,+ual"
5353
// IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" {{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual"
5454
// IR-LA64V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+lsx,+ual"
55-
// IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+frecipe,+lam-bh,+lsx,+ual"
56-
// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" {{.*}}"target-features"="+64bit,+d,+f,+frecipe,+lam-bh,+lasx,+lsx,+ual"
55+
// IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+frecipe,+lam-bh,+lamcas,+lsx,+ual"
56+
// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" {{.*}}"target-features"="+64bit,+d,+f,+frecipe,+lam-bh,+lamcas,+lasx,+lsx,+ual"
5757

5858
int foo(void) {
5959
return 3;

clang/test/Driver/loongarch-mlamcas.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/// Test -m[no]lamcas options.
2+
3+
// RUN: %clang --target=loongarch64 -mlamcas -fsyntax-only %s -### 2>&1 | \
4+
// RUN: FileCheck %s --check-prefix=CC1-LAMCAS
5+
// RUN: %clang --target=loongarch64 -mno-lamcas -fsyntax-only %s -### 2>&1 | \
6+
// RUN: FileCheck %s --check-prefix=CC1-NO-LAMCAS
7+
// RUN: %clang --target=loongarch64 -mno-lamcas -mlamcas -fsyntax-only %s -### 2>&1 | \
8+
// RUN: FileCheck %s --check-prefix=CC1-LAMCAS
9+
// RUN: %clang --target=loongarch64 -mlamcas -mno-lamcas -fsyntax-only %s -### 2>&1 | \
10+
// RUN: FileCheck %s --check-prefix=CC1-NO-LAMCAS
11+
12+
// RUN: %clang --target=loongarch64 -mlamcas -S -emit-llvm %s -o - | \
13+
// RUN: FileCheck %s --check-prefix=IR-LAMCAS
14+
// RUN: %clang --target=loongarch64 -mno-lamcas -S -emit-llvm %s -o - | \
15+
// RUN: FileCheck %s --check-prefix=IR-NO-LAMCAS
16+
// RUN: %clang --target=loongarch64 -mno-lamcas -mlamcas -S -emit-llvm %s -o - | \
17+
// RUN: FileCheck %s --check-prefix=IR-LAMCAS
18+
// RUN: %clang --target=loongarch64 -mlamcas -mno-lamcas -S -emit-llvm %s -o - | \
19+
// RUN: FileCheck %s --check-prefix=IR-NO-LAMCAS
20+
21+
22+
// CC1-LAMCAS: "-target-feature" "+lamcas"
23+
// CC1-NO-LAMCAS: "-target-feature" "-lamcas"
24+
25+
// IR-LAMCAS: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+lamcas{{(,.*)?}}"
26+
// IR-NO-LAMCAS: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}-lamcas{{(,.*)?}}"
27+
28+
int foo(void) {
29+
return 42;
30+
}

clang/test/Preprocessor/init-loongarch.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -798,7 +798,7 @@
798798
// LA64-FPU0-LP64S-NOT: #define __loongarch_single_float
799799
// LA64-FPU0-LP64S: #define __loongarch_soft_float 1
800800

801-
/// Check __loongarch_arch{_tune/_frecipe/_lam_bh}.
801+
/// Check __loongarch_arch{_tune/_frecipe/_lam_bh/_lamcas}.
802802

803803
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - | \
804804
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=loongarch64 %s
@@ -823,37 +823,46 @@
823823
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx | \
824824
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=loongarch64 %s
825825
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 | \
826-
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH -DARCH=la64v1.1 -DTUNE=loongarch64 %s
826+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,LAMCAS -DARCH=la64v1.1 -DTUNE=loongarch64 %s
827827
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -frecipe | \
828-
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAM-BH -DARCH=la64v1.0 -DTUNE=loongarch64 %s
828+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAM-BH,LAMCAS -DARCH=la64v1.0 -DTUNE=loongarch64 %s
829829
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -lsx | \
830-
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH -DARCH=loongarch64 -DTUNE=loongarch64 %s
830+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,LAMCAS -DARCH=loongarch64 -DTUNE=loongarch64 %s
831831
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +frecipe | \
832832
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=loongarch64 -DTUNE=loongarch64 %s
833833
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +frecipe | \
834834
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=la64v1.0 -DTUNE=loongarch64 %s
835835
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 -Xclang -target-feature -Xclang +lam-bh | \
836836
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAM-BH -DARCH=la64v1.0 -DTUNE=loongarch64 %s
837837
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -lam-bh | \
838-
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=la64v1.0 -DTUNE=loongarch64 %s
838+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAMCAS -DARCH=la64v1.0 -DTUNE=loongarch64 %s
839839
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lam-bh | \
840840
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAM-BH -DARCH=loongarch64 -DTUNE=loongarch64 %s
841841
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +lam-bh | \
842842
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAM-BH -DARCH=la64v1.0 -DTUNE=loongarch64 %s
843-
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 -Xclang -target-feature -Xclang +frecipe -Xclang -target-feature -Xclang +lam-bh | \
843+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 -Xclang -target-feature -Xclang +lamcas | \
844+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAMCAS -DARCH=la64v1.0 -DTUNE=loongarch64 %s
845+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -lamcas | \
846+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH -DARCH=la64v1.0 -DTUNE=loongarch64 %s
847+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lamcas | \
848+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAMCAS -DARCH=loongarch64 -DTUNE=loongarch64 %s
849+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +lamcas | \
850+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAMCAS -DARCH=la64v1.0 -DTUNE=loongarch64 %s
851+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 -Xclang -target-feature -Xclang +frecipe -Xclang -target-feature -Xclang +lam-bh -Xclang -target-feature -Xclang +lamcas | \
844852
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE -DARCH=la64v1.1 -DTUNE=loongarch64 %s
845853
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la664 | \
846-
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH -DARCH=la664 -DTUNE=la664 %s
854+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,LAMCAS -DARCH=la664 -DTUNE=la664 %s
847855
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=la664 | \
848856
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=la664 %s
849857
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -mtune=la664 | \
850858
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la664 %s
851859
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la664 -mtune=loongarch64 | \
852-
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH -DARCH=la664 -DTUNE=loongarch64 %s
860+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,LAMCAS -DARCH=la664 -DTUNE=loongarch64 %s
853861

854862
// ARCH-TUNE: #define __loongarch_arch "[[ARCH]]"
855863
// FRECIPE: #define __loongarch_frecipe 1
856864
// LAM-BH: #define __loongarch_lam_bh 1
865+
// LAMCAS: #define __loongarch_lamcas 1
857866
// ARCH-TUNE: #define __loongarch_tune "[[TUNE]]"
858867

859868
// RUN: %clang --target=loongarch64 -mlsx -x c -E -dM %s -o - \

llvm/include/llvm/TargetParser/LoongArchTargetParser.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ LOONGARCH_FEATURE("+lvz", FK_LVZ)
1212
LOONGARCH_FEATURE("+ual", FK_UAL)
1313
LOONGARCH_FEATURE("+frecipe", FK_FRECIPE)
1414
LOONGARCH_FEATURE("+lam-bh", FK_LAM_BH)
15+
LOONGARCH_FEATURE("+lamcas", FK_LAMCAS)
1516

1617
#undef LOONGARCH_FEATURE
1718

@@ -21,6 +22,6 @@ LOONGARCH_FEATURE("+lam-bh", FK_LAM_BH)
2122

2223
LOONGARCH_ARCH("loongarch64", AK_LOONGARCH64, FK_64BIT | FK_FP32 | FK_FP64 | FK_UAL)
2324
LOONGARCH_ARCH("la464", AK_LA464, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL)
24-
LOONGARCH_ARCH("la664", AK_LA664, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL | FK_FRECIPE | FK_LAM_BH)
25+
LOONGARCH_ARCH("la664", AK_LA664, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL | FK_FRECIPE | FK_LAM_BH | FK_LAMCAS)
2526

2627
#undef LOONGARCH_ARCH

llvm/include/llvm/TargetParser/LoongArchTargetParser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ enum FeatureKind : uint32_t {
5353
// Atomic memory swap and add instructions for byte and half word are
5454
// available.
5555
FK_LAM_BH = 1 << 10,
56+
57+
// Atomic memory compare and swap instructions for byte, half word, word and
58+
// double word are available.
59+
FK_LAMCAS = 1 << 11,
5660
};
5761

5862
struct FeatureInfo {

llvm/lib/Target/LoongArch/AsmParser/LoongArchAsmParser.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1562,7 +1562,9 @@ unsigned LoongArchAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
15621562
unsigned Opc = Inst.getOpcode();
15631563
switch (Opc) {
15641564
default:
1565-
if (Opc >= LoongArch::AMADD_D && Opc <= LoongArch::AMXOR_W) {
1565+
// amcas[_db].{b/h/w/d} didn't need this judgement
1566+
if ((Opc >= LoongArch::AMADD_B && Opc <= LoongArch::AMAND__DB_W) ||
1567+
(Opc >= LoongArch::AMMAX_D && Opc <= LoongArch::AMXOR__DB_W)) {
15661568
MCRegister Rd = Inst.getOperand(0).getReg();
15671569
MCRegister Rk = Inst.getOperand(1).getReg();
15681570
MCRegister Rj = Inst.getOperand(2).getReg();

llvm/lib/Target/LoongArch/LoongArch.td

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,12 @@ def FeatureLAM_BH
118118
"Support amswap[_db].{b/h} and amadd[_db].{b/h} instructions.">;
119119
def HasLAM_BH : Predicate<"Subtarget->hasLAM_BH()">;
120120

121+
// Atomic memory compare and swap instructions for byte, half word, word and double word
122+
def FeatureLAMCAS
123+
: SubtargetFeature<"lamcas", "HasLAMCAS", "true",
124+
"Support amcas[_db].{b/h/w/d}.">;
125+
def HasLAMCAS : Predicate<"Subtarget->hasLAMCAS()">;
126+
121127
def TunePreferWInst
122128
: SubtargetFeature<"prefer-w-inst", "PreferWInst", "true",
123129
"Prefer instructions with W suffix">;
@@ -158,7 +164,8 @@ def : ProcessorModel<"la664", NoSchedModel, [Feature64Bit,
158164
FeatureExtLVZ,
159165
FeatureExtLBT,
160166
FeatureFrecipe,
161-
FeatureLAM_BH]>;
167+
FeatureLAM_BH,
168+
FeatureLAMCAS]>;
162169

163170
//===----------------------------------------------------------------------===//
164171
// Define the LoongArch target.

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,10 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
363363
setPrefFunctionAlignment(Subtarget.getPrefFunctionAlignment());
364364
setPrefLoopAlignment(Subtarget.getPrefLoopAlignment());
365365
setMaxBytesForAlignment(Subtarget.getMaxBytesForAlignment());
366+
367+
// cmpxchg sizes down to 8 bits become legal if LAMCAS is available.
368+
if (Subtarget.hasLAMCAS())
369+
setMinCmpXchgSizeInBits(8);
366370
}
367371

368372
bool LoongArchTargetLowering::isOffsetFoldingLegal(
@@ -5743,6 +5747,10 @@ LoongArchTargetLowering::shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const {
57435747
}
57445748

57455749
unsigned Size = AI->getType()->getPrimitiveSizeInBits();
5750+
if (Subtarget.hasLAMCAS() &&
5751+
(AI->getOperation() == AtomicRMWInst::Nand || Size < 32))
5752+
return AtomicExpansionKind::CmpXChg;
5753+
57465754
if (Size == 8 || Size == 16)
57475755
return AtomicExpansionKind::MaskedIntrinsic;
57485756
return AtomicExpansionKind::None;
@@ -5797,6 +5805,10 @@ getIntrinsicForMaskedAtomicRMWBinOp(unsigned GRLen,
57975805
TargetLowering::AtomicExpansionKind
57985806
LoongArchTargetLowering::shouldExpandAtomicCmpXchgInIR(
57995807
AtomicCmpXchgInst *CI) const {
5808+
5809+
if (Subtarget.hasLAMCAS())
5810+
return AtomicExpansionKind::None;
5811+
58005812
unsigned Size = CI->getCompareOperand()->getType()->getPrimitiveSizeInBits();
58015813
if (Size == 8 || Size == 16)
58025814
return AtomicExpansionKind::MaskedIntrinsic;
@@ -6292,8 +6304,8 @@ bool LoongArchTargetLowering::hasAndNotCompare(SDValue Y) const {
62926304
}
62936305

62946306
ISD::NodeType LoongArchTargetLowering::getExtendForAtomicCmpSwapArg() const {
6295-
// TODO: LAMCAS will use amcas{_DB,}.[bhwd] which does not require extension.
6296-
return ISD::SIGN_EXTEND;
6307+
// LAMCAS will use amcas[_DB].{b/h/w/d} which does not require extension.
6308+
return Subtarget.hasLAMCAS() ? ISD::ANY_EXTEND : ISD::SIGN_EXTEND;
62976309
}
62986310

62996311
bool LoongArchTargetLowering::shouldSignExtendTypeInLibCall(

llvm/lib/Target/LoongArch/LoongArchInstrInfo.td

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -710,10 +710,16 @@ class STORE_2RI14<bits<32> op>
710710
"$rd, $rj, $imm14">;
711711
} // hasSideEffects = 0, mayLoad = 0, mayStore = 1
712712

713-
let hasSideEffects = 0, mayLoad = 1, mayStore = 1, Constraints = "@earlyclobber $rd" in
713+
let hasSideEffects = 0, mayLoad = 1, mayStore = 1, Constraints = "@earlyclobber $rd" in {
714714
class AM_3R<bits<32> op>
715715
: Fmt3R<op, (outs GPR:$rd), (ins GPR:$rk, GPRMemAtomic:$rj),
716716
"$rd, $rk, $rj">;
717+
}
718+
719+
let hasSideEffects = 0, mayLoad = 1, mayStore = 1, Constraints = "$rd = $dst" in
720+
class AMCAS_3R<bits<32> op>
721+
: Fmt3R<op, (outs GPR:$dst), (ins GPR:$rd, GPR:$rk, GPRMemAtomic:$rj),
722+
"$rd, $rk, $rj">;
717723

718724
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
719725
class LLBase<bits<32> op>
@@ -1024,14 +1030,14 @@ def AMMAX__DB_WU : AM_3R<0x38700000>;
10241030
def AMMAX__DB_DU : AM_3R<0x38708000>;
10251031
def AMMIN__DB_WU : AM_3R<0x38710000>;
10261032
def AMMIN__DB_DU : AM_3R<0x38718000>;
1027-
def AMCAS_B : AM_3R<0x38580000>;
1028-
def AMCAS_H : AM_3R<0x38588000>;
1029-
def AMCAS_W : AM_3R<0x38590000>;
1030-
def AMCAS_D : AM_3R<0x38598000>;
1031-
def AMCAS__DB_B : AM_3R<0x385a0000>;
1032-
def AMCAS__DB_H : AM_3R<0x385a8000>;
1033-
def AMCAS__DB_W : AM_3R<0x385b0000>;
1034-
def AMCAS__DB_D : AM_3R<0x385b8000>;
1033+
def AMCAS_B : AMCAS_3R<0x38580000>;
1034+
def AMCAS_H : AMCAS_3R<0x38588000>;
1035+
def AMCAS_W : AMCAS_3R<0x38590000>;
1036+
def AMCAS_D : AMCAS_3R<0x38598000>;
1037+
def AMCAS__DB_B : AMCAS_3R<0x385a0000>;
1038+
def AMCAS__DB_H : AMCAS_3R<0x385a8000>;
1039+
def AMCAS__DB_W : AMCAS_3R<0x385b0000>;
1040+
def AMCAS__DB_D : AMCAS_3R<0x385b8000>;
10351041
def LL_D : LLBase<0x22000000>;
10361042
def SC_D : SCBase<0x23000000>;
10371043
def SC_Q : SCBase_128<0x38570000>;
@@ -2106,6 +2112,26 @@ def : Pat<(atomic_load_sub_i16 GPR:$rj, GPR:$rk),
21062112
(AMADD__DB_H (SUB_W R0, GPR:$rk), GPR:$rj)>;
21072113
} // Predicates = [ IsLA64, HasLAM_BH ]
21082114

2115+
let Predicates = [ HasLAMCAS, IsLA64 ] in {
2116+
2117+
def : Pat<(atomic_cmp_swap_i8_monotonic GPR:$addr, GPR:$cmp, GPR:$new),
2118+
(AMCAS_B GPR:$cmp, GPR:$new, GPR:$addr)>;
2119+
def : Pat<(atomic_cmp_swap_i16_monotonic GPR:$addr, GPR:$cmp, GPR:$new),
2120+
(AMCAS_H GPR:$cmp, GPR:$new, GPR:$addr)>;
2121+
def : Pat<(atomic_cmp_swap_i32_monotonic GPR:$addr, GPR:$cmp, GPR:$new),
2122+
(AMCAS_W GPR:$cmp, GPR:$new, GPR:$addr)>;
2123+
def : Pat<(atomic_cmp_swap_i64_monotonic GPR:$addr, GPR:$cmp, GPR:$new),
2124+
(AMCAS_D GPR:$cmp, GPR:$new, GPR:$addr)>;
2125+
2126+
def : Pat<(atomic_cmp_swap_i8 GPR:$addr, GPR:$cmp, GPR:$new),
2127+
(AMCAS__DB_B GPR:$cmp, GPR:$new, GPR:$addr)>;
2128+
def : Pat<(atomic_cmp_swap_i16 GPR:$addr, GPR:$cmp, GPR:$new),
2129+
(AMCAS__DB_H GPR:$cmp, GPR:$new, GPR:$addr)>;
2130+
def : Pat<(atomic_cmp_swap_i32 GPR:$addr, GPR:$cmp, GPR:$new),
2131+
(AMCAS__DB_W GPR:$cmp, GPR:$new, GPR:$addr)>;
2132+
def : Pat<(atomic_cmp_swap_i64 GPR:$addr, GPR:$cmp, GPR:$new),
2133+
(AMCAS__DB_D GPR:$cmp, GPR:$new, GPR:$addr)>;
2134+
}
21092135

21102136
let Predicates = [IsLA64] in {
21112137

0 commit comments

Comments
 (0)