Skip to content

Commit 180004b

Browse files
authored
[Clang][XTHeadVector] Fix __riscv_v_elen and __riscv_v_elen_fp (llvm#115)
1 parent 962c56c commit 180004b

File tree

7 files changed

+131
-12
lines changed

7 files changed

+131
-12
lines changed

.github/workflows/ruyisdk-qemu-rvv-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ jobs:
104104
pushd rvv-intrinsic-doc/examples
105105
TESTS=(
106106
# rvv_branch.c
107-
# rvv_index.c
107+
rvv_index.c
108108
# rvv_matmul.c
109109
rvv_memcpy.c
110110
# rvv_reduce.c

clang/include/clang/Basic/riscv_vector_xtheadv_wrappers.td

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4976,6 +4976,30 @@ let HeaderCode =
49764976
#define __riscv_vfredsum_vs_f64m2_f64m1_m(mask, vector, scalar, vl) __riscv_th_vfredsum_vs_f64m2_f64m1_m(mask, vector, scalar, vl)
49774977
#define __riscv_vfredsum_vs_f64m4_f64m1_m(mask, vector, scalar, vl) __riscv_th_vfredsum_vs_f64m4_f64m1_m(mask, vector, scalar, vl)
49784978
#define __riscv_vfredsum_vs_f64m8_f64m1_m(mask, vector, scalar, vl) __riscv_th_vfredsum_vs_f64m8_f64m1_m(mask, vector, scalar, vl)
4979+
#define __riscv_vfredusum_vs_f16m1_f16m1(vector, scalar, vl) __riscv_vfredsum_vs_f16m1_f16m1(vector, scalar, vl)
4980+
#define __riscv_vfredusum_vs_f16m2_f16m1(vector, scalar, vl) __riscv_vfredsum_vs_f16m2_f16m1(vector, scalar, vl)
4981+
#define __riscv_vfredusum_vs_f16m4_f16m1(vector, scalar, vl) __riscv_vfredsum_vs_f16m4_f16m1(vector, scalar, vl)
4982+
#define __riscv_vfredusum_vs_f16m8_f16m1(vector, scalar, vl) __riscv_vfredsum_vs_f16m8_f16m1(vector, scalar, vl)
4983+
#define __riscv_vfredusum_vs_f32m1_f32m1(vector, scalar, vl) __riscv_vfredsum_vs_f32m1_f32m1(vector, scalar, vl)
4984+
#define __riscv_vfredusum_vs_f32m2_f32m1(vector, scalar, vl) __riscv_vfredsum_vs_f32m2_f32m1(vector, scalar, vl)
4985+
#define __riscv_vfredusum_vs_f32m4_f32m1(vector, scalar, vl) __riscv_vfredsum_vs_f32m4_f32m1(vector, scalar, vl)
4986+
#define __riscv_vfredusum_vs_f32m8_f32m1(vector, scalar, vl) __riscv_vfredsum_vs_f32m8_f32m1(vector, scalar, vl)
4987+
#define __riscv_vfredusum_vs_f64m1_f64m1(vector, scalar, vl) __riscv_vfredsum_vs_f64m1_f64m1(vector, scalar, vl)
4988+
#define __riscv_vfredusum_vs_f64m2_f64m1(vector, scalar, vl) __riscv_vfredsum_vs_f64m2_f64m1(vector, scalar, vl)
4989+
#define __riscv_vfredusum_vs_f64m4_f64m1(vector, scalar, vl) __riscv_vfredsum_vs_f64m4_f64m1(vector, scalar, vl)
4990+
#define __riscv_vfredusum_vs_f64m8_f64m1(vector, scalar, vl) __riscv_vfredsum_vs_f64m8_f64m1(vector, scalar, vl)
4991+
#define __riscv_vfredusum_vs_f16m1_f16m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f16m1_f16m1_m(mask, vector, scalar, vl)
4992+
#define __riscv_vfredusum_vs_f16m2_f16m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f16m2_f16m1_m(mask, vector, scalar, vl)
4993+
#define __riscv_vfredusum_vs_f16m4_f16m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f16m4_f16m1_m(mask, vector, scalar, vl)
4994+
#define __riscv_vfredusum_vs_f16m8_f16m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f16m8_f16m1_m(mask, vector, scalar, vl)
4995+
#define __riscv_vfredusum_vs_f32m1_f32m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f32m1_f32m1_m(mask, vector, scalar, vl)
4996+
#define __riscv_vfredusum_vs_f32m2_f32m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f32m2_f32m1_m(mask, vector, scalar, vl)
4997+
#define __riscv_vfredusum_vs_f32m4_f32m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f32m4_f32m1_m(mask, vector, scalar, vl)
4998+
#define __riscv_vfredusum_vs_f32m8_f32m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f32m8_f32m1_m(mask, vector, scalar, vl)
4999+
#define __riscv_vfredusum_vs_f64m1_f64m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f64m1_f64m1_m(mask, vector, scalar, vl)
5000+
#define __riscv_vfredusum_vs_f64m2_f64m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f64m2_f64m1_m(mask, vector, scalar, vl)
5001+
#define __riscv_vfredusum_vs_f64m4_f64m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f64m4_f64m1_m(mask, vector, scalar, vl)
5002+
#define __riscv_vfredusum_vs_f64m8_f64m1_m(mask, vector, scalar, vl) __riscv_vfredsum_vs_f64m8_f64m1_m(mask, vector, scalar, vl)
49795003
#define __riscv_vfwredosum_vs_f16m1_f32m1(vector, scalar, vl) __riscv_th_vfwredosum_vs_f16m1_f32m1(vector, scalar, vl)
49805004
#define __riscv_vfwredosum_vs_f16m2_f32m1(vector, scalar, vl) __riscv_th_vfwredosum_vs_f16m2_f32m1(vector, scalar, vl)
49815005
#define __riscv_vfwredosum_vs_f16m4_f32m1(vector, scalar, vl) __riscv_th_vfwredosum_vs_f16m4_f32m1(vector, scalar, vl)

clang/lib/Basic/Targets/RISCV.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,11 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
185185
Builder.defineMacro("__riscv_fsqrt");
186186
}
187187

188-
if (MinVLen) {
189-
Builder.defineMacro("__riscv_v_min_vlen", Twine(MinVLen));
188+
auto HasXTHeadVector = ISAInfo->hasExtension("xtheadvector");
189+
190+
if (MinVLen || HasXTHeadVector) {
191+
if (MinVLen)
192+
Builder.defineMacro("__riscv_v_min_vlen", Twine(MinVLen));
190193
Builder.defineMacro("__riscv_v_elen", Twine(MaxELen));
191194
Builder.defineMacro("__riscv_v_elen_fp", Twine(MaxELenFp));
192195
}
@@ -200,7 +203,7 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
200203
Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 12)));
201204
}
202205

