diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index c0ccd64a2a7b8..676f1a62b49dd 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -765,6 +765,12 @@ def warn_drv_loongarch_conflicting_implied_val : Warning< InGroup; def err_drv_loongarch_invalid_mfpu_EQ : Error< "invalid argument '%0' to -mfpu=; must be one of: 64, 32, none, 0 (alias for none)">; +def err_drv_loongarch_wrong_fpu_width_for_lsx : Error< + "wrong fpu width; LSX depends on 64-bit FPU.">; +def err_drv_loongarch_wrong_fpu_width_for_lasx : Error< + "wrong fpu width; LASX depends on 64-bit FPU.">; +def err_drv_loongarch_invalid_simd_option_combination : Error< + "invalid option combination; LASX depends on LSX.">; def err_drv_expand_response_file : Error< "failed to expand response file: %0">; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 7f3f5125d42e7..c8b730e0f7ecd 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -208,6 +208,8 @@ def m_riscv_Features_Group : OptionGroup<"">, Group, DocName<"RISC-V">; def m_ve_Features_Group : OptionGroup<"">, Group, DocName<"VE">; +def m_loongarch_Features_Group : OptionGroup<"">, + Group, DocName<"LoongArch">; def m_libc_Group : OptionGroup<"">, Group, Flags<[HelpHidden]>; @@ -4886,6 +4888,14 @@ def mstack_protector_guard_reg_EQ : Joined<["-"], "mstack-protector-guard-reg="> def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at function entry (x86/SystemZ only)">, Visibility<[ClangOption, CC1Option]>, Group, MarshallingInfoFlag>; +def mlsx : Flag<["-"], "mlsx">, Group, + HelpText<"Enable Loongson SIMD Extension (LSX).">; +def mno_lsx : Flag<["-"], "mno-lsx">, Group, + HelpText<"Disable Loongson SIMD Extension (LSX).">; +def mlasx : Flag<["-"], "mlasx">, Group, + HelpText<"Enable Loongson Advanced SIMD Extension (LASX).">; +def mno_lasx : Flag<["-"], "mno-lasx">, Group, + HelpText<"Disable Loongson Advanced SIMD Extension (LASX).">; def mnop_mcount : Flag<["-"], "mnop-mcount">, HelpText<"Generate mcount/__fentry__ calls as nops. To activate they need to be patched in.">, Visibility<[ClangOption, CC1Option]>, Group, MarshallingInfoFlag>; diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp index 4448a2ae10a17..88537989a0512 100644 --- a/clang/lib/Basic/Targets/LoongArch.cpp +++ b/clang/lib/Basic/Targets/LoongArch.cpp @@ -208,6 +208,11 @@ void LoongArchTargetInfo::getTargetDefines(const LangOptions &Opts, TuneCPU = ArchName; Builder.defineMacro("__loongarch_tune", Twine('"') + TuneCPU + Twine('"')); + if (HasFeatureLSX) + Builder.defineMacro("__loongarch_sx", Twine(1)); + if (HasFeatureLASX) + Builder.defineMacro("__loongarch_asx", Twine(1)); + StringRef ABI = getABI(); if (ABI == "lp64d" || ABI == "lp64f" || ABI == "lp64s") Builder.defineMacro("__loongarch_lp64"); @@ -257,6 +262,8 @@ bool LoongArchTargetInfo::hasFeature(StringRef Feature) const { .Case("loongarch64", Is64Bit) .Case("32bit", !Is64Bit) .Case("64bit", Is64Bit) + .Case("lsx", HasFeatureLSX) + .Case("lasx", HasFeatureLASX) .Default(false); } @@ -274,7 +281,10 @@ bool LoongArchTargetInfo::handleTargetFeatures( if (Feature == "+d") { HasFeatureD = true; } - } + } else if (Feature == "+lsx") + HasFeatureLSX = true; + else if (Feature == "+lasx") + HasFeatureLASX = true; } return true; } diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h index ba7fb78ab94cd..3313102492cb8 100644 --- a/clang/lib/Basic/Targets/LoongArch.h +++ b/clang/lib/Basic/Targets/LoongArch.h @@ -27,12 +27,16 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo { std::string CPU; bool HasFeatureD; bool HasFeatureF; + bool HasFeatureLSX; + bool HasFeatureLASX; public: LoongArchTargetInfo(const llvm::Triple &Triple, const TargetOptions &) : TargetInfo(Triple) { HasFeatureD = false; HasFeatureF = false; + HasFeatureLSX = false; + HasFeatureLASX = 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 65925e9ed6101..31153a67ad284 100644 --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -175,6 +175,38 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, A->ignoreTargetSpecific(); if (Arg *A = Args.getLastArgNoClaim(options::OPT_mfpu_EQ)) A->ignoreTargetSpecific(); + + // Select lsx feature determined by -m[no-]lsx. + if (const Arg *A = Args.getLastArg(options::OPT_mlsx, options::OPT_mno_lsx)) { + // LSX depends on 64-bit FPU. + // -m*-float and -mfpu=none/0/32 conflict with -mlsx. + if (A->getOption().matches(options::OPT_mlsx)) { + if (llvm::find(Features, "-d") != Features.end()) + D.Diag(diag::err_drv_loongarch_wrong_fpu_width_for_lsx); + else /*-mlsx*/ + Features.push_back("+lsx"); + } else /*-mno-lsx*/ { + Features.push_back("-lsx"); + } + } + + // Select lasx feature determined by -m[no-]lasx. + if (const Arg *A = + Args.getLastArg(options::OPT_mlasx, options::OPT_mno_lasx)) { + // LASX depends on 64-bit FPU and LSX. + // -mno-lsx conflicts with -mlasx. + if (A->getOption().matches(options::OPT_mlasx)) { + if (llvm::find(Features, "-d") != Features.end()) + D.Diag(diag::err_drv_loongarch_wrong_fpu_width_for_lasx); + else if (llvm::find(Features, "-lsx") != Features.end()) + D.Diag(diag::err_drv_loongarch_invalid_simd_option_combination); + else { /*-mlasx*/ + Features.push_back("+lsx"); + Features.push_back("+lasx"); + } + } else /*-mno-lasx*/ + Features.push_back("-lasx"); + } } std::string loongarch::postProcessTargetCPUString(const std::string &CPU, diff --git a/clang/test/Driver/loongarch-mlasx-error.c b/clang/test/Driver/loongarch-mlasx-error.c new file mode 100644 index 0000000000000..e66f277f7c292 --- /dev/null +++ b/clang/test/Driver/loongarch-mlasx-error.c @@ -0,0 +1,15 @@ +// RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlasx -msingle-float 2>&1 \ +// RUN: FileCheck --check-prefix=ERROR_LASX_FPU64 %s +// RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlasx -msoft-float 2>&1 \ +// RUN: FileCheck --check-prefix=ERROR_LASX_FPU64 %s +// RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlasx -mfpu=32 2>&1 \ +// RUN: FileCheck --check-prefix=ERROR_LASX_FPU64 %s +// RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlasx -mfpu=0 2>&1 \ +// RUN: FileCheck --check-prefix=ERROR_LASX_FPU64 %s +// RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlasx -mfpu=none 2>&1 \ +// RUN: FileCheck --check-prefix=ERROR_LASX_FPU64 %s +// RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlasx -mno-lsx 2>&1 \ +// RUN: FileCheck --check-prefix=ERROR_LASX_FPU128 %s + +// ERROR_LASX_FPU64: error: wrong fpu width; LASX depends on 64-bit FPU. +// ERROR_LASX_FPU128: error: invalid option combination; LASX depends on LSX. diff --git a/clang/test/Driver/loongarch-mlasx.c b/clang/test/Driver/loongarch-mlasx.c new file mode 100644 index 0000000000000..0b934f125c9e4 --- /dev/null +++ b/clang/test/Driver/loongarch-mlasx.c @@ -0,0 +1,37 @@ +/// Test -m[no-]lasx options. + +// RUN: %clang --target=loongarch64 -mlasx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-LASX +// RUN: %clang --target=loongarch64 -mno-lasx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-NOLASX +// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-NOLASX +// RUN: %clang --target=loongarch64 -mno-lasx -mlasx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-LASX +// RUN: %clang --target=loongarch64 -mlsx -mlasx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-LASX +// RUN: %clang --target=loongarch64 -mlasx -mlsx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-LASX + +// RUN: %clang --target=loongarch64 -mlasx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-LASX +// RUN: %clang --target=loongarch64 -mno-lasx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-NOLASX +// RUN: %clang --target=loongarch64 -mlasx -mno-lasx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-NOLASX +// RUN: %clang --target=loongarch64 -mno-lasx -mlasx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-LASX +// RUN: %clang --target=loongarch64 -mlsx -mlasx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-LASX +// RUN: %clang --target=loongarch64 -mlasx -mlsx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-LASX + +// CC1-LASX: "-target-feature" "+lsx" "-target-feature" "+lasx" +// CC1-NOLASX: "-target-feature" "-lasx" + +// IR-LASX: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+lasx{{(,.*)?}}" +// IR-NOLASX: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}-lasx{{(,.*)?}}" + +int foo(void){ + return 3; +} diff --git a/clang/test/Driver/loongarch-mlsx-error.c b/clang/test/Driver/loongarch-mlsx-error.c new file mode 100644 index 0000000000000..bd6b8e2718bf6 --- /dev/null +++ b/clang/test/Driver/loongarch-mlsx-error.c @@ -0,0 +1,12 @@ +// RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlsx -msingle-float 2>&1 \ +// RUN: FileCheck --check-prefix=ERROR_LSX_FPU64 %s +// RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlsx -msoft-float 2>&1 \ +// RUN: FileCheck --check-prefix=ERROR_LSX_FPU64 %s +// RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlsx -mfpu=32 2>&1 \ +// RUN: FileCheck --check-prefix=ERROR_LSX_FPU64 %s +// RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlsx -mfpu=0 2>&1 \ +// RUN: FileCheck --check-prefix=ERROR_LSX_FPU64 %s +// RUN: not %clang --target=loongarch64 %s -fsyntax-only -mlsx -mfpu=none 2>&1 \ +// RUN: FileCheck --check-prefix=ERROR_LSX_FPU64 %s + +// ERROR_LSX_FPU64: error: wrong fpu width; LSX depends on 64-bit FPU. diff --git a/clang/test/Driver/loongarch-mlsx.c b/clang/test/Driver/loongarch-mlsx.c new file mode 100644 index 0000000000000..7d4307b078e1a --- /dev/null +++ b/clang/test/Driver/loongarch-mlsx.c @@ -0,0 +1,41 @@ +/// Test -m[no-]lsx options. + +// RUN: %clang --target=loongarch64 -mlsx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-LSX +// RUN: %clang --target=loongarch64 -mno-lsx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-NOLSX +// RUN: %clang --target=loongarch64 -mlsx -mno-lsx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-NOLSX +// RUN: %clang --target=loongarch64 -mno-lsx -mlsx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-LSX +// RUN: %clang --target=loongarch64 -mlsx -mno-lasx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-LSX +// RUN: %clang --target=loongarch64 -mno-lasx -mlsx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-LSX +// RUN: %clang --target=loongarch64 -mno-lsx -mno-lasx -fsyntax-only %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CC1-NOLSX + +// RUN: %clang --target=loongarch64 -mlsx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-LSX +// RUN: %clang --target=loongarch64 -mno-lsx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-NOLSX +// RUN: %clang --target=loongarch64 -mlsx -mno-lsx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-NOLSX +// RUN: %clang --target=loongarch64 -mno-lsx -mlsx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-LSX +// RUN: %clang --target=loongarch64 -mlsx -mno-lasx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-LSX +// RUN: %clang --target=loongarch64 -mno-lasx -mlsx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-LSX +// RUN: %clang --target=loongarch64 -mno-lsx -mno-lasx -S -emit-llvm %s -o - | \ +// RUN: FileCheck %s --check-prefix=IR-NOLSX + +// CC1-LSX: "-target-feature" "+lsx" +// CC1-NOLSX: "-target-feature" "-lsx" + +// IR-LSX: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}+lsx{{(,.*)?}}" +// IR-NOLSX: attributes #[[#]] ={{.*}}"target-features"="{{(.*,)?}}-lsx{{(,.*)?}}" + +int foo(void){ + return 3; +} diff --git a/clang/test/Preprocessor/init-loongarch.c b/clang/test/Preprocessor/init-loongarch.c index 4ef42a921ec03..e235a72830215 100644 --- a/clang/test/Preprocessor/init-loongarch.c +++ b/clang/test/Preprocessor/init-loongarch.c @@ -807,3 +807,38 @@ // ARCH-TUNE: #define __loongarch_arch "[[ARCH]]" // ARCH-TUNE: #define __loongarch_tune "[[TUNE]]" + +// RUN: %clang --target=loongarch64 -mlsx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MLSX %s +// RUN: %clang --target=loongarch64 -mno-lsx -mlsx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MLSX %s +// RUN: %clang --target=loongarch64 -mlsx -mno-lasx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MLSX %s +// RUN: %clang --target=loongarch64 -mno-lasx -mlsx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MLSX %s +// MLSX-NOT: #define __loongarch_asx +// MLSX: #define __loongarch_sx 1 + +// RUN: %clang --target=loongarch64 -mlasx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MLASX %s +// RUN: %clang --target=loongarch64 -mno-lasx -mlasx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MLASX %s +// RUN: %clang --target=loongarch64 -mlsx -mlasx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MLASX %s +// RUN: %clang --target=loongarch64 -mlasx -mlsx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MLASX %s +// MLASX: #define __loongarch_asx 1 +// MLASX: #define __loongarch_sx 1 + +// RUN: %clang --target=loongarch64 -mno-lsx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MNO-LSX %s +// RUN: %clang --target=loongarch64 -mlsx -mno-lsx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MNO-LSX %s +// RUN: %clang --target=loongarch64 -mno-lsx -mno-lasx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MNO-LSX %s +// RUN: %clang --target=loongarch64 -mno-lasx -mno-lsx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MNO-LSX %s +// RUN: %clang --target=loongarch64 -mno-lasx -x c -E -dM %s -o - \ +// RUN: | FileCheck --match-full-lines --check-prefix=MNO-LSX %s +// MNO-LSX-NOT: #define __loongarch_asx +// MNO-LSX-NOT: #define __loongarch_sx