-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[RISCV] Support Xsfvfnrclipxfqf extensions #68297
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
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-llvm-support ChangesFP32-to-int8 Ranged Clip Instructions Patch is 182.97 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/68297.diff 33 Files Affected:
diff --git a/clang/include/clang/Basic/riscv_sifive_vector.td b/clang/include/clang/Basic/riscv_sifive_vector.td
index 6583a7eb7b2e59b..6e171cc7618b03a 100644
--- a/clang/include/clang/Basic/riscv_sifive_vector.td
+++ b/clang/include/clang/Basic/riscv_sifive_vector.td
@@ -103,3 +103,65 @@ let SupportOverloading = false in {
defm sf_vc_v_fvw : RVVVCIXBuiltinSet<["si"], "UwKzUwUvFe", [-1, 0, 2, 3], UseGPR=0>;
}
}
+
+multiclass RVVVFNRCLIPBuiltinSet<string suffix, string prototype, string type_range> {
+ let Log2LMUL = [-3, -2, -1, 0, 1, 2],
+ Name = NAME,
+ IRName = NAME,
+ MaskedIRName = NAME # "_mask" in
+ def : RVVConvBuiltin<suffix, prototype, type_range, NAME>;
+}
+
+let UnMaskedPolicyScheme = HasPassthruOperand, RequiredFeatures = ["Xsfvfnrclipxfqf"] in {
+let ManualCodegen = [{
+ {
+ // LLVM intrinsic
+ // Unmasked: (passthru, vector_in, scalar_in, frm, vl)
+ // Masked: (passthru, vector_in, scalar_in, mask, frm, vl, policy)
+
+ SmallVector<llvm::Value*, 7> Operands;
+ bool HasMaskedOff = !(
+ (IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
+ (!IsMasked && PolicyAttrs & RVV_VTA));
+ bool HasRoundModeOp = IsMasked ?
+ (HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5) :
+ (HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
+
+ unsigned Offset = IsMasked ?
+ (HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
+
+ if (!HasMaskedOff)
+ Operands.push_back(llvm::PoisonValue::get(ResultType));
+ else
+ Operands.push_back(Ops[IsMasked ? 1 : 0]);
+
+ Operands.push_back(Ops[Offset]); // op0
+ Operands.push_back(Ops[Offset + 1]); // op1
+
+ if (IsMasked)
+ Operands.push_back(Ops[0]); // mask
+
+ if (HasRoundModeOp) {
+ Operands.push_back(Ops[Offset + 2]); // frm
+ Operands.push_back(Ops[Offset + 3]); // vl
+ } else {
+ Operands.push_back(ConstantInt::get(Ops[Offset + 2]->getType(), 7)); // frm
+ Operands.push_back(Ops[Offset + 2]); // vl
+ }
+
+ if (IsMasked)
+ Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
+
+ IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Operands.back()->getType()};
+ llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
+ return Builder.CreateCall(F, Operands, "");
+ }
+}] in {
+ let HasFRMRoundModeOp = true in {
+ defm sf_vfnrclip_x_f_qf : RVVVFNRCLIPBuiltinSet<"v", "vFqfu", "c">;
+ defm sf_vfnrclip_xu_f_qf : RVVVFNRCLIPBuiltinSet<"Uv", "UvFqfu", "c">;
+ }
+ defm sf_vfnrclip_x_f_qf : RVVVFNRCLIPBuiltinSet<"v", "vFqf", "c">;
+ defm sf_vfnrclip_xu_f_qf : RVVVFNRCLIPBuiltinSet<"Uv", "UvFqf", "c">;
+}
+}
diff --git a/clang/include/clang/Basic/riscv_vector_common.td b/clang/include/clang/Basic/riscv_vector_common.td
index 141fac9d68e6d54..326c3883f0a8409 100644
--- a/clang/include/clang/Basic/riscv_vector_common.td
+++ b/clang/include/clang/Basic/riscv_vector_common.td
@@ -66,6 +66,7 @@
// t: ptrdiff_t, ignores "t"
// u: unsigned long, ignores "t"
// l: long, ignores "t"
+// f: float32, ignores "t"
//
// So for instance if t is "i", i.e. int, then "e" will yield int again. "v"
// will yield an RVV vector type (assume LMUL=1), so __rvv_int32m1_t.
diff --git a/clang/include/clang/Support/RISCVVIntrinsicUtils.h b/clang/include/clang/Support/RISCVVIntrinsicUtils.h
index 8ba57d77221dc52..9de83028f85e496 100644
--- a/clang/include/clang/Support/RISCVVIntrinsicUtils.h
+++ b/clang/include/clang/Support/RISCVVIntrinsicUtils.h
@@ -85,6 +85,7 @@ enum class BaseTypeModifier : uint8_t {
Ptrdiff,
UnsignedLong,
SignedLong,
+ Float32
};
// Modifier for type, used for both scalar and vector types.
@@ -485,14 +486,15 @@ enum RVVRequire : uint16_t {
RVV_REQ_RV64 = 1 << 0,
RVV_REQ_ZvfhminOrZvfh = 1 << 1,
RVV_REQ_Xsfvcp = 1 << 2,
- RVV_REQ_Zvbb = 1 << 3,
- RVV_REQ_Zvbc = 1 << 4,
- RVV_REQ_Zvkb = 1 << 5,
- RVV_REQ_Zvkg = 1 << 6,
- RVV_REQ_Zvkned = 1 << 7,
- RVV_REQ_Zvknha = 1 << 8,
- RVV_REQ_Zvksed = 1 << 9,
- RVV_REQ_Zvksh = 1 << 10,
+ RVV_REQ_Xsfvfnrclipxfqf = 1 << 3,
+ RVV_REQ_Zvbb = 1 << 4,
+ RVV_REQ_Zvbc = 1 << 5,
+ RVV_REQ_Zvkb = 1 << 6,
+ RVV_REQ_Zvkg = 1 << 7,
+ RVV_REQ_Zvkned = 1 << 8,
+ RVV_REQ_Zvknha = 1 << 9,
+ RVV_REQ_Zvksed = 1 << 10,
+ RVV_REQ_Zvksh = 1 << 11,
LLVM_MARK_AS_BITMASK_ENUM(RVV_REQ_Zvksh)
};
diff --git a/clang/lib/Sema/SemaRISCVVectorLookup.cpp b/clang/lib/Sema/SemaRISCVVectorLookup.cpp
index ae584dc68719901..6440e379d2d5036 100644
--- a/clang/lib/Sema/SemaRISCVVectorLookup.cpp
+++ b/clang/lib/Sema/SemaRISCVVectorLookup.cpp
@@ -205,6 +205,7 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
static const std::pair<const char *, RVVRequire> FeatureCheckList[] = {
{"64bit", RVV_REQ_RV64},
{"xsfvcp", RVV_REQ_Xsfvcp},
+ {"xsfvfnrclipxfqf", RVV_REQ_Xsfvfnrclipxfqf},
{"experimental-zvbb", RVV_REQ_Zvbb},
{"experimental-zvbc", RVV_REQ_Zvbc},
{"experimental-zvkb", RVV_REQ_Zvkb},
diff --git a/clang/lib/Support/RISCVVIntrinsicUtils.cpp b/clang/lib/Support/RISCVVIntrinsicUtils.cpp
index c105db434dc43c9..bc366cb2d99056d 100644
--- a/clang/lib/Support/RISCVVIntrinsicUtils.cpp
+++ b/clang/lib/Support/RISCVVIntrinsicUtils.cpp
@@ -430,6 +430,9 @@ PrototypeDescriptor::parsePrototypeDescriptor(
case 'l':
PT = BaseTypeModifier::SignedLong;
break;
+ case 'f':
+ PT = BaseTypeModifier::Float32;
+ break;
default:
llvm_unreachable("Illegal primitive type transformers!");
}
@@ -666,6 +669,10 @@ void RVVType::applyModifier(const PrototypeDescriptor &Transformer) {
case BaseTypeModifier::SignedLong:
ScalarType = ScalarTypeKind::SignedLong;
break;
+ case BaseTypeModifier::Float32:
+ ElementBitwidth = 32;
+ ScalarType = ScalarTypeKind::Float;
+ break;
case BaseTypeModifier::Invalid:
ScalarType = ScalarTypeKind::Invalid;
return;
@@ -1150,7 +1157,7 @@ void RVVIntrinsic::updateNamesAndPolicy(
SmallVector<PrototypeDescriptor> parsePrototypes(StringRef Prototypes) {
SmallVector<PrototypeDescriptor> PrototypeDescriptors;
- const StringRef Primaries("evwqom0ztul");
+ const StringRef Primaries("evwqo4m0ztulf");
while (!Prototypes.empty()) {
size_t Idx = 0;
// Skip over complex prototype because it could contain primitive type
diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_x_f_qf.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_x_f_qf.c
new file mode 100644
index 000000000000000..9b6e2f60f3fc9e8
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_x_f_qf.c
@@ -0,0 +1,98 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvfnrclipxfqf \
+// RUN: -disable-O0-optnone -emit-llvm %s -o - | \
+// RUN: opt -S -passes=mem2reg | FileCheck %s
+
+#include <sifive_vector.h>
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf8(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 1 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.nxv1i8.nxv1f32.i64(<vscale x 1 x i8> poison, <vscale x 1 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 7, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 1 x i8> [[TMP0]]
+//
+vint8mf8_t test_sf_vfnrclip_x_f_qf_i8mf8(vfloat32mf2_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf8(vs2, rs1, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 2 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.nxv2i8.nxv2f32.i64(<vscale x 2 x i8> poison, <vscale x 2 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 7, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 2 x i8> [[TMP0]]
+//
+vint8mf4_t test_sf_vfnrclip_x_f_qf_i8mf4(vfloat32m1_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf4(vs2, rs1, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 4 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.nxv4i8.nxv4f32.i64(<vscale x 4 x i8> poison, <vscale x 4 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 7, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 4 x i8> [[TMP0]]
+//
+vint8mf2_t test_sf_vfnrclip_x_f_qf_i8mf2(vfloat32m2_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf2(vs2, rs1, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 8 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.nxv8i8.nxv8f32.i64(<vscale x 8 x i8> poison, <vscale x 8 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 7, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 8 x i8> [[TMP0]]
+//
+vint8m1_t test_sf_vfnrclip_x_f_qf_i8m1(vfloat32m4_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8m1(vs2, rs1, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 16 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.nxv16i8.nxv16f32.i64(<vscale x 16 x i8> poison, <vscale x 16 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 7, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP0]]
+//
+vint8m2_t test_sf_vfnrclip_x_f_qf_i8m2(vfloat32m8_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8m2(vs2, rs1, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf8_m(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 1 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.mask.nxv1i8.nxv1f32.i64(<vscale x 1 x i8> poison, <vscale x 1 x float> [[VS2:%.*]], float [[RS1:%.*]], <vscale x 1 x i1> [[MASK:%.*]], i64 7, i64 [[VL:%.*]], i64 3)
+// CHECK-NEXT: ret <vscale x 1 x i8> [[TMP0]]
+//
+vint8mf8_t test_sf_vfnrclip_x_f_qf_i8mf8_m(vbool64_t mask, vfloat32mf2_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf8_m(mask, vs2, rs1, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf4_m(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 2 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.mask.nxv2i8.nxv2f32.i64(<vscale x 2 x i8> poison, <vscale x 2 x float> [[VS2:%.*]], float [[RS1:%.*]], <vscale x 2 x i1> [[MASK:%.*]], i64 7, i64 [[VL:%.*]], i64 3)
+// CHECK-NEXT: ret <vscale x 2 x i8> [[TMP0]]
+//
+vint8mf4_t test_sf_vfnrclip_x_f_qf_i8mf4_m(vbool32_t mask, vfloat32m1_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf4_m(mask, vs2, rs1, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf2_m(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 4 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.mask.nxv4i8.nxv4f32.i64(<vscale x 4 x i8> poison, <vscale x 4 x float> [[VS2:%.*]], float [[RS1:%.*]], <vscale x 4 x i1> [[MASK:%.*]], i64 7, i64 [[VL:%.*]], i64 3)
+// CHECK-NEXT: ret <vscale x 4 x i8> [[TMP0]]
+//
+vint8mf2_t test_sf_vfnrclip_x_f_qf_i8mf2_m(vbool16_t mask, vfloat32m2_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf2_m(mask, vs2, rs1, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m1_m(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 8 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.mask.nxv8i8.nxv8f32.i64(<vscale x 8 x i8> poison, <vscale x 8 x float> [[VS2:%.*]], float [[RS1:%.*]], <vscale x 8 x i1> [[MASK:%.*]], i64 7, i64 [[VL:%.*]], i64 3)
+// CHECK-NEXT: ret <vscale x 8 x i8> [[TMP0]]
+//
+vint8m1_t test_sf_vfnrclip_x_f_qf_i8m1_m(vbool8_t mask, vfloat32m4_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8m1_m(mask, vs2, rs1, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m2_m(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 16 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.mask.nxv16i8.nxv16f32.i64(<vscale x 16 x i8> poison, <vscale x 16 x float> [[VS2:%.*]], float [[RS1:%.*]], <vscale x 16 x i1> [[MASK:%.*]], i64 7, i64 [[VL:%.*]], i64 3)
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP0]]
+//
+vint8m2_t test_sf_vfnrclip_x_f_qf_i8m2_m(vbool4_t mask, vfloat32m8_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8m2_m(mask, vs2, rs1, vl);
+}
+
diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_x_f_qf_rm.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_x_f_qf_rm.c
new file mode 100644
index 000000000000000..5e4a52ca5f87238
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_x_f_qf_rm.c
@@ -0,0 +1,98 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvfnrclipxfqf \
+// RUN: -disable-O0-optnone -emit-llvm %s -o - | \
+// RUN: opt -S -passes=mem2reg | FileCheck %s
+
+#include <sifive_vector.h>
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf8(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 1 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.nxv1i8.nxv1f32.i64(<vscale x 1 x i8> poison, <vscale x 1 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 2, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 1 x i8> [[TMP0]]
+//
+vint8mf8_t test_sf_vfnrclip_x_f_qf_i8mf8(vfloat32mf2_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf8_rm(vs2, rs1, 2, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 2 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.nxv2i8.nxv2f32.i64(<vscale x 2 x i8> poison, <vscale x 2 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 2, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 2 x i8> [[TMP0]]
+//
+vint8mf4_t test_sf_vfnrclip_x_f_qf_i8mf4(vfloat32m1_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf4_rm(vs2, rs1, 2, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 4 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.nxv4i8.nxv4f32.i64(<vscale x 4 x i8> poison, <vscale x 4 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 2, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 4 x i8> [[TMP0]]
+//
+vint8mf2_t test_sf_vfnrclip_x_f_qf_i8mf2(vfloat32m2_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf2_rm(vs2, rs1, 2, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 8 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.nxv8i8.nxv8f32.i64(<vscale x 8 x i8> poison, <vscale x 8 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 2, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 8 x i8> [[TMP0]]
+//
+vint8m1_t test_sf_vfnrclip_x_f_qf_i8m1(vfloat32m4_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8m1_rm(vs2, rs1, 2, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 16 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.nxv16i8.nxv16f32.i64(<vscale x 16 x i8> poison, <vscale x 16 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 2, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP0]]
+//
+vint8m2_t test_sf_vfnrclip_x_f_qf_i8m2(vfloat32m8_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8m2_rm(vs2, rs1, 2, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf8_m(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 1 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.mask.nxv1i8.nxv1f32.i64(<vscale x 1 x i8> poison, <vscale x 1 x float> [[VS2:%.*]], float [[RS1:%.*]], <vscale x 1 x i1> [[MASK:%.*]], i64 2, i64 [[VL:%.*]], i64 3)
+// CHECK-NEXT: ret <vscale x 1 x i8> [[TMP0]]
+//
+vint8mf8_t test_sf_vfnrclip_x_f_qf_i8mf8_m(vbool64_t mask, vfloat32mf2_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf8_rm_m(mask, vs2, rs1, 2, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf4_m(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 2 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.mask.nxv2i8.nxv2f32.i64(<vscale x 2 x i8> poison, <vscale x 2 x float> [[VS2:%.*]], float [[RS1:%.*]], <vscale x 2 x i1> [[MASK:%.*]], i64 2, i64 [[VL:%.*]], i64 3)
+// CHECK-NEXT: ret <vscale x 2 x i8> [[TMP0]]
+//
+vint8mf4_t test_sf_vfnrclip_x_f_qf_i8mf4_m(vbool32_t mask, vfloat32m1_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf4_rm_m(mask, vs2, rs1, 2, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf2_m(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 4 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.mask.nxv4i8.nxv4f32.i64(<vscale x 4 x i8> poison, <vscale x 4 x float> [[VS2:%.*]], float [[RS1:%.*]], <vscale x 4 x i1> [[MASK:%.*]], i64 2, i64 [[VL:%.*]], i64 3)
+// CHECK-NEXT: ret <vscale x 4 x i8> [[TMP0]]
+//
+vint8mf2_t test_sf_vfnrclip_x_f_qf_i8mf2_m(vbool16_t mask, vfloat32m2_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8mf2_rm_m(mask, vs2, rs1, 2, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m1_m(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 8 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.mask.nxv8i8.nxv8f32.i64(<vscale x 8 x i8> poison, <vscale x 8 x float> [[VS2:%.*]], float [[RS1:%.*]], <vscale x 8 x i1> [[MASK:%.*]], i64 2, i64 [[VL:%.*]], i64 3)
+// CHECK-NEXT: ret <vscale x 8 x i8> [[TMP0]]
+//
+vint8m1_t test_sf_vfnrclip_x_f_qf_i8m1_m(vbool8_t mask, vfloat32m4_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8m1_rm_m(mask, vs2, rs1, 2, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m2_m(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 16 x i8> @llvm.riscv.sf.vfnrclip.x.f.qf.mask.nxv16i8.nxv16f32.i64(<vscale x 16 x i8> poison, <vscale x 16 x float> [[VS2:%.*]], float [[RS1:%.*]], <vscale x 16 x i1> [[MASK:%.*]], i64 2, i64 [[VL:%.*]], i64 3)
+// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP0]]
+//
+vint8m2_t test_sf_vfnrclip_x_f_qf_i8m2_m(vbool4_t mask, vfloat32m8_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_x_f_qf_i8m2_rm_m(mask, vs2, rs1, 2, vl);
+}
+
diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_xu_f_qf.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_xu_f_qf.c
new file mode 100644
index 000000000000000..266356e07f0ba08
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_xu_f_qf.c
@@ -0,0 +1,98 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: riscv-registered-target
+// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvfnrclipxfqf \
+// RUN: -disable-O0-optnone -emit-llvm %s -o - | \
+// RUN: opt -S -passes=mem2reg | FileCheck %s
+
+#include <sifive_vector.h>
+
+// CHECK-LABEL: @test_sf_vfnrclip_xu_f_qf_u8mf8(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 1 x i8> @llvm.riscv.sf.vfnrclip.xu.f.qf.nxv1i8.nxv1f32.i64(<vscale x 1 x i8> poison, <vscale x 1 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 7, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 1 x i8> [[TMP0]]
+//
+vuint8mf8_t test_sf_vfnrclip_xu_f_qf_u8mf8(vfloat32mf2_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_xu_f_qf_u8mf8(vs2, rs1, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_xu_f_qf_u8mf4(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 2 x i8> @llvm.riscv.sf.vfnrclip.xu.f.qf.nxv2i8.nxv2f32.i64(<vscale x 2 x i8> poison, <vscale x 2 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 7, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 2 x i8> [[TMP0]]
+//
+vuint8mf4_t test_sf_vfnrclip_xu_f_qf_u8mf4(vfloat32m1_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_xu_f_qf_u8mf4(vs2, rs1, vl);
+}
+
+// CHECK-LABEL: @test_sf_vfnrclip_xu_f_qf_u8mf2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: [[TMP0:%.*]] = call <vscale x 4 x i8> @llvm.riscv.sf.vfnrclip.xu.f.qf.nxv4i8.nxv4f32.i64(<vscale x 4 x i8> poison, <vscale x 4 x float> [[VS2:%.*]], float [[RS1:%.*]], i64 7, i64 [[VL:%.*]])
+// CHECK-NEXT: ret <vscale x 4 x i8> [[TMP0]]
+//
+vuint8mf2_t test_sf_vfnrclip_xu_f_qf_u8mf2(vfloat32m2_t vs2, float rs1, size_t vl) {
+ return __riscv_sf_vfnrclip_...
[truncated]
|
You can test this locally with the following command:git-clang-format --diff 945d2e6e603dd9cc5d155a3a34b67ecf17b91b68 d7f4a4e3f78e906d12fb325f3cd7aa6308f7da56 -- clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_x_f_qf.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_x_f_qf_rm.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_xu_f_qf.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfnrclip_xu_f_qf_rm.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vfnrclip_x_f_qf.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vfnrclip_x_f_qf_rm.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vfnrclip_xu_f_qf.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vfnrclip_xu_f_qf_rm.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vfnrclip_x_f_qf.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vfnrclip_x_f_qf_rm.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vfnrclip_xu_f_qf.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vfnrclip_xu_f_qf_rm.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vfnrclip_x_f_qf.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vfnrclip_x_f_qf_rm.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vfnrclip_xu_f_qf.c clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vfnrclip_xu_f_qf_rm.c clang/include/clang/Support/RISCVVIntrinsicUtils.h clang/lib/Sema/SemaRISCVVectorLookup.cpp clang/lib/Support/RISCVVIntrinsicUtils.cpp clang/test/Preprocessor/riscv-target-features.c clang/test/Sema/rvv-required-features-invalid.c clang/test/Sema/rvv-required-features.c clang/utils/TableGen/RISCVVEmitter.cpp llvm/lib/Support/RISCVISAInfo.cpp llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp llvm/unittests/Support/RISCVISAInfoTest.cpp View the diff from clang-format here.diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp
index 64eaf91d9..a2423c151 100644
--- a/clang/utils/TableGen/RISCVVEmitter.cpp
+++ b/clang/utils/TableGen/RISCVVEmitter.cpp
@@ -652,24 +652,25 @@ void RVVEmitter::createRVVIntrinsics(
SR.RequiredExtensions = 0;
for (auto RequiredFeature : RequiredFeatures) {
- RVVRequire RequireExt = StringSwitch<RVVRequire>(RequiredFeature)
- .Case("RV64", RVV_REQ_RV64)
- .Case("ZvfhminOrZvfh", RVV_REQ_ZvfhminOrZvfh)
- .Case("Xsfvcp", RVV_REQ_Xsfvcp)
- .Case("Xsfvfnrclipxfqf", RVV_REQ_Xsfvfnrclipxfqf)
- .Case("Xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq)
- .Case("Xsfvqmaccdod", RVV_REQ_Xsfvqmaccdod)
- .Case("Xsfvqmaccqoq", RVV_REQ_Xsfvqmaccqoq)
- .Case("Zvbb", RVV_REQ_Zvbb)
- .Case("Zvbc", RVV_REQ_Zvbc)
- .Case("Zvkb", RVV_REQ_Zvkb)
- .Case("Zvkg", RVV_REQ_Zvkg)
- .Case("Zvkned", RVV_REQ_Zvkned)
- .Case("Zvknha", RVV_REQ_Zvknha)
- .Case("Zvknhb", RVV_REQ_Zvknhb)
- .Case("Zvksed", RVV_REQ_Zvksed)
- .Case("Zvksh", RVV_REQ_Zvksh)
- .Default(RVV_REQ_None);
+ RVVRequire RequireExt =
+ StringSwitch<RVVRequire>(RequiredFeature)
+ .Case("RV64", RVV_REQ_RV64)
+ .Case("ZvfhminOrZvfh", RVV_REQ_ZvfhminOrZvfh)
+ .Case("Xsfvcp", RVV_REQ_Xsfvcp)
+ .Case("Xsfvfnrclipxfqf", RVV_REQ_Xsfvfnrclipxfqf)
+ .Case("Xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq)
+ .Case("Xsfvqmaccdod", RVV_REQ_Xsfvqmaccdod)
+ .Case("Xsfvqmaccqoq", RVV_REQ_Xsfvqmaccqoq)
+ .Case("Zvbb", RVV_REQ_Zvbb)
+ .Case("Zvbc", RVV_REQ_Zvbc)
+ .Case("Zvkb", RVV_REQ_Zvkb)
+ .Case("Zvkg", RVV_REQ_Zvkg)
+ .Case("Zvkned", RVV_REQ_Zvkned)
+ .Case("Zvknha", RVV_REQ_Zvknha)
+ .Case("Zvknhb", RVV_REQ_Zvknhb)
+ .Case("Zvksed", RVV_REQ_Zvksed)
+ .Case("Zvksh", RVV_REQ_Zvksh)
+ .Default(RVV_REQ_None);
assert(RequireExt != RVV_REQ_None && "Unrecognized required feature?");
SR.RequiredExtensions |= RequireExt;
}
|
f21a58a
to
788d560
Compare
ping |
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.
LGTM
FP32-to-int8 Ranged Clip Instructions https://sifive.cdn.prismic.io/sifive/0aacff47-f530-43dc-8446-5caa2260ece0_xsfvfnrclipxfqf-spec.pdf
eb0dda1
to
d7f4a4e
Compare
FP32-to-int8 Ranged Clip Instructions
https://sifive.cdn.prismic.io/sifive/0aacff47-f530-43dc-8446-5caa2260ece0_xsfvfnrclipxfqf-spec.pdf