https://github.com/tangaac updated https://github.com/llvm/llvm-project/pull/116764
>From 78e214321a273636f7cf4838f0b1ce04ba21d445 Mon Sep 17 00:00:00 2001 From: tangaac <tangya...@loongson.cn> Date: Tue, 19 Nov 2024 15:04:29 +0800 Subject: [PATCH 1/2] [LoongArch] Support LA V1.1 feature that div.w[u] and mod.w[u] instructions with inputs not signed-extended. --- clang/include/clang/Driver/Options.td | 4 +++ clang/lib/Basic/Targets/LoongArch.cpp | 7 ++++- clang/lib/Basic/Targets/LoongArch.h | 2 ++ .../lib/Driver/ToolChains/Arch/LoongArch.cpp | 9 ++++++ clang/test/Driver/loongarch-march.c | 8 ++--- clang/test/Driver/loongarch-mdiv32.c | 30 +++++++++++++++++++ clang/test/Preprocessor/init-loongarch.c | 25 +++++++++++----- .../TargetParser/LoongArchTargetParser.def | 3 +- .../llvm/TargetParser/LoongArchTargetParser.h | 3 ++ llvm/lib/Target/LoongArch/LoongArch.td | 9 +++++- .../LoongArch/LoongArchISelLowering.cpp | 16 ++++++++-- .../Target/LoongArch/LoongArchISelLowering.h | 2 ++ .../Target/LoongArch/LoongArchInstrInfo.td | 4 +++ .../TargetParser/LoongArchTargetParser.cpp | 1 + .../ir-instruction/sdiv-udiv-srem-urem.ll | 24 +++++++-------- 15 files changed, 118 insertions(+), 29 deletions(-) create mode 100644 clang/test/Driver/loongarch-mdiv32.c diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d7230dd7272fd6..e3358216b3db7e 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5416,6 +5416,10 @@ def mlam_bh : Flag<["-"], "mlam-bh">, Group<m_loongarch_Features_Group>, HelpText<"Enable amswap[_db].{b/h} and amadd[_db].{b/h}">; def mno_lam_bh : Flag<["-"], "mno-lam-bh">, Group<m_loongarch_Features_Group>, HelpText<"Disable amswap[_db].{b/h} and amadd[_db].{b/h}">; +def mdiv32 : Flag<["-"], "mdiv32">, Group<m_loongarch_Features_Group>, + HelpText<"Use div.w[u] and mod.w[u] instructions with input not sign-extended.">; +def mno_div32 : Flag<["-"], "mno-div32">, Group<m_loongarch_Features_Group>, + HelpText<"Do not use div.w[u] and mod.w[u] instructions with input not sign-extended.">; def mannotate_tablejump : Flag<["-"], "mannotate-tablejump">, Group<m_loongarch_Features_Group>, HelpText<"Enable annotate table jump instruction to correlate it with the jump table.">; def mno_annotate_tablejump : Flag<["-"], "mno-annotate-tablejump">, Group<m_loongarch_Features_Group>, diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index 07b22b35f603ce..2124d8e32ff607 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -205,7 +205,7 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, // TODO: As more features of the V1.1 ISA are supported, a unified "v1.1" // arch feature set will be used to include all sub-features belonging to // the V1.1 ISA version. - if (HasFeatureFrecipe && HasFeatureLAM_BH) + if (HasFeatureFrecipe && HasFeatureLAM_BH && HasFeatureDiv32) Builder.defineMacro("__loongarch_arch", Twine('"') + "la64v1.1" + Twine('"')); else @@ -239,6 +239,9 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, if (HasFeatureLAM_BH) Builder.defineMacro("__loongarch_lam_bh", Twine(1)); + if (HasFeatureDiv32) + Builder.defineMacro("__loongarch_div32", Twine(1)); + StringRef ABI = getABI(); if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s") Builder.defineMacro("__loongarch_lp64"); @@ -317,6 +320,8 @@ bool LoongArchTargetInfo::handleTargetFeatures( HasFeatureFrecipe = true; else if (Feature == "+lam-bh") HasFeatureLAM_BH = true; + else if (Feature == "+div32") + HasFeatureDiv32 = true; } return true; } diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index 3585e9f7968b4b..16ffb0eddf50da 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -31,6 +31,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { bool HasFeatureLASX; bool HasFeatureFrecipe; bool HasFeatureLAM_BH; + bool HasFeatureDiv32; public: LoongArchTargetInfo(const llvm::Triple &Triple, const TargetOptions &) @@ -41,6 +42,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { HasFeatureLASX = false; HasFeatureFrecipe = false; HasFeatureLAM_BH = false; + HasFeatureDiv32 = false; LongDoubleWidth = 128; LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad(); diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp index 987db4638fca88..3e85d4ad076ea5 100644 --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -274,6 +274,15 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, else Features.push_back("-lam-bh"); } + + // Select div32 feature determined by -m[no-]div32. + if (const Arg *A = + Args.getLastArg(options::OPT_mdiv32, options::OPT_mno_div32)) { + if (A->getOption().matches(options::OPT_mdiv32)) + Features.push_back("+div32"); + else + Features.push_back("-div32"); + } } std::string loongarch::postProcessTargetCPUString(const std::string &CPU, diff --git a/clang/test/Driver/loongarch-march.c b/clang/test/Driver/loongarch-march.c index d4cd5b07ae905f..c2b82bb71bec74 100644 --- a/clang/test/Driver/loongarch-march.c +++ b/clang/test/Driver/loongarch-march.c @@ -39,21 +39,21 @@ // CC1-LA64V1P1: "-target-cpu" "loongarch64" // CC1-LA64V1P1-NOT: "-target-feature" -// CC1-LA64V1P1: "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual" "-target-feature" "+frecipe" "-target-feature" "+lam-bh" +// CC1-LA64V1P1: "-target-feature" "+64bit" "-target-feature" "+d" "-target-feature" "+lsx" "-target-feature" "+ual" "-target-feature" "+frecipe" "-target-feature" "+lam-bh" "-target-feature" "+div32" // CC1-LA64V1P1-NOT: "-target-feature" // CC1-LA64V1P1: "-target-abi" "lp64d" // CC1-LA664: "-target-cpu" "la664" // CC1-LA664-NOT: "-target-feature" -// 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" +// 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" "+div32" // CC1-LA664-NOT: "-target-feature" // CC1-LA664: "-target-abi" "lp64d" // IR-LOONGARCH64: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+f,+ual" // IR-LA464: attributes #[[#]] ={{.*}}"target-cpu"="la464" {{.*}}"target-features"="+64bit,+d,+f,+lasx,+lsx,+ual" // IR-LA64V1P0: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+lsx,+ual" -// IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+frecipe,+lam-bh,+lsx,+ual" -// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" {{.*}}"target-features"="+64bit,+d,+f,+frecipe,+lam-bh,+lasx,+lsx,+ual" +// IR-LA64V1P1: attributes #[[#]] ={{.*}}"target-cpu"="loongarch64" {{.*}}"target-features"="+64bit,+d,+div32,+frecipe,+lam-bh,+lsx,+ual" +// IR-LA664: attributes #[[#]] ={{.*}}"target-cpu"="la664" {{.*}}"target-features"="+64bit,+d,+div32,+f,+frecipe,+lam-bh,+lasx,+lsx,+ual" int foo(void) { return 3; diff --git a/clang/test/Driver/loongarch-mdiv32.c b/clang/test/Driver/loongarch-mdiv32.c new file mode 100644 index 00000000000000..cf774b3818c55d --- /dev/null +++ b/clang/test/Driver/loongarch-mdiv32.c @@ -0,0 +1,30 @@ +/// Test -m[no]div32 options. + +// RUN: %clang --target=loongarch64 -mdiv32 -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-DIV32 +// RUN: %clang --target=loongarch64 -mno-div32 -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-NO-DIV32 +// RUN: %clang --target=loongarch64 -mno-div32 -mdiv32 -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-DIV32 +// RUN: %clang --target=loongarch64 -mdiv32 -mno-div32 -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-NO-DIV32 + +// RUN: %clang --target=loongarch64 -mdiv32 -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-DIV32 +// RUN: %clang --target=loongarch64 -mno-div32 -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-NO-DIV32 +// RUN: %clang --target=loongarch64 -mno-div32 -mdiv32 -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-DIV32 +// RUN: %clang --target=loongarch64 -mdiv32 -mno-div32 -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-NO-DIV32 + + +// CC1-DIV32: "-target-feature" "+div32" +// CC1-NO-DIV32: "-target-feature" "-div32" + +// IR-DIV32: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+div32{{(,.*)?}}" +// IR-NO-DIV32: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}-div32{{(,.*)?}}" + +int foo(void) { + return 42; +} diff --git a/clang/test/Preprocessor/init-loongarch.c b/clang/test/Preprocessor/init-loongarch.c index 8019292e0f10e0..8a3d3d5b023de7 100644 --- a/clang/test/Preprocessor/init-loongarch.c +++ b/clang/test/Preprocessor/init-loongarch.c @@ -798,7 +798,7 @@ // LA64-FPU0-LP64S-NOT: #define __loongarch_single_float // LA64-FPU0-LP64S: #define __loongarch_soft_float 1 -/// Check __loongarch_arch{_tune/_frecipe/_lam_bh}. +/// Check __loongarch_arch{_tune/_frecipe/_lam_bh/_div32}. // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - | \ // RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=loongarch64 %s @@ -823,11 +823,11 @@ // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx | \ // RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 | \ -// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH -DARCH=la64v1.1 -DTUNE=loongarch64 %s +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,DIV32 -DARCH=la64v1.1 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -frecipe | \ -// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAM-BH -DARCH=la64v1.0 -DTUNE=loongarch64 %s +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAM-BH,DIV32 -DARCH=la64v1.0 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -lsx | \ -// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH -DARCH=loongarch64 -DTUNE=loongarch64 %s +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,DIV32 -DARCH=loongarch64 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +frecipe | \ // RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=loongarch64 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +frecipe | \ @@ -835,23 +835,32 @@ // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 -Xclang -target-feature -Xclang +lam-bh | \ // RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAM-BH -DARCH=la64v1.0 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -lam-bh | \ -// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE -DARCH=la64v1.0 -DTUNE=loongarch64 %s +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,DIV32 -DARCH=la64v1.0 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lam-bh | \ // RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAM-BH -DARCH=loongarch64 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +lam-bh | \ // RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,LAM-BH -DARCH=la64v1.0 -DTUNE=loongarch64 %s -// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 -Xclang -target-feature -Xclang +frecipe -Xclang -target-feature -Xclang +lam-bh | \ +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.0 -Xclang -target-feature -Xclang +div32 | \ +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,DIV32 -DARCH=la64v1.0 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la64v1.1 -Xclang -target-feature -Xclang -div32| \ +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH -DARCH=la64v1.0 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +div32 | \ +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,DIV32 -DARCH=loongarch64 -DTUNE=loongarch64 %s +// RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -Xclang -target-feature -Xclang +lsx -Xclang -target-feature -Xclang +div32 | \ +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,DIV32 -DARCH=la64v1.0 -DTUNE=loongarch64 %s +// 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 +div32 | \ // RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE -DARCH=la64v1.1 -DTUNE=loongarch64 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la664 | \ -// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH -DARCH=la664 -DTUNE=la664 %s +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,DIV32 -DARCH=la664 -DTUNE=la664 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -mtune=la664 | \ // RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=la64v1.0 -DTUNE=la664 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=loongarch64 -mtune=la664 | \ // RUN: FileCheck --match-full-lines --check-prefix=ARCH-TUNE -DARCH=loongarch64 -DTUNE=la664 %s // RUN: %clang --target=loongarch64 -x c -E -dM %s -o - -march=la664 -mtune=loongarch64 | \ -// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH -DARCH=la664 -DTUNE=loongarch64 %s +// RUN: FileCheck --match-full-lines --check-prefixes=ARCH-TUNE,FRECIPE,LAM-BH,DIV32 -DARCH=la664 -DTUNE=loongarch64 %s // ARCH-TUNE: #define __loongarch_arch "[[ARCH]]" +// DIV32: #define __loongarch_div32 1 // FRECIPE: #define __loongarch_frecipe 1 // LAM-BH: #define __loongarch_lam_bh 1 // ARCH-TUNE: #define __loongarch_tune "[[TUNE]]" diff --git a/llvm/include/llvm/TargetParser/LoongArchTargetParser.def b/llvm/include/llvm/TargetParser/LoongArchTargetParser.def index 6cd2018b7b59cb..aecab7263c6cbf 100644 --- a/llvm/include/llvm/TargetParser/LoongArchTargetParser.def +++ b/llvm/include/llvm/TargetParser/LoongArchTargetParser.def @@ -12,6 +12,7 @@ LOONGARCH_FEATURE("+lvz", FK_LVZ) LOONGARCH_FEATURE("+ual", FK_UAL) LOONGARCH_FEATURE("+frecipe", FK_FRECIPE) LOONGARCH_FEATURE("+lam-bh", FK_LAM_BH) +LOONGARCH_FEATURE("+div32", FK_DIV32) #undef LOONGARCH_FEATURE @@ -21,6 +22,6 @@ LOONGARCH_FEATURE("+lam-bh", FK_LAM_BH) LOONGARCH_ARCH("loongarch64", AK_LOONGARCH64, FK_64BIT | FK_FP32 | FK_FP64 | FK_UAL) LOONGARCH_ARCH("la464", AK_LA464, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL) -LOONGARCH_ARCH("la664", AK_LA664, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL | FK_FRECIPE | FK_LAM_BH) +LOONGARCH_ARCH("la664", AK_LA664, FK_64BIT | FK_FP32 | FK_FP64 | FK_LSX | FK_LASX | FK_UAL | FK_FRECIPE | FK_LAM_BH | FK_DIV32) #undef LOONGARCH_ARCH diff --git a/llvm/include/llvm/TargetParser/LoongArchTargetParser.h b/llvm/include/llvm/TargetParser/LoongArchTargetParser.h index b5be03b1b67fbb..a0e21e4484ce39 100644 --- a/llvm/include/llvm/TargetParser/LoongArchTargetParser.h +++ b/llvm/include/llvm/TargetParser/LoongArchTargetParser.h @@ -53,6 +53,9 @@ enum FeatureKind : uint32_t { // Atomic memory swap and add instructions for byte and half word are // available. FK_LAM_BH = 1 << 10, + + // Assume div.w[u] and mod.w[u] can handle inputs that are not sign-extended. + FK_DIV32 = 1 << 13, }; struct FeatureInfo { diff --git a/llvm/lib/Target/LoongArch/LoongArch.td b/llvm/lib/Target/LoongArch/LoongArch.td index ecd00cd6d5d619..cdab5a736bd693 100644 --- a/llvm/lib/Target/LoongArch/LoongArch.td +++ b/llvm/lib/Target/LoongArch/LoongArch.td @@ -118,6 +118,12 @@ def FeatureLAM_BH "Support amswap[_db].{b/h} and amadd[_db].{b/h} instructions.">; def HasLAM_BH : Predicate<"Subtarget->hasLAM_BH()">; +// Assume div.w[u] and mod.w[u] can handle inputs that are not sign-extended. +def FeatureDiv32 + : SubtargetFeature<"div32", "HasDiv32", "true", + "Support div.w[u] and mod.w[u] can handle inputs that are not sign-extended">; +def HasDiv32 : Predicate<"Subtarget->hasDiv32()">; + def TunePreferWInst : SubtargetFeature<"prefer-w-inst", "PreferWInst", "true", "Prefer instructions with W suffix">; @@ -160,7 +166,8 @@ def : ProcessorModel<"la664", NoSchedModel, [Feature64Bit, FeatureExtLVZ, FeatureExtLBT, FeatureFrecipe, - FeatureLAM_BH]>; + FeatureLAM_BH, + FeatureDiv32]>; //===----------------------------------------------------------------------===// // Define the LoongArch target. diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp index 5c567ed4a6f724..9fb59a11bb9caf 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.cpp @@ -141,7 +141,8 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM, setOperationAction(ISD::BITREVERSE, MVT::i32, Custom); setOperationAction(ISD::BSWAP, MVT::i32, Custom); - setOperationAction({ISD::UDIV, ISD::UREM}, MVT::i32, Custom); + setOperationAction({ISD::SDIV, ISD::UDIV, ISD::SREM, ISD::UREM}, MVT::i32, + Custom); setOperationAction(ISD::LROUND, MVT::i32, Custom); } @@ -2629,8 +2630,12 @@ static LoongArchISD::NodeType getLoongArchWOpcode(unsigned Opcode) { switch (Opcode) { default: llvm_unreachable("Unexpected opcode"); + case ISD::SDIV: + return LoongArchISD::DIV_W; case ISD::UDIV: return LoongArchISD::DIV_WU; + case ISD::SREM: + return LoongArchISD::MOD_W; case ISD::UREM: return LoongArchISD::MOD_WU; case ISD::SHL: @@ -2827,11 +2832,16 @@ void LoongArchTargetLowering::ReplaceNodeResults( "Unexpected custom legalisation"); Results.push_back(customLegalizeToWOpWithSExt(N, DAG)); break; + case ISD::SDIV: case ISD::UDIV: + case ISD::SREM: case ISD::UREM: assert(VT == MVT::i32 && Subtarget.is64Bit() && "Unexpected custom legalisation"); - Results.push_back(customLegalizeToWOp(N, DAG, 2, ISD::SIGN_EXTEND)); + Results.push_back(customLegalizeToWOp(N, DAG, 2, + Subtarget.hasDiv32() && VT == MVT::i32 + ? ISD::ANY_EXTEND + : ISD::SIGN_EXTEND)); break; case ISD::SHL: case ISD::SRA: @@ -4667,7 +4677,9 @@ const char *LoongArchTargetLowering::getTargetNodeName(unsigned Opcode) const { NODE_NAME_CASE(BITREV_W) NODE_NAME_CASE(ROTR_W) NODE_NAME_CASE(ROTL_W) + NODE_NAME_CASE(DIV_W) NODE_NAME_CASE(DIV_WU) + NODE_NAME_CASE(MOD_W) NODE_NAME_CASE(MOD_WU) NODE_NAME_CASE(CLZ_W) NODE_NAME_CASE(CTZ_W) diff --git a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h index 1aa686695b49b8..5a47dfb257175f 100644 --- a/llvm/lib/Target/LoongArch/LoongArchISelLowering.h +++ b/llvm/lib/Target/LoongArch/LoongArchISelLowering.h @@ -44,6 +44,8 @@ enum NodeType : unsigned { ROTR_W, // unsigned 32-bit integer division + DIV_W, + MOD_W, DIV_WU, MOD_WU, diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td index 3de20d6e599dbf..1a7165015a86d9 100644 --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -85,7 +85,9 @@ def loongarch_sll_w : SDNode<"LoongArchISD::SLL_W", SDT_LoongArchIntBinOpW>; def loongarch_sra_w : SDNode<"LoongArchISD::SRA_W", SDT_LoongArchIntBinOpW>; def loongarch_srl_w : SDNode<"LoongArchISD::SRL_W", SDT_LoongArchIntBinOpW>; def loongarch_rotr_w : SDNode<"LoongArchISD::ROTR_W", SDT_LoongArchIntBinOpW>; +def loongarch_div_w : SDNode<"LoongArchISD::DIV_W", SDT_LoongArchIntBinOpW>; def loongarch_div_wu : SDNode<"LoongArchISD::DIV_WU", SDT_LoongArchIntBinOpW>; +def loongarch_mod_w : SDNode<"LoongArchISD::MOD_W", SDT_LoongArchIntBinOpW>; def loongarch_mod_wu : SDNode<"LoongArchISD::MOD_WU", SDT_LoongArchIntBinOpW>; def loongarch_crc_w_b_w : SDNode<"LoongArchISD::CRC_W_B_W", SDT_LoongArchIntBinOpW, [SDNPHasChain]>; @@ -1144,10 +1146,12 @@ def : PatGprGpr<sub, SUB_D>; def : PatGprGpr<sdiv, DIV_D>; def : PatGprGpr_32<sdiv, DIV_W>; def : PatGprGpr<udiv, DIV_DU>; +def : PatGprGpr<loongarch_div_w, DIV_W>; def : PatGprGpr<loongarch_div_wu, DIV_WU>; def : PatGprGpr<srem, MOD_D>; def : PatGprGpr_32<srem, MOD_W>; def : PatGprGpr<urem, MOD_DU>; +def : PatGprGpr<loongarch_mod_w, MOD_W>; def : PatGprGpr<loongarch_mod_wu, MOD_WU>; def : PatGprGpr<shiftop<rotr>, ROTR_D>; def : PatGprGpr<shiftopw<loongarch_rotr_w>, ROTR_W>; diff --git a/llvm/lib/TargetParser/LoongArchTargetParser.cpp b/llvm/lib/TargetParser/LoongArchTargetParser.cpp index 27e3b5683c5a6e..930a6d1c35ddd2 100644 --- a/llvm/lib/TargetParser/LoongArchTargetParser.cpp +++ b/llvm/lib/TargetParser/LoongArchTargetParser.cpp @@ -53,6 +53,7 @@ bool LoongArch::getArchFeatures(StringRef Arch, if (Arch == "la64v1.1") { Features.push_back("+frecipe"); Features.push_back("+lam-bh"); + Features.push_back("+div32"); } return true; } diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll index c5af79157eaadc..99824f6d7718e7 100644 --- a/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem.ll @@ -121,7 +121,7 @@ define i32 @sdiv_i32(i32 %a, i32 %b) { ; LA64: # %bb.0: # %entry ; LA64-NEXT: addi.w $a1, $a1, 0 ; LA64-NEXT: addi.w $a0, $a0, 0 -; LA64-NEXT: div.d $a0, $a0, $a1 +; LA64-NEXT: div.w $a0, $a0, $a1 ; LA64-NEXT: ret ; ; LA32-TRAP-LABEL: sdiv_i32: @@ -137,7 +137,7 @@ define i32 @sdiv_i32(i32 %a, i32 %b) { ; LA64-TRAP: # %bb.0: # %entry ; LA64-TRAP-NEXT: addi.w $a1, $a1, 0 ; LA64-TRAP-NEXT: addi.w $a0, $a0, 0 -; LA64-TRAP-NEXT: div.d $a0, $a0, $a1 +; LA64-TRAP-NEXT: div.w $a0, $a0, $a1 ; LA64-TRAP-NEXT: bnez $a1, .LBB3_2 ; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 @@ -156,7 +156,7 @@ define i32 @sdiv_ui32_si32_si32(i32 signext %a, i32 signext %b) { ; ; LA64-LABEL: sdiv_ui32_si32_si32: ; LA64: # %bb.0: # %entry -; LA64-NEXT: div.d $a0, $a0, $a1 +; LA64-NEXT: div.w $a0, $a0, $a1 ; LA64-NEXT: ret ; ; LA32-TRAP-LABEL: sdiv_ui32_si32_si32: @@ -170,7 +170,7 @@ define i32 @sdiv_ui32_si32_si32(i32 signext %a, i32 signext %b) { ; ; LA64-TRAP-LABEL: sdiv_ui32_si32_si32: ; LA64-TRAP: # %bb.0: # %entry -; LA64-TRAP-NEXT: div.d $a0, $a0, $a1 +; LA64-TRAP-NEXT: div.w $a0, $a0, $a1 ; LA64-TRAP-NEXT: bnez $a1, .LBB4_2 ; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 @@ -693,7 +693,7 @@ define i32 @srem_i32(i32 %a, i32 %b) { ; LA64: # %bb.0: # %entry ; LA64-NEXT: addi.w $a1, $a1, 0 ; LA64-NEXT: addi.w $a0, $a0, 0 -; LA64-NEXT: mod.d $a0, $a0, $a1 +; LA64-NEXT: mod.w $a0, $a0, $a1 ; LA64-NEXT: ret ; ; LA32-TRAP-LABEL: srem_i32: @@ -709,7 +709,7 @@ define i32 @srem_i32(i32 %a, i32 %b) { ; LA64-TRAP: # %bb.0: # %entry ; LA64-TRAP-NEXT: addi.w $a1, $a1, 0 ; LA64-TRAP-NEXT: addi.w $a0, $a0, 0 -; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 +; LA64-TRAP-NEXT: mod.w $a0, $a0, $a1 ; LA64-TRAP-NEXT: bnez $a1, .LBB19_2 ; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 @@ -728,7 +728,7 @@ define i32 @srem_ui32_si32_si32(i32 signext %a, i32 signext %b) { ; ; LA64-LABEL: srem_ui32_si32_si32: ; LA64: # %bb.0: # %entry -; LA64-NEXT: mod.d $a0, $a0, $a1 +; LA64-NEXT: mod.w $a0, $a0, $a1 ; LA64-NEXT: ret ; ; LA32-TRAP-LABEL: srem_ui32_si32_si32: @@ -742,7 +742,7 @@ define i32 @srem_ui32_si32_si32(i32 signext %a, i32 signext %b) { ; ; LA64-TRAP-LABEL: srem_ui32_si32_si32: ; LA64-TRAP: # %bb.0: # %entry -; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 +; LA64-TRAP-NEXT: mod.w $a0, $a0, $a1 ; LA64-TRAP-NEXT: bnez $a1, .LBB20_2 ; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 @@ -763,7 +763,7 @@ define signext i32 @srem_si32_ui32_ui32(i32 %a, i32 %b) { ; LA64: # %bb.0: # %entry ; LA64-NEXT: addi.w $a1, $a1, 0 ; LA64-NEXT: addi.w $a0, $a0, 0 -; LA64-NEXT: mod.d $a0, $a0, $a1 +; LA64-NEXT: mod.w $a0, $a0, $a1 ; LA64-NEXT: ret ; ; LA32-TRAP-LABEL: srem_si32_ui32_ui32: @@ -779,7 +779,7 @@ define signext i32 @srem_si32_ui32_ui32(i32 %a, i32 %b) { ; LA64-TRAP: # %bb.0: # %entry ; LA64-TRAP-NEXT: addi.w $a1, $a1, 0 ; LA64-TRAP-NEXT: addi.w $a0, $a0, 0 -; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 +; LA64-TRAP-NEXT: mod.w $a0, $a0, $a1 ; LA64-TRAP-NEXT: bnez $a1, .LBB21_2 ; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 @@ -798,7 +798,7 @@ define signext i32 @srem_si32_si32_si32(i32 signext %a, i32 signext %b) { ; ; LA64-LABEL: srem_si32_si32_si32: ; LA64: # %bb.0: # %entry -; LA64-NEXT: mod.d $a0, $a0, $a1 +; LA64-NEXT: mod.w $a0, $a0, $a1 ; LA64-NEXT: ret ; ; LA32-TRAP-LABEL: srem_si32_si32_si32: @@ -812,7 +812,7 @@ define signext i32 @srem_si32_si32_si32(i32 signext %a, i32 signext %b) { ; ; LA64-TRAP-LABEL: srem_si32_si32_si32: ; LA64-TRAP: # %bb.0: # %entry -; LA64-TRAP-NEXT: mod.d $a0, $a0, $a1 +; LA64-TRAP-NEXT: mod.w $a0, $a0, $a1 ; LA64-TRAP-NEXT: bnez $a1, .LBB22_2 ; LA64-TRAP-NEXT: # %bb.1: # %entry ; LA64-TRAP-NEXT: break 7 >From cffa8d88a6d36e1aedcb1f60622b7c2d5681b303 Mon Sep 17 00:00:00 2001 From: tangaac <tangya...@loongson.cn> Date: Wed, 20 Nov 2024 14:36:37 +0800 Subject: [PATCH 2/2] add a test --- .../sdiv-udiv-srem-urem-div32.ll | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem-div32.ll diff --git a/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem-div32.ll b/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem-div32.ll new file mode 100644 index 00000000000000..d22b4e9c30fd61 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/ir-instruction/sdiv-udiv-srem-urem-div32.ll @@ -0,0 +1,75 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc --mtriple=loongarch64 -mattr=+d,-div32 < %s | FileCheck %s --check-prefix=LA64 +; RUN: llc --mtriple=loongarch64 -mattr=+d,+div32 < %s | FileCheck %s --check-prefix=LA64-DIV32 + +define dso_local noundef signext i32 @divw(i64 noundef %0, i64 noundef %1) local_unnamed_addr #0 { +; LA64-LABEL: divw: +; LA64: # %bb.0: +; LA64-NEXT: addi.w $a1, $a1, 0 +; LA64-NEXT: addi.w $a0, $a0, 0 +; LA64-NEXT: div.w $a0, $a0, $a1 +; LA64-NEXT: ret +; +; LA64-DIV32-LABEL: divw: +; LA64-DIV32: # %bb.0: +; LA64-DIV32-NEXT: div.w $a0, $a0, $a1 +; LA64-DIV32-NEXT: ret + %3 = trunc i64 %0 to i32 + %4 = trunc i64 %1 to i32 + %5 = sdiv i32 %3, %4 + ret i32 %5 +} + +define dso_local noundef signext i32 @divwu(i64 noundef %0, i64 noundef %1) local_unnamed_addr #0 { +; LA64-LABEL: divwu: +; LA64: # %bb.0: +; LA64-NEXT: addi.w $a1, $a1, 0 +; LA64-NEXT: addi.w $a0, $a0, 0 +; LA64-NEXT: div.wu $a0, $a0, $a1 +; LA64-NEXT: ret +; +; LA64-DIV32-LABEL: divwu: +; LA64-DIV32: # %bb.0: +; LA64-DIV32-NEXT: div.wu $a0, $a0, $a1 +; LA64-DIV32-NEXT: ret + %3 = trunc i64 %0 to i32 + %4 = trunc i64 %1 to i32 + %5 = udiv i32 %3, %4 + ret i32 %5 +} + +define dso_local signext range(i32 -2147483647, -2147483648) i32 @modw(i64 noundef %0, i64 noundef %1) local_unnamed_addr #0 { +; LA64-LABEL: modw: +; LA64: # %bb.0: +; LA64-NEXT: addi.w $a1, $a1, 0 +; LA64-NEXT: addi.w $a0, $a0, 0 +; LA64-NEXT: mod.w $a0, $a0, $a1 +; LA64-NEXT: ret +; +; LA64-DIV32-LABEL: modw: +; LA64-DIV32: # %bb.0: +; LA64-DIV32-NEXT: mod.w $a0, $a0, $a1 +; LA64-DIV32-NEXT: ret + %3 = trunc i64 %0 to i32 + %4 = trunc i64 %1 to i32 + %5 = srem i32 %3, %4 + ret i32 %5 +} + +define dso_local signext range(i32 0, -1) i32 @modwu(i64 noundef %0, i64 noundef %1) local_unnamed_addr #0 { +; LA64-LABEL: modwu: +; LA64: # %bb.0: +; LA64-NEXT: addi.w $a1, $a1, 0 +; LA64-NEXT: addi.w $a0, $a0, 0 +; LA64-NEXT: mod.wu $a0, $a0, $a1 +; LA64-NEXT: ret +; +; LA64-DIV32-LABEL: modwu: +; LA64-DIV32: # %bb.0: +; LA64-DIV32-NEXT: mod.wu $a0, $a0, $a1 +; LA64-DIV32-NEXT: ret + %3 = trunc i64 %0 to i32 + %4 = trunc i64 %1 to i32 + %5 = urem i32 %3, %4 + ret i32 %5 +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits