Skip to content

Commit da34aff

Browse files
committed
[Clang][LoongArch] Implement __builtin_loongarch_crc_w_d_w builtin and add diagnostics
This patch adds support to prevent __builtin_loongarch_crc_w_d_w from compiling on loongarch32 in the front end and adds diagnostics accordingly. Reference: https://github.com/gcc-mirror/gcc/blob/master/gcc/config/loongarch/larchintrin.h#L175-L184 Depends on D136906 Differential Revision: https://reviews.llvm.org/D137316
1 parent ffb109b commit da34aff

File tree

16 files changed

+165
-0
lines changed

16 files changed

+165
-0
lines changed

clang/include/clang/Basic/BuiltinsLoongArch.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,7 @@
1919
// TODO: Added feature constraints.
2020
TARGET_BUILTIN(__builtin_loongarch_dbar, "vIUi", "nc", "")
2121

22+
TARGET_BUILTIN(__builtin_loongarch_crc_w_d_w, "iLii", "nc", "64bit")
23+
2224
#undef BUILTIN
2325
#undef TARGET_BUILTIN

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11729,4 +11729,8 @@ def err_non_designated_init_used : Error<
1172911729
"a randomized struct can only be initialized with a designated initializer">;
1173011730
def err_cast_from_randomized_struct : Error<
1173111731
"casting from randomized structure pointer type %0 to %1">;
11732+
11733+
// LoongArch-specific Diagnostics
11734+
def err_loongarch_builtin_requires_la64 : Error<
11735+
"this builtin requires target: loongarch64">;
1173211736
} // end of sema component.

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13342,6 +13342,8 @@ class Sema final {
1334213342
bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum);
1334313343
bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
1334413344
CallExpr *TheCall);
13345+
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI,
13346+
unsigned BuiltinID, CallExpr *TheCall);
1334513347

1334613348
bool SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall);
1334713349
bool SemaBuiltinVAStartARMMicrosoft(CallExpr *Call);

clang/lib/Basic/Targets/LoongArch.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,27 @@ const Builtin::Info LoongArchTargetInfo::BuiltinInfo[] = {
168168
#include "clang/Basic/BuiltinsLoongArch.def"
169169
};
170170

171+
bool LoongArchTargetInfo::initFeatureMap(
172+
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
173+
const std::vector<std::string> &FeaturesVec) const {
174+
if (getTriple().getArch() == llvm::Triple::loongarch64)
175+
Features["64bit"] = true;
176+
177+
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
178+
}
179+
180+
/// Return true if has this feature.
181+
bool LoongArchTargetInfo::hasFeature(StringRef Feature) const {
182+
bool Is64Bit = getTriple().getArch() == llvm::Triple::loongarch64;
183+
// TODO: Handle more features.
184+
return llvm::StringSwitch<bool>(Feature)
185+
.Case("loongarch32", !Is64Bit)
186+
.Case("loongarch64", Is64Bit)
187+
.Case("32bit", !Is64Bit)
188+
.Case("64bit", Is64Bit)
189+
.Default(false);
190+
}
191+
171192
ArrayRef<Builtin::Info> LoongArchTargetInfo::getTargetBuiltins() const {
172193
return llvm::makeArrayRef(BuiltinInfo, clang::LoongArch::LastTSBuiltin -
173194
Builtin::FirstTSBuiltin);

clang/lib/Basic/Targets/LoongArch.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
6666

6767
bool handleTargetFeatures(std::vector<std::string> &Features,
6868
DiagnosticsEngine &Diags) override;
69+
70+
bool
71+
initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
72+
StringRef CPU,
73+
const std::vector<std::string> &FeaturesVec) const override;
74+
75+
bool hasFeature(StringRef Feature) const override;
6976
};
7077

7178
class LLVM_LIBRARY_VISIBILITY LoongArch32TargetInfo

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19638,6 +19638,9 @@ Value *CodeGenFunction::EmitLoongArchBuiltinExpr(unsigned BuiltinID,
1963819638
case LoongArch::BI__builtin_loongarch_dbar:
1963919639
ID = Intrinsic::loongarch_dbar;
1964019640
break;
19641+
case LoongArch::BI__builtin_loongarch_crc_w_d_w:
19642+
ID = Intrinsic::loongarch_crc_w_d_w;
19643+
break;
1964119644
// TODO: Support more Intrinsics.
1964219645
}
1964319646

clang/lib/Headers/larchintrin.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@
1414
extern "C" {
1515
#endif
1616

17+
#if __loongarch_grlen == 64
18+
extern __inline int
19+
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
20+
__crc_w_d_w(long int _1, int _2) {
21+
return (int)__builtin_loongarch_crc_w_d_w((long int)_1, (int)_2);
22+
}
23+
#endif
24+
1725
#define __dbar(/*ui15*/ _1) __builtin_loongarch_dbar((_1))
1826

1927
#ifdef __cplusplus

clang/lib/Sema/SemaChecking.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,6 +2020,9 @@ bool Sema::CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID,
20202020
case llvm::Triple::riscv32:
20212021
case llvm::Triple::riscv64:
20222022
return CheckRISCVBuiltinFunctionCall(TI, BuiltinID, TheCall);
2023+
case llvm::Triple::loongarch32:
2024+
case llvm::Triple::loongarch64:
2025+
return CheckLoongArchBuiltinFunctionCall(TI, BuiltinID, TheCall);
20232026
}
20242027
}
20252028

@@ -3668,6 +3671,23 @@ bool Sema::CheckHexagonBuiltinFunctionCall(unsigned BuiltinID,
36683671
return CheckHexagonBuiltinArgument(BuiltinID, TheCall);
36693672
}
36703673

3674+
bool Sema::CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI,
3675+
unsigned BuiltinID,
3676+
CallExpr *TheCall) {
3677+
switch (BuiltinID) {
3678+
default:
3679+
break;
3680+
case LoongArch::BI__builtin_loongarch_crc_w_d_w:
3681+
if (!TI.hasFeature("64bit"))
3682+
return Diag(TheCall->getBeginLoc(),
3683+
diag::err_loongarch_builtin_requires_la64)
3684+
<< TheCall->getSourceRange();
3685+
break;
3686+
}
3687+
3688+
return false;
3689+
}
3690+
36713691
bool Sema::CheckMipsBuiltinFunctionCall(const TargetInfo &TI,
36723692
unsigned BuiltinID, CallExpr *TheCall) {
36733693
return CheckMipsBuiltinCpu(TI, BuiltinID, TheCall) ||
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -triple loongarch32 -emit-llvm -S -verify %s -o /dev/null
3+
4+
#include <larchintrin.h>
5+
6+
int crc_w_d_w(long int a, int b) {
7+
return __builtin_loongarch_crc_w_d_w(a, b); // expected-error {{this builtin requires target: loongarch64}}
8+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// RUN: %clang_cc1 -triple loongarch64 -O2 -emit-llvm %s -o - | FileCheck %s
3+
4+
#include <larchintrin.h>
5+
6+
// CHECK-LABEL: @crc_w_d_w(
7+
// CHECK-NEXT: entry:
8+
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.crc.w.d.w(i64 [[A:%.*]], i32 [[B:%.*]])
9+
// CHECK-NEXT: ret i32 [[TMP0]]
10+
//
11+
int crc_w_d_w(long int a, int b) {
12+
return __builtin_loongarch_crc_w_d_w(a, b);
13+
}

0 commit comments

Comments
 (0)