Skip to content

Commit 74f38df

Browse files
authored
[RISCV] Support Xsfvfnrclipxfqf extensions (#68297)
FP32-to-int8 Ranged Clip Instructions https://sifive.cdn.prismic.io/sifive/0aacff47-f530-43dc-8446-5caa2260ece0_xsfvfnrclipxfqf-spec.pdf
1 parent 945d2e6 commit 74f38df

34 files changed

+3047
-14
lines changed

clang/include/clang/Basic/riscv_sifive_vector.td

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ multiclass RVVVQMACCBuiltinSet<list<list<string>> suffixes_prototypes> {
120120
defm NAME : RVVOutOp1Op2BuiltinSet<NAME, "i", suffixes_prototypes>;
121121
}
122122

123+
multiclass RVVVFNRCLIPBuiltinSet<string suffix, string prototype, string type_range> {
124+
let Log2LMUL = [-3, -2, -1, 0, 1, 2],
125+
Name = NAME,
126+
IRName = NAME,
127+
MaskedIRName = NAME # "_mask" in
128+
def : RVVConvBuiltin<suffix, prototype, type_range, NAME>;
129+
}
130+
123131
let UnMaskedPolicyScheme = HasPolicyOperand in
124132
let RequiredFeatures = ["Xsfvqmaccdod"] in {
125133
defm sf_vqmaccu_2x8x2 : RVVVQMACCBuiltinSet<[["", "v", "vv(FixedSEW:8)SUv(FixedSEW:8)Uv"]]>;
@@ -139,3 +147,57 @@ let UnMaskedPolicyScheme = HasPolicyOperand in
139147
let UnMaskedPolicyScheme = HasPolicyOperand in
140148
let RequiredFeatures = ["Xsfvfwmaccqqq"] in
141149
defm sf_vfwmacc_4x4x4 : RVVVFWMACCBuiltinSet<[["", "w", "wwSvv"]]>;
150+
151+
let UnMaskedPolicyScheme = HasPassthruOperand, RequiredFeatures = ["Xsfvfnrclipxfqf"] in {
152+
let ManualCodegen = [{
153+
{
154+
// LLVM intrinsic
155+
// Unmasked: (passthru, vector_in, scalar_in, frm, vl)
156+
// Masked: (passthru, vector_in, scalar_in, mask, frm, vl, policy)
157+
158+
SmallVector<llvm::Value*, 7> Operands;
159+
bool HasMaskedOff = !(
160+
(IsMasked && (PolicyAttrs & RVV_VTA) && (PolicyAttrs & RVV_VMA)) ||
161+
(!IsMasked && PolicyAttrs & RVV_VTA));
162+
bool HasRoundModeOp = IsMasked ?
163+
(HasMaskedOff ? Ops.size() == 6 : Ops.size() == 5) :
164+
(HasMaskedOff ? Ops.size() == 5 : Ops.size() == 4);
165+
166+
unsigned Offset = IsMasked ?
167+
(HasMaskedOff ? 2 : 1) : (HasMaskedOff ? 1 : 0);
168+
169+
if (!HasMaskedOff)
170+
Operands.push_back(llvm::PoisonValue::get(ResultType));
171+
else
172+
Operands.push_back(Ops[IsMasked ? 1 : 0]);
173+
174+
Operands.push_back(Ops[Offset]); // op0
175+
Operands.push_back(Ops[Offset + 1]); // op1
176+
177+
if (IsMasked)
178+
Operands.push_back(Ops[0]); // mask
179+
180+
if (HasRoundModeOp) {
181+
Operands.push_back(Ops[Offset + 2]); // frm
182+
Operands.push_back(Ops[Offset + 3]); // vl
183+
} else {
184+
Operands.push_back(ConstantInt::get(Ops[Offset + 2]->getType(), 7)); // frm
185+
Operands.push_back(Ops[Offset + 2]); // vl
186+
}
187+
188+
if (IsMasked)
189+
Operands.push_back(ConstantInt::get(Ops.back()->getType(), PolicyAttrs));
190+
191+
IntrinsicTypes = {ResultType, Ops[Offset]->getType(), Operands.back()->getType()};
192+
llvm::Function *F = CGM.getIntrinsic(ID, IntrinsicTypes);
193+
return Builder.CreateCall(F, Operands, "");
194+
}
195+
}] in {
196+
let HasFRMRoundModeOp = true in {
197+
defm sf_vfnrclip_x_f_qf : RVVVFNRCLIPBuiltinSet<"v", "vFqfu", "c">;
198+
defm sf_vfnrclip_xu_f_qf : RVVVFNRCLIPBuiltinSet<"Uv", "UvFqfu", "c">;
199+
}
200+
defm sf_vfnrclip_x_f_qf : RVVVFNRCLIPBuiltinSet<"v", "vFqf", "c">;
201+
defm sf_vfnrclip_xu_f_qf : RVVVFNRCLIPBuiltinSet<"Uv", "UvFqf", "c">;
202+
}
203+
}

clang/include/clang/Basic/riscv_vector_common.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
// t: ptrdiff_t, ignores "t"
6767
// u: unsigned long, ignores "t"
6868
// l: long, ignores "t"
69+
// f: float32, ignores "t"
6970
//
7071
// So for instance if t is "i", i.e. int, then "e" will yield int again. "v"
7172
// will yield an RVV vector type (assume LMUL=1), so __rvv_int32m1_t.

clang/include/clang/Support/RISCVVIntrinsicUtils.h

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ enum class BaseTypeModifier : uint8_t {
8585
Ptrdiff,
8686
UnsignedLong,
8787
SignedLong,
88+
Float32
8889
};
8990

9091
// Modifier for type, used for both scalar and vector types.
@@ -485,18 +486,19 @@ enum RVVRequire : uint16_t {
485486
RVV_REQ_RV64 = 1 << 0,
486487
RVV_REQ_ZvfhminOrZvfh = 1 << 1,
487488
RVV_REQ_Xsfvcp = 1 << 2,
488-
RVV_REQ_Xsfvfwmaccqqq = 1 << 3,
489-
RVV_REQ_Xsfvqmaccdod = 1 << 4,
490-
RVV_REQ_Xsfvqmaccqoq = 1 << 5,
491-
RVV_REQ_Zvbb = 1 << 6,
492-
RVV_REQ_Zvbc = 1 << 7,
493-
RVV_REQ_Zvkb = 1 << 8,
494-
RVV_REQ_Zvkg = 1 << 9,
495-
RVV_REQ_Zvkned = 1 << 10,
496-
RVV_REQ_Zvknha = 1 << 11,
497-
RVV_REQ_Zvknhb = 1 << 12,
498-
RVV_REQ_Zvksed = 1 << 13,
499-
RVV_REQ_Zvksh = 1 << 14,
489+
RVV_REQ_Xsfvfnrclipxfqf = 1 << 3,
490+
RVV_REQ_Xsfvfwmaccqqq = 1 << 4,
491+
RVV_REQ_Xsfvqmaccdod = 1 << 5,
492+
RVV_REQ_Xsfvqmaccqoq = 1 << 6,
493+
RVV_REQ_Zvbb = 1 << 7,
494+
RVV_REQ_Zvbc = 1 << 8,
495+
RVV_REQ_Zvkb = 1 << 9,
496+
RVV_REQ_Zvkg = 1 << 10,
497+
RVV_REQ_Zvkned = 1 << 11,
498+
RVV_REQ_Zvknha = 1 << 12,
499+
RVV_REQ_Zvknhb = 1 << 13,
500+
RVV_REQ_Zvksed = 1 << 14,
501+
RVV_REQ_Zvksh = 1 << 15,
500502

501503
LLVM_MARK_AS_BITMASK_ENUM(RVV_REQ_Zvksh)
502504
};

clang/lib/Sema/SemaRISCVVectorLookup.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics(
205205
static const std::pair<const char *, RVVRequire> FeatureCheckList[] = {
206206
{"64bit", RVV_REQ_RV64},
207207
{"xsfvcp", RVV_REQ_Xsfvcp},
208+
{"xsfvfnrclipxfqf", RVV_REQ_Xsfvfnrclipxfqf},
208209
{"xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq},
209210
{"xsfvqmaccdod", RVV_REQ_Xsfvqmaccdod},
210211
{"xsfvqmaccqoq", RVV_REQ_Xsfvqmaccqoq},

clang/lib/Support/RISCVVIntrinsicUtils.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,9 @@ PrototypeDescriptor::parsePrototypeDescriptor(
429429
case 'l':
430430
PT = BaseTypeModifier::SignedLong;
431431
break;
432+
case 'f':
433+
PT = BaseTypeModifier::Float32;
434+
break;
432435
default:
433436
llvm_unreachable("Illegal primitive type transformers!");
434437
}
@@ -665,6 +668,10 @@ void RVVType::applyModifier(const PrototypeDescriptor &Transformer) {
665668
case BaseTypeModifier::SignedLong:
666669
ScalarType = ScalarTypeKind::SignedLong;
667670
break;
671+
case BaseTypeModifier::Float32:
672+
ElementBitwidth = 32;
673+
ScalarType = ScalarTypeKind::Float;
674+
break;
668675
case BaseTypeModifier::Invalid:
669676
ScalarType = ScalarTypeKind::Invalid;
670677
return;
@@ -1149,7 +1156,7 @@ void RVVIntrinsic::updateNamesAndPolicy(
11491156

11501157
SmallVector<PrototypeDescriptor> parsePrototypes(StringRef Prototypes) {
11511158
SmallVector<PrototypeDescriptor> PrototypeDescriptors;
1152-
const StringRef Primaries("evwqom0ztul");
1159+
const StringRef Primaries("evwqom0ztulf");
11531160
while (!Prototypes.empty()) {
11541161
size_t Idx = 0;
11551162
// Skip over complex prototype because it could contain primitive type
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// REQUIRES: riscv-registered-target
3+
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvfnrclipxfqf \
4+
// RUN: -disable-O0-optnone -emit-llvm %s -o - | \
5+
// RUN: opt -S -passes=mem2reg | FileCheck %s
6+
7+
#include <sifive_vector.h>
8+
9+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf8(
10+
// CHECK-NEXT: entry:
11+
// 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:%.*]])
12+
// CHECK-NEXT: ret <vscale x 1 x i8> [[TMP0]]
13+
//
14+
vint8mf8_t test_sf_vfnrclip_x_f_qf_i8mf8(vfloat32mf2_t vs2, float rs1, size_t vl) {
15+
return __riscv_sf_vfnrclip_x_f_qf_i8mf8(vs2, rs1, vl);
16+
}
17+
18+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf4(
19+
// CHECK-NEXT: entry:
20+
// 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:%.*]])
21+
// CHECK-NEXT: ret <vscale x 2 x i8> [[TMP0]]
22+
//
23+
vint8mf4_t test_sf_vfnrclip_x_f_qf_i8mf4(vfloat32m1_t vs2, float rs1, size_t vl) {
24+
return __riscv_sf_vfnrclip_x_f_qf_i8mf4(vs2, rs1, vl);
25+
}
26+
27+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf2(
28+
// CHECK-NEXT: entry:
29+
// 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:%.*]])
30+
// CHECK-NEXT: ret <vscale x 4 x i8> [[TMP0]]
31+
//
32+
vint8mf2_t test_sf_vfnrclip_x_f_qf_i8mf2(vfloat32m2_t vs2, float rs1, size_t vl) {
33+
return __riscv_sf_vfnrclip_x_f_qf_i8mf2(vs2, rs1, vl);
34+
}
35+
36+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m1(
37+
// CHECK-NEXT: entry:
38+
// 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:%.*]])
39+
// CHECK-NEXT: ret <vscale x 8 x i8> [[TMP0]]
40+
//
41+
vint8m1_t test_sf_vfnrclip_x_f_qf_i8m1(vfloat32m4_t vs2, float rs1, size_t vl) {
42+
return __riscv_sf_vfnrclip_x_f_qf_i8m1(vs2, rs1, vl);
43+
}
44+
45+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m2(
46+
// CHECK-NEXT: entry:
47+
// 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:%.*]])
48+
// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP0]]
49+
//
50+
vint8m2_t test_sf_vfnrclip_x_f_qf_i8m2(vfloat32m8_t vs2, float rs1, size_t vl) {
51+
return __riscv_sf_vfnrclip_x_f_qf_i8m2(vs2, rs1, vl);
52+
}
53+
54+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf8_m(
55+
// CHECK-NEXT: entry:
56+
// 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)
57+
// CHECK-NEXT: ret <vscale x 1 x i8> [[TMP0]]
58+
//
59+
vint8mf8_t test_sf_vfnrclip_x_f_qf_i8mf8_m(vbool64_t mask, vfloat32mf2_t vs2, float rs1, size_t vl) {
60+
return __riscv_sf_vfnrclip_x_f_qf_i8mf8_m(mask, vs2, rs1, vl);
61+
}
62+
63+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf4_m(
64+
// CHECK-NEXT: entry:
65+
// 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)
66+
// CHECK-NEXT: ret <vscale x 2 x i8> [[TMP0]]
67+
//
68+
vint8mf4_t test_sf_vfnrclip_x_f_qf_i8mf4_m(vbool32_t mask, vfloat32m1_t vs2, float rs1, size_t vl) {
69+
return __riscv_sf_vfnrclip_x_f_qf_i8mf4_m(mask, vs2, rs1, vl);
70+
}
71+
72+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf2_m(
73+
// CHECK-NEXT: entry:
74+
// 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)
75+
// CHECK-NEXT: ret <vscale x 4 x i8> [[TMP0]]
76+
//
77+
vint8mf2_t test_sf_vfnrclip_x_f_qf_i8mf2_m(vbool16_t mask, vfloat32m2_t vs2, float rs1, size_t vl) {
78+
return __riscv_sf_vfnrclip_x_f_qf_i8mf2_m(mask, vs2, rs1, vl);
79+
}
80+
81+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m1_m(
82+
// CHECK-NEXT: entry:
83+
// 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)
84+
// CHECK-NEXT: ret <vscale x 8 x i8> [[TMP0]]
85+
//
86+
vint8m1_t test_sf_vfnrclip_x_f_qf_i8m1_m(vbool8_t mask, vfloat32m4_t vs2, float rs1, size_t vl) {
87+
return __riscv_sf_vfnrclip_x_f_qf_i8m1_m(mask, vs2, rs1, vl);
88+
}
89+
90+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m2_m(
91+
// CHECK-NEXT: entry:
92+
// 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)
93+
// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP0]]
94+
//
95+
vint8m2_t test_sf_vfnrclip_x_f_qf_i8m2_m(vbool4_t mask, vfloat32m8_t vs2, float rs1, size_t vl) {
96+
return __riscv_sf_vfnrclip_x_f_qf_i8m2_m(mask, vs2, rs1, vl);
97+
}
98+
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
2+
// REQUIRES: riscv-registered-target
3+
// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvfnrclipxfqf \
4+
// RUN: -disable-O0-optnone -emit-llvm %s -o - | \
5+
// RUN: opt -S -passes=mem2reg | FileCheck %s
6+
7+
#include <sifive_vector.h>
8+
9+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf8(
10+
// CHECK-NEXT: entry:
11+
// 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:%.*]])
12+
// CHECK-NEXT: ret <vscale x 1 x i8> [[TMP0]]
13+
//
14+
vint8mf8_t test_sf_vfnrclip_x_f_qf_i8mf8(vfloat32mf2_t vs2, float rs1, size_t vl) {
15+
return __riscv_sf_vfnrclip_x_f_qf_i8mf8_rm(vs2, rs1, 2, vl);
16+
}
17+
18+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf4(
19+
// CHECK-NEXT: entry:
20+
// 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:%.*]])
21+
// CHECK-NEXT: ret <vscale x 2 x i8> [[TMP0]]
22+
//
23+
vint8mf4_t test_sf_vfnrclip_x_f_qf_i8mf4(vfloat32m1_t vs2, float rs1, size_t vl) {
24+
return __riscv_sf_vfnrclip_x_f_qf_i8mf4_rm(vs2, rs1, 2, vl);
25+
}
26+
27+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf2(
28+
// CHECK-NEXT: entry:
29+
// 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:%.*]])
30+
// CHECK-NEXT: ret <vscale x 4 x i8> [[TMP0]]
31+
//
32+
vint8mf2_t test_sf_vfnrclip_x_f_qf_i8mf2(vfloat32m2_t vs2, float rs1, size_t vl) {
33+
return __riscv_sf_vfnrclip_x_f_qf_i8mf2_rm(vs2, rs1, 2, vl);
34+
}
35+
36+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m1(
37+
// CHECK-NEXT: entry:
38+
// 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:%.*]])
39+
// CHECK-NEXT: ret <vscale x 8 x i8> [[TMP0]]
40+
//
41+
vint8m1_t test_sf_vfnrclip_x_f_qf_i8m1(vfloat32m4_t vs2, float rs1, size_t vl) {
42+
return __riscv_sf_vfnrclip_x_f_qf_i8m1_rm(vs2, rs1, 2, vl);
43+
}
44+
45+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m2(
46+
// CHECK-NEXT: entry:
47+
// 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:%.*]])
48+
// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP0]]
49+
//
50+
vint8m2_t test_sf_vfnrclip_x_f_qf_i8m2(vfloat32m8_t vs2, float rs1, size_t vl) {
51+
return __riscv_sf_vfnrclip_x_f_qf_i8m2_rm(vs2, rs1, 2, vl);
52+
}
53+
54+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf8_m(
55+
// CHECK-NEXT: entry:
56+
// 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)
57+
// CHECK-NEXT: ret <vscale x 1 x i8> [[TMP0]]
58+
//
59+
vint8mf8_t test_sf_vfnrclip_x_f_qf_i8mf8_m(vbool64_t mask, vfloat32mf2_t vs2, float rs1, size_t vl) {
60+
return __riscv_sf_vfnrclip_x_f_qf_i8mf8_rm_m(mask, vs2, rs1, 2, vl);
61+
}
62+
63+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf4_m(
64+
// CHECK-NEXT: entry:
65+
// 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)
66+
// CHECK-NEXT: ret <vscale x 2 x i8> [[TMP0]]
67+
//
68+
vint8mf4_t test_sf_vfnrclip_x_f_qf_i8mf4_m(vbool32_t mask, vfloat32m1_t vs2, float rs1, size_t vl) {
69+
return __riscv_sf_vfnrclip_x_f_qf_i8mf4_rm_m(mask, vs2, rs1, 2, vl);
70+
}
71+
72+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8mf2_m(
73+
// CHECK-NEXT: entry:
74+
// 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)
75+
// CHECK-NEXT: ret <vscale x 4 x i8> [[TMP0]]
76+
//
77+
vint8mf2_t test_sf_vfnrclip_x_f_qf_i8mf2_m(vbool16_t mask, vfloat32m2_t vs2, float rs1, size_t vl) {
78+
return __riscv_sf_vfnrclip_x_f_qf_i8mf2_rm_m(mask, vs2, rs1, 2, vl);
79+
}
80+
81+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m1_m(
82+
// CHECK-NEXT: entry:
83+
// 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)
84+
// CHECK-NEXT: ret <vscale x 8 x i8> [[TMP0]]
85+
//
86+
vint8m1_t test_sf_vfnrclip_x_f_qf_i8m1_m(vbool8_t mask, vfloat32m4_t vs2, float rs1, size_t vl) {
87+
return __riscv_sf_vfnrclip_x_f_qf_i8m1_rm_m(mask, vs2, rs1, 2, vl);
88+
}
89+
90+
// CHECK-LABEL: @test_sf_vfnrclip_x_f_qf_i8m2_m(
91+
// CHECK-NEXT: entry:
92+
// 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)
93+
// CHECK-NEXT: ret <vscale x 16 x i8> [[TMP0]]
94+
//
95+
vint8m2_t test_sf_vfnrclip_x_f_qf_i8m2_m(vbool4_t mask, vfloat32m8_t vs2, float rs1, size_t vl) {
96+
return __riscv_sf_vfnrclip_x_f_qf_i8m2_rm_m(mask, vs2, rs1, 2, vl);
97+
}
98+

0 commit comments

Comments
 (0)