Skip to content

Commit f4379db

Browse files
authored
[LoongArch] Support LA V1.1 feature that div.w[u] and mod.w[u] instructions with inputs not signed-extended. (#116764)
Two options for clang -mdiv32: Use div.w[u] and mod.w[u] instructions with input not sign-extended. -mno-div32: Do not use div.w[u] and mod.w[u] instructions with input not sign-extended. The default is -mno-div32.
1 parent 46fcdbb commit f4379db

File tree

14 files changed

+173
-18
lines changed

14 files changed

+173
-18
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5417,6 +5417,10 @@ def mld_seq_sa : Flag<["-"], "mld-seq-sa">, Group<m_loongarch_Features_Group>,
54175417
HelpText<"Do not generate load-load barrier instructions (dbar 0x700)">;
54185418
def mno_ld_seq_sa : Flag<["-"], "mno-ld-seq-sa">, Group<m_loongarch_Features_Group>,
54195419
HelpText<"Generate load-load barrier instructions (dbar 0x700)">;
5420+
def mdiv32 : Flag<["-"], "mdiv32">, Group<m_loongarch_Features_Group>,
5421+
HelpText<"Use div.w[u] and mod.w[u] instructions with input not sign-extended.">;
5422+
def mno_div32 : Flag<["-"], "mno-div32">, Group<m_loongarch_Features_Group>,
5423+
HelpText<"Do not use div.w[u] and mod.w[u] instructions with input not sign-extended.">;
54205424
def mannotate_tablejump : Flag<["-"], "mannotate-tablejump">, Group<m_loongarch_Features_Group>,
54215425
HelpText<"Enable annotate table jump instruction to correlate it with the jump table.">;
54225426
def mno_annotate_tablejump : Flag<["-"], "mno-annotate-tablejump">, Group<m_loongarch_Features_Group>,

clang/lib/Basic/Targets/LoongArch.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ 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 && HasFeatureLD_SEQ_SA)
208+
if (HasFeatureFrecipe && HasFeatureLAM_BH && HasFeatureLD_SEQ_SA &&
209+
HasFeatureDiv32)
209210
Builder.defineMacro("__loongarch_arch",
210211
Twine('"') + "la64v1.1" + Twine('"'));
211212
else
@@ -242,6 +243,9 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts,
242243
if (HasFeatureLD_SEQ_SA)
243244
Builder.defineMacro("__loongarch_ld_seq_sa", Twine(1));
244245

246+
if (HasFeatureDiv32)
247+
Builder.defineMacro("__loongarch_div32", Twine(1));
248+
245249
StringRef ABI = getABI();
246250
if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s")
247251
Builder.defineMacro("__loongarch_lp64");
@@ -322,6 +326,8 @@ bool LoongArchTargetInfo::handleTargetFeatures(
322326
HasFeatureLAM_BH = true;
323327
else if (Feature == "+ld-seq-sa")
324328
HasFeatureLD_SEQ_SA = true;
329+
else if (Feature == "+div32")
330+
HasFeatureDiv32 = true;
325331
}
326332
return true;
327333
}

clang/lib/Basic/Targets/LoongArch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
3232
bool HasFeatureFrecipe;
3333
bool HasFeatureLAM_BH;
3434
bool HasFeatureLD_SEQ_SA;
35+
bool HasFeatureDiv32;
3536

3637
public:
3738
LoongArchTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
@@ -43,6 +44,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
4344
HasFeatureFrecipe = false;
4445
HasFeatureLAM_BH = false;
4546
HasFeatureLD_SEQ_SA = false;
47+
HasFeatureDiv32 = false;
4648
LongDoubleWidth = 128;
4749
LongDoubleAlign = 128;
4850
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
@@ -283,6 +283,15 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D,
283283
else
284284
Features.push_back("-ld-seq-sa");
285285
}
286+
287+
// Select div32 feature determined by -m[no-]div32.
288+
if (const Arg *A =
289+
Args.getLastArg(options::OPT_mdiv32, options::OPT_mno_div32)) {
290+
if (A->getOption().matches(options::OPT_mdiv32))
291+
Features.push_back("+div32");
292+
else
293+
Features.push_back("-div32");
294+
}
286295
}
287296

