982 changes: 982 additions & 0 deletions clang/include/clang/Basic/BuiltinsLoongArchLASX.def

Large diffs are not rendered by default.

953 changes: 953 additions & 0 deletions clang/include/clang/Basic/BuiltinsLoongArchLSX.def

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,12 @@ def warn_drv_loongarch_conflicting_implied_val : Warning<
InGroup<OptionIgnored>;
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">;
Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ def m_riscv_Features_Group : OptionGroup<"<riscv features group>">,
Group<m_Group>, DocName<"RISC-V">;
def m_ve_Features_Group : OptionGroup<"<ve features group>">,
Group<m_Group>, DocName<"VE">;
def m_loongarch_Features_Group : OptionGroup<"<loongarch features group>">,
Group<m_Group>, DocName<"LoongArch">;

def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_mips_Features_Group>,
Flags<[HelpHidden]>;
Expand Down Expand Up @@ -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<m_Group>,
MarshallingInfoFlag<CodeGenOpts<"CallFEntry">>;
def mlsx : Flag<["-"], "mlsx">, Group<m_loongarch_Features_Group>,
HelpText<"Enable Loongson SIMD Extension (LSX).">;
def mno_lsx : Flag<["-"], "mno-lsx">, Group<m_loongarch_Features_Group>,
HelpText<"Disable Loongson SIMD Extension (LSX).">;
def mlasx : Flag<["-"], "mlasx">, Group<m_loongarch_Features_Group>,
HelpText<"Enable Loongson Advanced SIMD Extension (LASX).">;
def mno_lasx : Flag<["-"], "mno-lasx">, Group<m_loongarch_Features_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<m_Group>,
MarshallingInfoFlag<CodeGenOpts<"MNopMCount">>;
Expand Down
12 changes: 11 additions & 1 deletion clang/lib/Basic/Targets/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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);
}

Expand All @@ -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;
}
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets/LoongArch.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/CodeGen/Targets/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,13 @@ ABIArgInfo LoongArchABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
return ABIArgInfo::getDirect();
}

// Pass 128-bit/256-bit vector values via vector registers directly.
if (Ty->isVectorType() && (((getContext().getTypeSize(Ty) == 128) &&
(getTarget().hasFeature("lsx"))) ||
((getContext().getTypeSize(Ty) == 256) &&
getTarget().hasFeature("lasx"))))
return ABIArgInfo::getDirect();

// Complex types for the *f or *d ABI must be passed directly rather than
// using CoerceAndExpand.
if (IsFixed && Ty->isComplexType() && FRLen && FARsLeft >= 2) {
Expand Down
32 changes: 32 additions & 0 deletions clang/lib/Driver/ToolChains/Arch/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Headers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ set(hlsl_files

set(loongarch_files
larchintrin.h
lasxintrin.h
lsxintrin.h
)

set(mips_msa_files
Expand Down
3,860 changes: 3,860 additions & 0 deletions clang/lib/Headers/lasxintrin.h

Large diffs are not rendered by default.

3,726 changes: 3,726 additions & 0 deletions clang/lib/Headers/lsxintrin.h

Large diffs are not rendered by default.

456 changes: 455 additions & 1 deletion clang/lib/Sema/SemaChecking.cpp

Large diffs are not rendered by default.

1,373 changes: 1,373 additions & 0 deletions clang/test/CodeGen/LoongArch/lasx/builtin-alias-error.c

Large diffs are not rendered by default.

4,430 changes: 4,430 additions & 0 deletions clang/test/CodeGen/LoongArch/lasx/builtin-alias.c

Large diffs are not rendered by default.

1,392 changes: 1,392 additions & 0 deletions clang/test/CodeGen/LoongArch/lasx/builtin-error.c

Large diffs are not rendered by default.

4,452 changes: 4,452 additions & 0 deletions clang/test/CodeGen/LoongArch/lasx/builtin.c

Large diffs are not rendered by default.

1,359 changes: 1,359 additions & 0 deletions clang/test/CodeGen/LoongArch/lsx/builtin-alias-error.c

Large diffs are not rendered by default.

4,451 changes: 4,451 additions & 0 deletions clang/test/CodeGen/LoongArch/lsx/builtin-alias.c

Large diffs are not rendered by default.

1,382 changes: 1,382 additions & 0 deletions clang/test/CodeGen/LoongArch/lsx/builtin-error.c

Large diffs are not rendered by default.

5,193 changes: 5,193 additions & 0 deletions clang/test/CodeGen/LoongArch/lsx/builtin.c

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions clang/test/Driver/loongarch-mlasx-error.c
Original file line number Diff line number Diff line change
@@ -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.
37 changes: 37 additions & 0 deletions clang/test/Driver/loongarch-mlasx.c
Original file line number Diff line number Diff line change
@@ -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;
}
12 changes: 12 additions & 0 deletions clang/test/Driver/loongarch-mlsx-error.c
Original file line number Diff line number Diff line change
@@ -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.
41 changes: 41 additions & 0 deletions clang/test/Driver/loongarch-mlsx.c
Original file line number Diff line number Diff line change
@@ -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;
}
35 changes: 35 additions & 0 deletions clang/test/Preprocessor/init-loongarch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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