203-
if (ISAInfo->hasExtension("xtheadvector")) {
206+
if (HasXTHeadVector) {
204207
// https://github.com/riscv-non-isa/rvv-intrinsic-doc/pull/298/files
205208
Builder.defineMacro("__riscv_th_v_intrinsic", Twine(getVersionValue(0, 11)));
206209
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2
2+
// RUN: %clang_cc1 -triple riscv64 -target-feature +xtheadvector \
3+
// RUN: -disable-O0-optnone -emit-llvm %s -o - | \
4+
// RUN: opt -S -passes=mem2reg | \
5+
// RUN: FileCheck --check-prefix=CHECK-IR %s
6+
7+
#include <riscv_vector.h>
8+
9+
// CHECK-IR-LABEL: define dso_local void @index_vec
10+
// CHECK-IR-SAME: (ptr noundef [[A:%.*]], ptr noundef [[B:%.*]], ptr noundef [[C:%.*]], i32 noundef signext [[N:%.*]]) #[[ATTR0:[0-9]+]] {
11+
// CHECK-IR-NEXT: entry:
12+
// CHECK-IR-NEXT: [[TMP0:%.*]] = call i64 @llvm.riscv.th.vsetvlmax.i64(i64 2, i64 0)
13+
// CHECK-IR-NEXT: [[TMP1:%.*]] = call <vscale x 2 x i32> @llvm.riscv.th.vid.nxv2i32.i64(<vscale x 2 x i32> poison, i64 [[TMP0]])
14+
// CHECK-IR-NEXT: br label [[FOR_COND:%.*]]
15+
// CHECK-IR: for.cond:
16+
// CHECK-IR-NEXT: [[VEC_I_0:%.*]] = phi <vscale x 2 x i32> [ [[TMP1]], [[ENTRY:%.*]] ], [ [[TMP7:%.*]], [[FOR_INC:%.*]] ]
17+
// CHECK-IR-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[CONV3:%.*]], [[FOR_INC]] ]
18+
// CHECK-IR-NEXT: [[C_ADDR_0:%.*]] = phi ptr [ [[C]], [[ENTRY]] ], [ [[ADD_PTR5:%.*]], [[FOR_INC]] ]
19+
// CHECK-IR-NEXT: [[B_ADDR_0:%.*]] = phi ptr [ [[B]], [[ENTRY]] ], [ [[ADD_PTR4:%.*]], [[FOR_INC]] ]
20+
// CHECK-IR-NEXT: [[A_ADDR_0:%.*]] = phi ptr [ [[A]], [[ENTRY]] ], [ [[ADD_PTR:%.*]], [[FOR_INC]] ]
21+
// CHECK-IR-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N_ADDR_0]], 0
22+
// CHECK-IR-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
23+
// CHECK-IR: for.body:
24+
// CHECK-IR-NEXT: [[CONV:%.*]] = sext i32 [[N_ADDR_0]] to i64
25+
// CHECK-IR-NEXT: [[TMP2:%.*]] = call i64 @llvm.riscv.th.vsetvl.i64(i64 [[CONV]], i64 3, i64 1)
26+
// CHECK-IR-NEXT: [[TMP3:%.*]] = call <vscale x 2 x double> @llvm.riscv.th.vfwcvt.f.xu.v.nxv2f64.nxv2i32.i64(<vscale x 2 x double> poison, <vscale x 2 x i32> [[VEC_I_0]], i64 [[TMP2]])
27+
// CHECK-IR-NEXT: [[TMP4:%.*]] = call <vscale x 2 x double> @llvm.riscv.th.vle.nxv2f64.i64(<vscale x 2 x double> poison, ptr [[B_ADDR_0]], i64 [[TMP2]])
28+
// CHECK-IR-NEXT: [[TMP5:%.*]] = call <vscale x 2 x double> @llvm.riscv.th.vle.nxv2f64.i64(<vscale x 2 x double> poison, ptr [[C_ADDR_0]], i64 [[TMP2]])
29+
// CHECK-IR-NEXT: [[TMP6:%.*]] = call <vscale x 2 x double> @llvm.riscv.th.vfmadd.nxv2f64.nxv2f64.i64(<vscale x 2 x double> [[TMP5]], <vscale x 2 x double> [[TMP3]], <vscale x 2 x double> [[TMP4]], i64 7, i64 [[TMP2]])
30+
// CHECK-IR-NEXT: call void @llvm.riscv.th.vse.nxv2f64.i64(<vscale x 2 x double> [[TMP6]], ptr [[A_ADDR_0]], i64 [[TMP2]])
31+
// CHECK-IR-NEXT: [[CONV1:%.*]] = trunc i64 [[TMP2]] to i32
32+
// CHECK-IR-NEXT: [[TMP7]] = call <vscale x 2 x i32> @llvm.riscv.th.vadd.nxv2i32.i32.i64(<vscale x 2 x i32> poison, <vscale x 2 x i32> [[VEC_I_0]], i32 [[CONV1]], i64 [[TMP2]])
33+
// CHECK-IR-NEXT: br label [[FOR_INC]]
34+
// CHECK-IR: for.inc:
35+
// CHECK-IR-NEXT: [[CONV2:%.*]] = sext i32 [[N_ADDR_0]] to i64
36+
// CHECK-IR-NEXT: [[SUB:%.*]] = sub i64 [[CONV2]], [[TMP2]]
37+
// CHECK-IR-NEXT: [[CONV3]] = trunc i64 [[SUB]] to i32
38+
// CHECK-IR-NEXT: [[ADD_PTR]] = getelementptr inbounds double, ptr [[A_ADDR_0]], i64 [[TMP2]]
39+
// CHECK-IR-NEXT: [[ADD_PTR4]] = getelementptr inbounds double, ptr [[B_ADDR_0]], i64 [[TMP2]]
40+
// CHECK-IR-NEXT: [[ADD_PTR5]] = getelementptr inbounds double, ptr [[C_ADDR_0]], i64 [[TMP2]]
41+
// CHECK-IR-NEXT: br label [[FOR_COND]], !llvm.loop [[LOOP4:![0-9]+]]
42+
// CHECK-IR: for.end:
43+
// CHECK-IR-NEXT: ret void
44+
//
45+
void index_vec(double *a, double *b, double *c, int n) {
46+
size_t vlmax = __riscv_vsetvlmax_e32m1();
47+
vuint32m1_t vec_i = __riscv_vid_v_u32m1(vlmax);
48+
for (size_t vl; n > 0; n -= vl, a += vl, b += vl, c += vl) {
49+
vl = __riscv_vsetvl_e64m2(n);
50+
51+
vfloat64m2_t vec_i_double = __riscv_vfwcvt_f_xu_v_f64m2(vec_i, vl);
52+
53+
vfloat64m2_t vec_b = __riscv_vle64_v_f64m2(b, vl);
54+
vfloat64m2_t vec_c = __riscv_vle64_v_f64m2(c, vl);
55+
56+
vfloat64m2_t vec_a = __riscv_vfmadd_vv_f64m2(vec_c, vec_i_double, vec_b, vl);
57+
__riscv_vse64_v_f64m2(a, vec_a, vl);
58+
59+
vec_i = __riscv_vadd_vx_u32m1(vec_i, vl, vl);
60+
}
61+
}

clang/test/Preprocessor/riscv-target-features.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,18 @@
231231
// CHECK-V0P7-EXT: __riscv_th_v_intrinsic 11000{{$}}
232232
// CHECK-V0P7-EXT: __riscv_xtheadvector 1000000{{$}}
233233

234+
// RUN: %clang -target riscv32-unknown-linux-gnu \
235+
// RUN: -march=rv32i_xtheadvector -x c -E -dM %s \
236+
// RUN: -o - | FileCheck --check-prefix=CHECK-V0P7-EXT-RV32 %s
237+
// CHECK-V0P7-EXT-RV32: __riscv_v_elen 32
238+
// CHECK-V0P7-EXT-RV32: __riscv_v_elen_fp 0
239+
240+
// RUN: %clang -target riscv64-unknown-linux-gnu \
241+
// RUN: -march=rv64i_xtheadvector -x c -E -dM %s \
242+
// RUN: -o - | FileCheck --check-prefix=CHECK-V0P7-EXT-RV64 %s
243+
// CHECK-V0P7-EXT-RV64: __riscv_v_elen 64
244+
// CHECK-V0P7-EXT-RV64: __riscv_v_elen_fp 0
245+
234246
// RUN: %clang -target riscv32-unknown-linux-gnu \
235247
// RUN: -march=rv32izfhmin1p0 -x c -E -dM %s \
236248
// RUN: -o - | FileCheck --check-prefix=CHECK-ZFHMIN-EXT %s

llvm/lib/Support/RISCVISAInfo.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,6 +1199,11 @@ void RISCVISAInfo::updateMinVLen() {
11991199
}
12001200

12011201
void RISCVISAInfo::updateMaxELen() {
1202+
if (Exts.count("xtheadvector")) {
1203+
MaxELen = XLen;
1204+
MaxELenFp = FLen;
1205+
return;
1206+
}
12021207
// handles EEW restriction by sub-extension zve
12031208
for (auto const &Ext : Exts) {
12041209
StringRef ExtName = Ext.first;

llvm/unittests/Support/RISCVISAInfoTest.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,28 @@ TEST(ParseNormalizedArchString, AcceptsArbitraryExtensionsAndVersions) {
8989
}
9090

9191
TEST(ParseNormalizedArchString, UpdatesFLenMinVLenMaxELen) {
92-
auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(
93-
"rv64i2p0_d2p0_zvl64b1p0_zve64d1p0");
94-
ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
95-
RISCVISAInfo &Info = **MaybeISAInfo;
96-
EXPECT_EQ(Info.getXLen(), 64U);
97-
EXPECT_EQ(Info.getFLen(), 64U);
98-
EXPECT_EQ(Info.getMinVLen(), 64U);
99-
EXPECT_EQ(Info.getMaxELen(), 64U);
92+
{
93+
auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(
94+
"rv64i2p0_d2p0_zvl64b1p0_zve64d1p0");
95+
ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
96+
RISCVISAInfo &Info = **MaybeISAInfo;
97+
EXPECT_EQ(Info.getXLen(), 64U);
98+
EXPECT_EQ(Info.getFLen(), 64U);
99+
EXPECT_EQ(Info.getMinVLen(), 64U);
100+
EXPECT_EQ(Info.getMaxELen(), 64U);
101+
}
102+
103+
{
104+
auto MaybeISAInfo = RISCVISAInfo::parseNormalizedArchString(
105+
"rv64i2p0_d2p0_xtheadvector1p0");
106+
ASSERT_THAT_EXPECTED(MaybeISAInfo, Succeeded());
107+
RISCVISAInfo &Info = **MaybeISAInfo;
108+
EXPECT_EQ(Info.getXLen(), 64U);
109+
EXPECT_EQ(Info.getFLen(), 64U);
110+
EXPECT_EQ(Info.getMinVLen(), 0U);
111+
EXPECT_EQ(Info.getMaxELen(), 64U);
112+
EXPECT_EQ(Info.getMaxELenFp(), 64U);
113+
}
100114
}
101115

102116
TEST(ParseArchString, RejectsUpperCase) {

0 commit comments

Comments
 (0)