288297
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" "-target-feature" "+ld-seq-sa"
42+
// CC1-LA64V1P1: "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual" "-target-feature" "+frecipe" "-target-feature" "+lam-bh" "-target-feature" "+ld-seq-sa" "-target-feature" "+div32"
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" "-target-feature" "+ld-seq-sa"
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" "+ld-seq-sa" "-target-feature" "+div32"
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,+ld-seq-sa,+lsx,+ual"
56-
// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" {{.*}}"target-features"="+64bit,+d,+f,+frecipe,+lam-bh,+lasx,+ld-seq-sa,+lsx,+ual"
55+
// IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+div32,+frecipe,+lam-bh,+ld-seq-sa,+lsx,+ual"
56+
// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" {{.*}}"target-features"="+64bit,+d,+div32,+f,+frecipe,+lam-bh,+lasx,+ld-seq-sa,+lsx,+ual"
5757

5858
int foo(void) {
5959
return 3;

clang/test/Driver/loongarch-mdiv32.c

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

clang/test/Preprocessor/init-loongarch.c

Lines changed: 18 additions & 9 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/_ld_seq_sa}.
801+
/// Check __loongarch_arch{_tune/_frecipe/_lam_bh/_ld_seq_sa/_div32}.
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,43 +823,52 @@
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,LD-SEQ-SA -DARCH=la64v1.1 -DTUNE=loongarch64 %s
826+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,LD-SEQ-SA,DIV32 -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,LD-SEQ-SA -DARCH=la64v1.0 -DTUNE=loongarch64 %s
828+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAM-BH,LD-SEQ-SA,DIV32 -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,LD-SEQ-SA -DARCH=loongarch64 -DTUNE=loongarch64 %s
830+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,LD-SEQ-SA,DIV32 -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,LD-SEQ-SA -DARCH=la64v1.0 -DTUNE=loongarch64 %s
838+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LD-SEQ-SA,DIV32 -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
843843
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 -Xclang -target-feature -Xclang +ld-seq-sa | \
844844
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LD-SEQ-SA -DARCH=la64v1.0 -DTUNE=loongarch64 %s
845845
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -ld-seq-sa | \
846-
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH -DARCH=la64v1.0 -DTUNE=loongarch64 %s
846+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,DIV32 -DARCH=la64v1.0 -DTUNE=loongarch64 %s
847847
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +ld-seq-sa | \
848848
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LD-SEQ-SA -DARCH=loongarch64 -DTUNE=loongarch64 %s
849849
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +ld-seq-sa | \
850850
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LD-SEQ-SA -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 +ld-seq-sa | \
851+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 -Xclang -target-feature -Xclang +div32 | \
852+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,DIV32 -DARCH=la64v1.0 -DTUNE=loongarch64 %s
853+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -div32| \
854+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,LD-SEQ-SA -DARCH=la64v1.0 -DTUNE=loongarch64 %s
855+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +div32 | \
856+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,DIV32 -DARCH=loongarch64 -DTUNE=loongarch64 %s
857+
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +div32 | \
858+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,DIV32 -DARCH=la64v1.0 -DTUNE=loongarch64 %s
859+
// 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 +ld-seq-sa -Xclang -target-feature -Xclang +div32 | \
852860
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE -DARCH=la64v1.1 -DTUNE=loongarch64 %s
853861
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la664 | \
854-
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,LD-SEQ-SA -DARCH=la664 -DTUNE=la664 %s
862+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,LD-SEQ-SA,DIV32 -DARCH=la664 -DTUNE=la664 %s
855863
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=la664 | \
856864
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=la664 %s
857865
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -mtune=la664 | \
858866
// RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la664 %s
859867
// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la664 -mtune=loongarch64 | \
860-
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,LD-SEQ-SA -DARCH=la664 -DTUNE=loongarch64 %s
868+
// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,LD-SEQ-SA,DIV32 -DARCH=la664 -DTUNE=loongarch64 %s
861869

862870
// ARCH-TUNE: #define __loongarch_arch "[[ARCH]]"
871+
// DIV32: #define __loongarch_div32 1
863872
// FRECIPE: #define __loongarch_frecipe 1
864873
// LAM-BH: #define __loongarch_lam_bh 1
865874
// LD-SEQ-SA: #define __loongarch_ld_seq_sa 1

llvm/include/llvm/TargetParser/LoongArchTargetParser.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ LOONGARCH_FEATURE("+ual", FK_UAL)
1313
LOONGARCH_FEATURE("+frecipe", FK_FRECIPE)
1414
LOONGARCH_FEATURE("+lam-bh", FK_LAM_BH)
1515
LOONGARCH_FEATURE("+ld-seq-sa", FK_LD_SEQ_SA)
16+
LOONGARCH_FEATURE("+div32", FK_DIV32)
1617

1718
#undef LOONGARCH_FEATURE
1819

@@ -22,6 +23,6 @@ LOONGARCH_FEATURE("+ld-seq-sa", FK_LD_SEQ_SA)
2223

2324
LOONGARCH_ARCH("loongarch64", AK_LOONGARCH64, FK_64BIT | FK_FP32 | FK_FP64 | FK_UAL)
2425
LOONGARCH_ARCH("la464", AK_LA464, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL)
25-
LOONGARCH_ARCH("la664", AK_LA664, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL | FK_FRECIPE | FK_LAM_BH | FK_LD_SEQ_SA)
26+
LOONGARCH_ARCH("la664", AK_LA664, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL | FK_FRECIPE | FK_LAM_BH | FK_LD_SEQ_SA | FK_DIV32)
2627

2728
#undef LOONGARCH_ARCH

llvm/include/llvm/TargetParser/LoongArchTargetParser.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ enum FeatureKind : uint32_t {
5757
// Do not generate load-load barrier instructions (dbar 0x700).
5858
FK_LD_SEQ_SA = 1 << 12,
5959

60+
// Assume div.w[u] and mod.w[u] can handle inputs that are not sign-extended.
61+
FK_DIV32 = 1 << 13,
6062
};
6163

6264
struct FeatureInfo {

llvm/lib/Target/LoongArch/LoongArch.td

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ def FeatureLD_SEQ_SA
123123
"Don't use load-load barrier (dbar 0x700).">;
124124
def HasLD_SEQ_SA : Predicate<"Subtarget->hasLD_SEQ_SA()">;
125125

126+
// Assume div.w[u] and mod.w[u] can handle inputs that are not sign-extended.
127+
def FeatureDiv32
128+
: SubtargetFeature<"div32", "HasDiv32", "true",
129+
"Assume div.w[u] and mod.w[u] can handle inputs that are not sign-extended">;
130+
def HasDiv32 : Predicate<"Subtarget->hasDiv32()">;
131+
126132
def TunePreferWInst
127133
: SubtargetFeature<"prefer-w-inst", "PreferWInst", "true",
128134
"Prefer instructions with W suffix">;
@@ -165,7 +171,8 @@ def : ProcessorModel<"la664", NoSchedModel, [Feature64Bit,
165171
FeatureExtLVZ,
166172
FeatureExtLBT,
167173
FeatureFrecipe,
168-
FeatureLAM_BH]>;
174+
FeatureLAM_BH,
175+
FeatureDiv32]>;
169176

170177
//===----------------------------------------------------------------------===//
171178
// Define the LoongArch target.

llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2833,7 +2833,10 @@ void LoongArchTargetLowering::ReplaceNodeResults(
28332833
case ISD::UREM:
28342834
assert(VT == MVT::i32 && Subtarget.is64Bit() &&
28352835
"Unexpected custom legalisation");
2836-
Results.push_back(customLegalizeToWOp(N, DAG, 2, ISD::SIGN_EXTEND));
2836+
Results.push_back(customLegalizeToWOp(N, DAG, 2,
2837+
Subtarget.hasDiv32() && VT == MVT::i32
2838+
? ISD::ANY_EXTEND
2839+
: ISD::SIGN_EXTEND));
28372840
break;
28382841
case ISD::SHL:
28392842
case ISD::SRA:

llvm/lib/TargetParser/Host.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2025,12 +2025,12 @@ const StringMap<bool> sys::getHostCPUFeatures() {
20252025
Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ
20262026

20272027
Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE
2028+
Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32
20282029
Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH
20292030

20302031
Features["ld-seq-sa"] = cpucfg3 & (1U << 23); // CPUCFG.3.LD_SEQ_SA
20312032

20322033
// TODO: Need to complete.
2033-
// Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32
20342034
// Features["lamcas"] = cpucfg2 & (1U << 28); // CPUCFG.2.LAMCAS
20352035
// Features["llacq-screl"] = cpucfg2 & (1U << 29); // CPUCFG.2.LLACQ_SCREL
20362036
// Features["scq"] = cpucfg2 & (1U << 30); // CPUCFG.2.SCQ

llvm/lib/TargetParser/LoongArchTargetParser.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ bool LoongArch::getArchFeatures(StringRef Arch,
5454
Features.push_back("+frecipe");
5555
Features.push_back("+lam-bh");
5656
Features.push_back("+ld-seq-sa");
57+
Features.push_back("+div32");
5758
}
5859
return true;
5960
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc --mtriple=loongarch64 -mattr=+d,-div32 < %s | FileCheck %s --check-prefix=LA64
3+
; RUN: llc --mtriple=loongarch64 -mattr=+d,+div32 < %s | FileCheck %s --check-prefix=LA64-DIV32
4+
5+
; TODO: Use div.w/mod.w for sdiv/srem i32
6+
7+
define i32 @divw(i64 %a, i64 %b) {
8+
; LA64-LABEL: divw:
9+
; LA64: # %bb.0:
10+
; LA64-NEXT: addi.w $a0, $a0, 0
11+
; LA64-NEXT: addi.w $a1, $a1, 0
12+
; LA64-NEXT: div.d $a0, $a0, $a1
13+
; LA64-NEXT: ret
14+
;
15+
; LA64-DIV32-LABEL: divw:
16+
; LA64-DIV32: # %bb.0:
17+
; LA64-DIV32-NEXT: addi.w $a0, $a0, 0
18+
; LA64-DIV32-NEXT: addi.w $a1, $a1, 0
19+
; LA64-DIV32-NEXT: div.d $a0, $a0, $a1
20+
; LA64-DIV32-NEXT: ret
21+
%conv1 = trunc i64 %a to i32
22+
%conv2 = trunc i64 %b to i32
23+
%r = sdiv i32 %conv1, %conv2
24+
ret i32 %r
25+
}
26+
27+
define i32 @divwu(i64 %a, i64 %b) {
28+
; LA64-LABEL: divwu:
29+
; LA64: # %bb.0:
30+
; LA64-NEXT: addi.w $a1, $a1, 0
31+
; LA64-NEXT: addi.w $a0, $a0, 0
32+
; LA64-NEXT: div.wu $a0, $a0, $a1
33+
; LA64-NEXT: ret
34+
;
35+
; LA64-DIV32-LABEL: divwu:
36+
; LA64-DIV32: # %bb.0:
37+
; LA64-DIV32-NEXT: div.wu $a0, $a0, $a1
38+
; LA64-DIV32-NEXT: ret
39+
%conv1 = trunc i64 %a to i32
40+
%conv2 = trunc i64 %b to i32
41+
%r = udiv i32 %conv1, %conv2
42+
ret i32 %r
43+
}
44+
45+
define i32 @modw(i64 %a, i64 %b) {
46+
; LA64-LABEL: modw:
47+
; LA64: # %bb.0:
48+
; LA64-NEXT: addi.w $a0, $a0, 0
49+
; LA64-NEXT: addi.w $a1, $a1, 0
50+
; LA64-NEXT: mod.d $a0, $a0, $a1
51+
; LA64-NEXT: ret
52+
;
53+
; LA64-DIV32-LABEL: modw:
54+
; LA64-DIV32: # %bb.0:
55+
; LA64-DIV32-NEXT: addi.w $a0, $a0, 0
56+
; LA64-DIV32-NEXT: addi.w $a1, $a1, 0
57+
; LA64-DIV32-NEXT: mod.d $a0, $a0, $a1
58+
; LA64-DIV32-NEXT: ret
59+
%conv1 = trunc i64 %a to i32
60+
%conv2 = trunc i64 %b to i32
61+
%r = srem i32 %conv1, %conv2
62+
ret i32 %r
63+
}
64+
65+
define i32 @modwu(i64 %a, i64 %b) {
66+
; LA64-LABEL: modwu:
67+
; LA64: # %bb.0:
68+
; LA64-NEXT: addi.w $a1, $a1, 0
69+
; LA64-NEXT: addi.w $a0, $a0, 0
70+
; LA64-NEXT: mod.wu $a0, $a0, $a1
71+
; LA64-NEXT: ret
72+
;
73+
; LA64-DIV32-LABEL: modwu:
74+
; LA64-DIV32: # %bb.0:
75+
; LA64-DIV32-NEXT: mod.wu $a0, $a0, $a1
76+
; LA64-DIV32-NEXT: ret
77+
%conv1 = trunc i64 %a to i32
78+
%conv2 = trunc i64 %b to i32
79+
%r = urem i32 %conv1, %conv2
80+
ret i32 %r
81+
}

0 commit comments

Comments
 (0)