Skip to content

Commit 9e06d18

Browse files
committed
[LoongArch] Add intrinsics for CACOP instruction
The CACOP instruction is mainly used for cache initialization and cache-consistency maintenance. Depends on D140872 Reviewed By: SixWeining Differential Revision: https://reviews.llvm.org/D140527
1 parent a021db3 commit 9e06d18

File tree

18 files changed

+202
-7
lines changed

18 files changed

+202
-7
lines changed

clang/include/clang/Basic/BuiltinsLoongArch.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
// TODO: Support more builtins.
1919
// TODO: Added feature constraints.
20+
TARGET_BUILTIN(__builtin_loongarch_cacop_d, "vLiULiLi", "nc", "64bit")
21+
TARGET_BUILTIN(__builtin_loongarch_cacop_w, "viUii", "nc", "32bit")
2022
TARGET_BUILTIN(__builtin_loongarch_dbar, "vIUi", "nc", "")
2123
TARGET_BUILTIN(__builtin_loongarch_ibar, "vIUi", "nc", "")
2224
TARGET_BUILTIN(__builtin_loongarch_movfcsr2gr, "UiIUi", "nc", "f")

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11764,4 +11764,6 @@ def warn_unsafe_buffer_expression : Warning<
1176411764
def warn_unsafe_buffer_variable : Warning<
1176511765
"variable %0 participates in unchecked buffer operations">,
1176611766
InGroup<UnsafeBufferUsage>, DefaultIgnore;
11767+
def err_loongarch_builtin_requires_la32 : Error<
11768+
"this builtin requires target: loongarch32">;
1176711769
} // end of sema component.

