-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RISCV][Clang] Added builtin support for experimental Zimop extension #79971
base: main
Are you sure you want to change the base?
Conversation
This change adds builtin of mop.r.[n] and mop.rr.[n] instructions for Zimop extension based on https://github.com/riscv-non-isa/riscv-c-api-doc/blob/master/riscv-c-api.md.
@llvm/pr-subscribers-backend-risc-v @llvm/pr-subscribers-clang-codegen Author: Jivan Hakobyan (JivanH) ChangesThis change adds builtin of mop.r.[n] and mop.rr.[n] instructions for Zimop extension based on https://github.com/riscv-non-isa/riscv-c-api-doc/blob/master/riscv-c-api.md. Full diff: https://github.com/llvm/llvm-project/pull/79971.diff 4 Files Affected:
diff --git a/clang/include/clang/Basic/BuiltinsRISCV.def b/clang/include/clang/Basic/BuiltinsRISCV.def
index 1528b18c82ead..7e2dda21830c5 100644
--- a/clang/include/clang/Basic/BuiltinsRISCV.def
+++ b/clang/include/clang/Basic/BuiltinsRISCV.def
@@ -89,5 +89,12 @@ TARGET_BUILTIN(__builtin_riscv_sm3p1, "UiUi", "nc", "zksh")
TARGET_BUILTIN(__builtin_riscv_ntl_load, "v.", "t", "zihintntl")
TARGET_BUILTIN(__builtin_riscv_ntl_store, "v.", "t", "zihintntl")
+// Zimop extension
+TARGET_BUILTIN(__builtin_riscv_mopr_32, "UiUiUi", "nc", "experimental-zimop")
+TARGET_BUILTIN(__builtin_riscv_mopr_64, "UWiUWiUWi", "nc",
+ "experimental-zimop,64bit")
+TARGET_BUILTIN(__builtin_riscv_moprr_32, "UiUiUiUi", "nc", "experimental-zimop")
+TARGET_BUILTIN(__builtin_riscv_moprr_64, "UWiUWiUWiUWi", "nc",
+ "experimental-zimop,64bit")
#undef BUILTIN
#undef TARGET_BUILTIN
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index f3ab5ad7b08ec..28511f9e0beac 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -21189,6 +21189,10 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
case RISCV::BI__builtin_riscv_clmulh_64:
case RISCV::BI__builtin_riscv_clmulr_32:
case RISCV::BI__builtin_riscv_clmulr_64:
+ case RISCV::BI__builtin_riscv_mopr_32:
+ case RISCV::BI__builtin_riscv_mopr_64:
+ case RISCV::BI__builtin_riscv_moprr_32:
+ case RISCV::BI__builtin_riscv_moprr_64:
case RISCV::BI__builtin_riscv_xperm4_32:
case RISCV::BI__builtin_riscv_xperm4_64:
case RISCV::BI__builtin_riscv_xperm8_32:
@@ -21237,6 +21241,16 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
ID = Intrinsic::riscv_clmulr;
break;
+ // Zimop
+ case RISCV::BI__builtin_riscv_mopr_32:
+ case RISCV::BI__builtin_riscv_mopr_64:
+ ID = Intrinsic::riscv_mopr;
+ break;
+ case RISCV::BI__builtin_riscv_moprr_32:
+ case RISCV::BI__builtin_riscv_moprr_64:
+ ID = Intrinsic::riscv_moprr;
+ break;
+
// Zbkx
case RISCV::BI__builtin_riscv_xperm8_32:
case RISCV::BI__builtin_riscv_xperm8_64:
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 502b24bcdf8b4..c2702bec29dd7 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5588,6 +5588,14 @@ bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI,
// Check if rnum is in [0, 10]
case RISCV::BI__builtin_riscv_aes64ks1i:
return SemaBuiltinConstantArgRange(TheCall, 1, 0, 10);
+ // Check if n of mop.r.[n] is in [0, 31]
+ case RISCV::BI__builtin_riscv_mopr_32:
+ case RISCV::BI__builtin_riscv_mopr_64:
+ return SemaBuiltinConstantArgRange(TheCall, 1, 0, 31);
+ // Check if n of mop.rr.[n] is in [0, 7]
+ case RISCV::BI__builtin_riscv_moprr_32:
+ case RISCV::BI__builtin_riscv_moprr_64:
+ return SemaBuiltinConstantArgRange(TheCall, 2, 0, 7);
// Check if value range for vxrm is in [0, 3]
case RISCVVector::BI__builtin_rvv_vaaddu_vv:
case RISCVVector::BI__builtin_rvv_vaaddu_vx:
diff --git a/clang/test/CodeGen/RISCV/rvb-intrinsics/zimop.c b/clang/test/CodeGen/RISCV/rvb-intrinsics/zimop.c
new file mode 100644
index 0000000000000..b4367e33bdc19
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/rvb-intrinsics/zimop.c
@@ -0,0 +1,105 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple riscv32 -target-feature +experimental-zimop -emit-llvm %s -o - \
+// RUN: -disable-O0-optnone | opt -S -passes=mem2reg \
+// RUN: | FileCheck %s -check-prefix=RV32ZIMOP
+// RUN: %clang_cc1 -triple riscv64 -target-feature +experimental-zimop -emit-llvm %s -o - \
+// RUN: -disable-O0-optnone | opt -S -passes=mem2reg \
+// RUN: | FileCheck %s -check-prefix=RV64ZIMOP
+
+#include <stdint.h>
+
+#if __riscv_xlen == 64
+// RV64ZIMOP-LABEL: @mopr_0_64(
+// RV64ZIMOP-NEXT: entry:
+// RV64ZIMOP-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.mopr.i64(i64 [[A:%.*]], i64 0)
+// RV64ZIMOP-NEXT: ret i64 [[TMP0]]
+//
+uint64_t mopr_0_64(uint64_t a) {
+ return __builtin_riscv_mopr_64(a, 0);
+}
+
+// RV64ZIMOP-LABEL: @mopr_31_64(
+// RV64ZIMOP-NEXT: entry:
+// RV64ZIMOP-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.mopr.i64(i64 [[A:%.*]], i64 31)
+// RV64ZIMOP-NEXT: ret i64 [[TMP0]]
+//
+uint64_t mopr_31_64(uint64_t a) {
+ return __builtin_riscv_mopr_64(a, 31);
+}
+
+// RV64ZIMOP-LABEL: @moprr_0_64(
+// RV64ZIMOP-NEXT: entry:
+// RV64ZIMOP-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.moprr.i64(i64 [[A:%.*]], i64 [[B:%.*]], i64 0)
+// RV64ZIMOP-NEXT: ret i64 [[TMP0]]
+//
+uint64_t moprr_0_64(uint64_t a, uint64_t b) {
+ return __builtin_riscv_moprr_64(a, b, 0);
+}
+
+// RV64ZIMOP-LABEL: @moprr_7_64(
+// RV64ZIMOP-NEXT: entry:
+// RV64ZIMOP-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.moprr.i64(i64 [[A:%.*]], i64 [[B:%.*]], i64 7)
+// RV64ZIMOP-NEXT: ret i64 [[TMP0]]
+//
+uint64_t moprr_7_64(uint64_t a, uint64_t b) {
+ return __builtin_riscv_moprr_64(a, b, 7);
+}
+
+#endif
+
+// RV32ZIMOP-LABEL: @mopr_0_32(
+// RV32ZIMOP-NEXT: entry:
+// RV32ZIMOP-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.mopr.i32(i32 [[A:%.*]], i32 0)
+// RV32ZIMOP-NEXT: ret i32 [[TMP0]]
+//
+// RV64ZIMOP-LABEL: @mopr_0_32(
+// RV64ZIMOP-NEXT: entry:
+// RV64ZIMOP-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.mopr.i32(i32 [[A:%.*]], i32 0)
+// RV64ZIMOP-NEXT: ret i32 [[TMP0]]
+//
+uint32_t mopr_0_32(uint32_t a) {
+ return __builtin_riscv_mopr_32(a, 0);
+}
+
+// RV32ZIMOP-LABEL: @mopr_31_32(
+// RV32ZIMOP-NEXT: entry:
+// RV32ZIMOP-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.mopr.i32(i32 [[A:%.*]], i32 31)
+// RV32ZIMOP-NEXT: ret i32 [[TMP0]]
+//
+// RV64ZIMOP-LABEL: @mopr_31_32(
+// RV64ZIMOP-NEXT: entry:
+// RV64ZIMOP-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.mopr.i32(i32 [[A:%.*]], i32 31)
+// RV64ZIMOP-NEXT: ret i32 [[TMP0]]
+//
+uint32_t mopr_31_32(uint32_t a) {
+ return __builtin_riscv_mopr_32(a, 31);
+}
+
+// RV32ZIMOP-LABEL: @moprr_0_32(
+// RV32ZIMOP-NEXT: entry:
+// RV32ZIMOP-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.moprr.i32(i32 [[A:%.*]], i32 [[B:%.*]], i32 0)
+// RV32ZIMOP-NEXT: ret i32 [[TMP0]]
+//
+// RV64ZIMOP-LABEL: @moprr_0_32(
+// RV64ZIMOP-NEXT: entry:
+// RV64ZIMOP-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.moprr.i32(i32 [[A:%.*]], i32 [[B:%.*]], i32 0)
+// RV64ZIMOP-NEXT: ret i32 [[TMP0]]
+//
+uint32_t moprr_0_32(uint32_t a, uint32_t b) {
+ return __builtin_riscv_moprr_32(a, b, 0);
+}
+
+// RV32ZIMOP-LABEL: @moprr_7_32(
+// RV32ZIMOP-NEXT: entry:
+// RV32ZIMOP-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.moprr.i32(i32 [[A:%.*]], i32 [[B:%.*]], i32 7)
+// RV32ZIMOP-NEXT: ret i32 [[TMP0]]
+//
+// RV64ZIMOP-LABEL: @moprr_7_32(
+// RV64ZIMOP-NEXT: entry:
+// RV64ZIMOP-NEXT: [[TMP0:%.*]] = call i32 @llvm.riscv.moprr.i32(i32 [[A:%.*]], i32 [[B:%.*]], i32 7)
+// RV64ZIMOP-NEXT: ret i32 [[TMP0]]
+//
+uint32_t moprr_7_32(uint32_t a, uint32_t b) {
+ return __builtin_riscv_moprr_32(a, b, 7);
+}
+
|
Please review |
clang/lib/CodeGen/CGBuiltin.cpp
Outdated
@@ -21189,6 +21189,10 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, | |||
case RISCV::BI__builtin_riscv_clmulh_64: | |||
case RISCV::BI__builtin_riscv_clmulr_32: | |||
case RISCV::BI__builtin_riscv_clmulr_64: | |||
case RISCV::BI__builtin_riscv_mopr_32: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think put mop between zb* builtins is not a good ideal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed
@@ -89,5 +89,13 @@ TARGET_BUILTIN(__builtin_riscv_sm3p1, "UiUi", "nc", "zksh") | |||
TARGET_BUILTIN(__builtin_riscv_ntl_load, "v.", "t", "zihintntl") | |||
TARGET_BUILTIN(__builtin_riscv_ntl_store, "v.", "t", "zihintntl") | |||
|
|||
// Zimop extension | |||
TARGET_BUILTIN(__builtin_riscv_mopr_32, "UiUiUi", "nc", "experimental-zimop") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The last argument should include 'I' to indicate it needs to be a compile time constant. See __builtin_riscv_sm4ed
for example.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
REMIND: Hi. Could you please review my patch? |
@@ -89,5 +89,13 @@ TARGET_BUILTIN(__builtin_riscv_sm3p1, "UiUi", "nc", "zksh") | |||
TARGET_BUILTIN(__builtin_riscv_ntl_load, "v.", "t", "zihintntl") | |||
TARGET_BUILTIN(__builtin_riscv_ntl_store, "v.", "t", "zihintntl") | |||
|
|||
// Zimop extension |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may need to rebase as I have rewritten this file in TableGen.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebased
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code is OK I think.
One question: how will these builtins be used? Are their semantics bound to specific extensions that extend MOPs?
Surely we should instead be defining intrinsics with actual names for the operations we know about? What's the actual use case for needing an arbitrary unnamed one? |
This change adds builtin of mop.r.[n] and mop.rr.[n] instructions for Zimop extension based on https://github.com/riscv-non-isa/riscv-c-api-doc/blob/master/riscv-c-api.md.