clang/lib/Basic/Targets/LoongArch.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ bool LoongArchTargetInfo::initFeatureMap(
179179
const std::vector<std::string> &FeaturesVec) const {
180180
if (getTriple().getArch() == llvm::Triple::loongarch64)
181181
Features["64bit"] = true;
182+
if (getTriple().getArch() == llvm::Triple::loongarch32)
183+
Features["32bit"] = true;
182184

183185
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
184186
}

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19694,6 +19694,12 @@ Value *CodeGenFunction::EmitLoongArchBuiltinExpr(unsigned BuiltinID,
1969419694
switch (BuiltinID) {
1969519695
default:
1969619696
llvm_unreachable("unexpected builtin ID.");
19697+
case LoongArch::BI__builtin_loongarch_cacop_d:
19698+
ID = Intrinsic::loongarch_cacop_d;
19699+
break;
19700+
case LoongArch::BI__builtin_loongarch_cacop_w:
19701+
ID = Intrinsic::loongarch_cacop_w;
19702+
break;
1969719703
case LoongArch::BI__builtin_loongarch_dbar:
1969819704
ID = Intrinsic::loongarch_dbar;
1969919705
break;

clang/lib/Headers/larchintrin.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ extern __inline int
106106

107107
#define __break(/*ui15*/ _1) __builtin_loongarch_break((_1))
108108

109+
#if __loongarch_grlen == 32
110+
#define __cacop_w(/*uimm5*/ _1, /*unsigned int*/ _2, /*simm12*/ _3) \
111+
((void)__builtin_loongarch_cacop_w((_1), (unsigned int)(_2), (_3)))
112+
#endif
113+
114+
#if __loongarch_grlen == 64
115+
#define __cacop_d(/*uimm5*/ _1, /*unsigned long int*/ _2, /*simm12*/ _3) \
116+
((void)__builtin_loongarch_cacop_d((_1), (unsigned long int)(_2), (_3)))
117+
#endif
118+
109119
#define __dbar(/*ui15*/ _1) __builtin_loongarch_dbar((_1))
110120

111121
#define __ibar(/*ui15*/ _1) __builtin_loongarch_ibar((_1))

clang/lib/Sema/SemaChecking.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3705,6 +3705,23 @@ bool Sema::CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI,
37053705
switch (BuiltinID) {
37063706
default:
37073707
break;
3708+
case LoongArch::BI__builtin_loongarch_cacop_d:
3709+
if (!TI.hasFeature("64bit"))
3710+
return Diag(TheCall->getBeginLoc(),
3711+
diag::err_loongarch_builtin_requires_la64)
3712+
<< TheCall->getSourceRange();
3713+
LLVM_FALLTHROUGH;
3714+
case LoongArch::BI__builtin_loongarch_cacop_w: {
3715+
if (BuiltinID == LoongArch::BI__builtin_loongarch_cacop_w &&
3716+
!TI.hasFeature("32bit"))
3717+
return Diag(TheCall->getBeginLoc(),
3718+
diag::err_loongarch_builtin_requires_la32)
3719+
<< TheCall->getSourceRange();
3720+
SemaBuiltinConstantArgRange(TheCall, 0, 0, llvm::maxUIntN(5));
3721+
SemaBuiltinConstantArgRange(TheCall, 2, llvm::minIntN(12),
3722+
llvm::maxIntN(12));
3723+
break;
3724+
}
37083725
case LoongArch::BI__builtin_loongarch_crc_w_b_w:
37093726
case LoongArch::BI__builtin_loongarch_crc_w_h_w:
37103727
case LoongArch::BI__builtin_loongarch_crc_w_w_w:

clang/test/CodeGen/LoongArch/intrinsic-la32-error.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33

44
#include <larchintrin.h>
55

6+
void cacop_d(unsigned long int a) {
7+
__builtin_loongarch_cacop_d(1, a, 1024); // expected-error {{this builtin requires target: loongarch64}}
8+
__builtin_loongarch_cacop_w(-1, a, 1024); // expected-error {{argument value -1 is outside the valid range [0, 31]}}
9+
__builtin_loongarch_cacop_w(32, a, 1024); // expected-error {{argument value 32 is outside the valid range [0, 31]}}
10+
__builtin_loongarch_cacop_w(1, a, -4096); // expected-error {{argument value -4096 is outside the valid range [-2048, 2047]}}
11+
__builtin_loongarch_cacop_w(1, a, 4096); // expected-error {{argument value 4096 is outside the valid range [-2048, 2047]}}
12+
}
13+
614
void dbar(int a) {
715
__builtin_loongarch_dbar(32768); // expected-error {{argument value 32768 is outside the valid range [0, 32767]}}
816
__builtin_loongarch_dbar(-1); // expected-error {{argument value 4294967295 is outside the valid range [0, 32767]}}

clang/test/CodeGen/LoongArch/intrinsic-la32.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,3 +200,14 @@ void loongarch_movgr2fcsr(int a) {
200200
__movgr2fcsr(1, a);
201201
__builtin_loongarch_movgr2fcsr(1, a);
202202
}
203+
204+
// CHECK-LABEL: @cacop_w(
205+
// CHECK-NEXT: entry:
206+
// CHECK-NEXT: tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A:%.*]], i32 1024)
207+
// CHECK-NEXT: tail call void @llvm.loongarch.cacop.w(i32 1, i32 [[A]], i32 1024)
208+
// CHECK-NEXT: ret void
209+
//
210+
void cacop_w(unsigned long int a) {
211+
__cacop_w(1, a, 1024);
212+
__builtin_loongarch_cacop_w(1, a, 1024);
213+
}

clang/test/CodeGen/LoongArch/intrinsic-la64.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,17 @@ int crc_w_w_w(int a, int b) {
123123
return 0;
124124
}
125125

126+
// CHECK-LABEL: @cacop_d(
127+
// CHECK-NEXT: entry:
128+
// CHECK-NEXT: tail call void @llvm.loongarch.cacop.d(i64 1, i64 [[A:%.*]], i64 1024)
129+
// CHECK-NEXT: tail call void @llvm.loongarch.cacop.d(i64 1, i64 [[A]], i64 1024)
130+
// CHECK-NEXT: ret void
131+
//
132+
void cacop_d(unsigned long int a) {
133+
__cacop_d(1, a, 1024);
134+
__builtin_loongarch_cacop_d(1, a, 1024);
135+
}
136+
126137
// CHECK-LABEL: @crc_w_d_w(
127138
// CHECK-NEXT: entry:
128139
// CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.loongarch.crc.w.d.w(i64 [[A:%.*]], i32 [[B:%.*]])

clang/test/Driver/loongarch-default-features.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %clang --target=loongarch32 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA32
22
// RUN: %clang --target=loongarch64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=LA64
33

4-
// LA32-NOT: "target-features"=
4+
// LA32: "target-features"="+32bit"
55
// LA64: "target-features"="+64bit,+d,+f"
66

77
int foo(void) {

0 commit comments

Comments
 (0)