diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td index 6adc600313414..c1380863ba82b 100644 --- a/clang/include/clang/Basic/riscv_vector.td +++ b/clang/include/clang/Basic/riscv_vector.td @@ -467,10 +467,6 @@ defvar EEWList = [["8", "(Log2EEW:3)"], ["32", "(Log2EEW:5)"], ["64", "(Log2EEW:6)"]]; -class IsFloat { - bit val = !or(!eq(type, "x"), !eq(type, "f"), !eq(type, "d")); -} - let SupportOverloading = false, MaskedPolicyScheme = NonePolicy in { class RVVVLEMaskBuiltin : RVVOutBuiltin<"m", "mPCUe", "c"> { diff --git a/clang/include/clang/Basic/riscv_vector_common.td b/clang/include/clang/Basic/riscv_vector_common.td index e276e4c3c409b..f936671a1f81d 100644 --- a/clang/include/clang/Basic/riscv_vector_common.td +++ b/clang/include/clang/Basic/riscv_vector_common.td @@ -244,3 +244,7 @@ class RVVBuiltin { + bit val = !or(!eq(type, "x"), !eq(type, "f"), !eq(type, "d")); +} diff --git a/clang/include/clang/Basic/riscv_vector_xtheadv.td b/clang/include/clang/Basic/riscv_vector_xtheadv.td index 09b0fe6366d38..e763ed9949160 100644 --- a/clang/include/clang/Basic/riscv_vector_xtheadv.td +++ b/clang/include/clang/Basic/riscv_vector_xtheadv.td @@ -14,9 +14,9 @@ include "riscv_vector_common.td" -class XRVVBuiltin - : RVVBuiltin { +class RVVOutBuiltin + : RVVBuiltin { + let IntrinsicTypes = [-1]; } multiclass RVVBuiltinSet; + def : RVVBuiltin; } } } @@ -55,7 +55,7 @@ multiclass RVVIntBinBuiltinSet //===----------------------------------------------------------------------===// -// 6. Configuration-Setting Instructions +// 6. Configuration-Setting and Utility //===----------------------------------------------------------------------===// // Define vread_csr&vwrite_csr described in RVV intrinsics doc. @@ -170,7 +170,73 @@ let HasBuiltinAlias = false, } //===----------------------------------------------------------------------===// -// 12. Vector Integer Arithmetic Instructions +// 7. Vector Loads and Stores +//===----------------------------------------------------------------------===// + +let SupportOverloading = false, + UnMaskedPolicyScheme = HasPassthruOperand in { + multiclass RVVVLEBuiltin types> { + let Name = NAME # "_v", + IRName = "th_vle", + MaskedIRName ="th_vle_mask" in { + foreach type = types in { + // `vPCe` is type `const T * -> VectorType` + def : RVVOutBuiltin<"v", "vPCe", type>; + if !not(IsFloat.val) then { + // `UvPCUe` is type `const unsigned T * -> unsigned VectorType` + def : RVVOutBuiltin<"Uv", "UvPCUe", type>; + } + } + } + } +} + +let HasMaskedOffOperand = false, + MaskedPolicyScheme = NonePolicy, + ManualCodegen = [{ + if (IsMasked) { + // Builtin: (mask, ptr, value, vl). Intrinsic: (value, ptr, mask, vl) + std::swap(Ops[0], Ops[2]); + } else { + // Builtin: (ptr, value, vl). Intrinsic: (value, ptr, vl) + std::swap(Ops[0], Ops[1]); + } + Ops[1] = Builder.CreateBitCast(Ops[1], Ops[0]->getType()->getPointerTo()); + if (IsMasked) + IntrinsicTypes = {Ops[0]->getType(), Ops[3]->getType()}; + else + IntrinsicTypes = {Ops[0]->getType(), Ops[2]->getType()}; + }] in { + multiclass RVVVSEBuiltin types> { + let Name = NAME # "_v", + IRName = "th_vse", + MaskedIRName = "th_vse_mask" in { + foreach type = types in { + // `0Pev` is type `T * -> VectorType -> void` + def : RVVBuiltin<"v", "0Pev", type>; + if !not(IsFloat.val) then { + // `0PUeUv` is type `unsigned T * -> unsigned VectorType -> void` + def : RVVBuiltin<"Uv", "0PUeUv", type>; + } + } + } + } +} + +// 7.1. Vector Unit-Stride Operations +// TODO: vlb, vlh, vlw +defm th_vle8: RVVVLEBuiltin<["c"]>; +defm th_vle16: RVVVLEBuiltin<["s","x"]>; +defm th_vle32: RVVVLEBuiltin<["i","f"]>; +defm th_vle64: RVVVLEBuiltin<["l","d"]>; +// TODO: vsb, vsh, vsw +defm th_vse8 : RVVVSEBuiltin<["c"]>; +defm th_vse16: RVVVSEBuiltin<["s","x"]>; +defm th_vse32: RVVVSEBuiltin<["i","f"]>; +defm th_vse64: RVVVSEBuiltin<["l","d"]>; + +//===----------------------------------------------------------------------===// +// 12. Vector Integer Arithmetic Operations //===----------------------------------------------------------------------===// let UnMaskedPolicyScheme = HasPassthruOperand in { diff --git a/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/rvv-example-memcpy.c b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/rvv-example-memcpy.c new file mode 100644 index 0000000000000..0da0fe0447788 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/rvv-example-memcpy.c @@ -0,0 +1,70 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +xtheadvector \ +// RUN: -O0 -emit-llvm %s -o - | FileCheck %s + +#include + +typedef unsigned char uint8_t; + +// CHECK-LABEL: define dso_local void @memcpy_v(ptr noundef %dst, ptr noundef %src, i32 noundef signext %n) #0 { +// CHECK-NEXT: entry: +// CHECK-NEXT: %dst.addr = alloca ptr, align 8 +// CHECK-NEXT: %src.addr = alloca ptr, align 8 +// CHECK-NEXT: %n.addr = alloca i32, align 4 +// CHECK-NEXT: %vl = alloca i32, align 4 +// CHECK-NEXT: %vec_src = alloca , align 1 +// CHECK-NEXT: store ptr %dst, ptr %dst.addr, align 8 +// CHECK-NEXT: store ptr %src, ptr %src.addr, align 8 +// CHECK-NEXT: store i32 %n, ptr %n.addr, align 4 +// CHECK-NEXT: br label %for.cond +// +// CHECK-LABEL: for.cond: ; preds = %for.inc, %entry +// CHECK-NEXT: %0 = load i32, ptr %n.addr, align 4 +// CHECK-NEXT: %cmp = icmp sgt i32 %0, 0 +// CHECK-NEXT: br i1 %cmp, label %for.body, label %for.end +// +// CHECK-LABEL: for.body: ; preds = %for.cond +// CHECK-NEXT: %1 = load i32, ptr %n.addr, align 4 +// CHECK-NEXT: %conv = sext i32 %1 to i64 +// CHECK-NEXT: %2 = call i64 @llvm.riscv.th.vsetvl.i64(i64 %conv, i64 0, i64 2) +// CHECK-NEXT: %conv1 = trunc i64 %2 to i32 +// CHECK-NEXT: store i32 %conv1, ptr %vl, align 4 +// CHECK-NEXT: %3 = load ptr, ptr %src.addr, align 8 +// CHECK-NEXT: %4 = load i32, ptr %vl, align 4 +// CHECK-NEXT: %conv2 = sext i32 %4 to i64 +// CHECK-NEXT: %5 = call @llvm.riscv.th.vle.nxv32i8.i64( poison, ptr %3, i64 %conv2) +// CHECK-NEXT: store %5, ptr %vec_src, align 1 +// CHECK-NEXT: %6 = load ptr, ptr %dst.addr, align 8 +// CHECK-NEXT: %7 = load , ptr %vec_src, align 1 +// CHECK-NEXT: %8 = load i32, ptr %vl, align 4 +// CHECK-NEXT: %conv3 = sext i32 %8 to i64 +// CHECK-NEXT: call void @llvm.riscv.th.vse.nxv32i8.i64( %7, ptr %6, i64 %conv3) +// CHECK-NEXT: br label %for.inc +// +// CHECK-LABEL: for.inc: ; preds = %for.body +// CHECK-NEXT: %9 = load i32, ptr %vl, align 4 +// CHECK-NEXT: %10 = load i32, ptr %n.addr, align 4 +// CHECK-NEXT: %sub = sub nsw i32 %10, %9 +// CHECK-NEXT: store i32 %sub, ptr %n.addr, align 4 +// CHECK-NEXT: %11 = load i32, ptr %vl, align 4 +// CHECK-NEXT: %12 = load ptr, ptr %src.addr, align 8 +// CHECK-NEXT: %idx.ext = sext i32 %11 to i64 +// CHECK-NEXT: %add.ptr = getelementptr inbounds i8, ptr %12, i64 %idx.ext +// CHECK-NEXT: store ptr %add.ptr, ptr %src.addr, align 8 +// CHECK-NEXT: %13 = load i32, ptr %vl, align 4 +// CHECK-NEXT: %14 = load ptr, ptr %dst.addr, align 8 +// CHECK-NEXT: %idx.ext4 = sext i32 %13 to i64 +// CHECK-NEXT: %add.ptr5 = getelementptr inbounds i8, ptr %14, i64 %idx.ext4 +// CHECK-NEXT: store ptr %add.ptr5, ptr %dst.addr, align 8 +// CHECK-NEXT: br label %for.cond, !llvm.loop !4 +// +// CHECK-LABEL: for.end: ; preds = %for.cond +// CHECK-NEXT: ret void +// CHECK-NEXT: } + +void memcpy_v(uint8_t *dst, const uint8_t *src, int n) { + for (int vl; n > 0; n -= vl, src += vl, dst += vl) { + vl = __riscv_vsetvl_e8m4(n); + vuint8m4_t vec_src = __riscv_th_vle8_v_u8m4(src, vl); + __riscv_th_vse8_v_u8m4(dst, vec_src, vl); + } +} diff --git a/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle16.c b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle16.c new file mode 100644 index 0000000000000..7c1bc0c88ef8a --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle16.c @@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +xtheadvector \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_f16m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv4f16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m1_t test_th_vle16_v_f16m1(const _Float16 *base, size_t vl) { + return __riscv_th_vle16_v_f16m1(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_f16m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv8f16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m2_t test_th_vle16_v_f16m2(const _Float16 *base, size_t vl) { + return __riscv_th_vle16_v_f16m2(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_f16m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv16f16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m4_t test_th_vle16_v_f16m4(const _Float16 *base, size_t vl) { + return __riscv_th_vle16_v_f16m4(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_f16m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv32f16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat16m8_t test_th_vle16_v_f16m8(const _Float16 *base, size_t vl) { + return __riscv_th_vle16_v_f16m8(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_i16m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv4i16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m1_t test_th_vle16_v_i16m1(const int16_t *base, size_t vl) { + return __riscv_th_vle16_v_i16m1(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_i16m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv8i16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m2_t test_th_vle16_v_i16m2(const int16_t *base, size_t vl) { + return __riscv_th_vle16_v_i16m2(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_i16m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv16i16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m4_t test_th_vle16_v_i16m4(const int16_t *base, size_t vl) { + return __riscv_th_vle16_v_i16m4(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_i16m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv32i16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint16m8_t test_th_vle16_v_i16m8(const int16_t *base, size_t vl) { + return __riscv_th_vle16_v_i16m8(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_u16m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv4i16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m1_t test_th_vle16_v_u16m1(const uint16_t *base, size_t vl) { + return __riscv_th_vle16_v_u16m1(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_u16m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv8i16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m2_t test_th_vle16_v_u16m2(const uint16_t *base, size_t vl) { + return __riscv_th_vle16_v_u16m2(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_u16m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv16i16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m4_t test_th_vle16_v_u16m4(const uint16_t *base, size_t vl) { + return __riscv_th_vle16_v_u16m4(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle16_v_u16m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv32i16.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint16m8_t test_th_vle16_v_u16m8(const uint16_t *base, size_t vl) { + return __riscv_th_vle16_v_u16m8(base, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle32.c b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle32.c new file mode 100644 index 0000000000000..d94a9ee587ba4 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle32.c @@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +xtheadvector \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_f32m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv2f32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_th_vle32_v_f32m1(const float *base, size_t vl) { + return __riscv_th_vle32_v_f32m1(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_f32m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv4f32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_th_vle32_v_f32m2(const float *base, size_t vl) { + return __riscv_th_vle32_v_f32m2(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_f32m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv8f32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_th_vle32_v_f32m4(const float *base, size_t vl) { + return __riscv_th_vle32_v_f32m4(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_f32m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv16f32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_th_vle32_v_f32m8(const float *base, size_t vl) { + return __riscv_th_vle32_v_f32m8(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_i32m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv2i32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m1_t test_th_vle32_v_i32m1(const int32_t *base, size_t vl) { + return __riscv_th_vle32_v_i32m1(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_i32m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv4i32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m2_t test_th_vle32_v_i32m2(const int32_t *base, size_t vl) { + return __riscv_th_vle32_v_i32m2(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_i32m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv8i32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m4_t test_th_vle32_v_i32m4(const int32_t *base, size_t vl) { + return __riscv_th_vle32_v_i32m4(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_i32m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv16i32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint32m8_t test_th_vle32_v_i32m8(const int32_t *base, size_t vl) { + return __riscv_th_vle32_v_i32m8(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_u32m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv2i32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m1_t test_th_vle32_v_u32m1(const uint32_t *base, size_t vl) { + return __riscv_th_vle32_v_u32m1(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_u32m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv4i32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m2_t test_th_vle32_v_u32m2(const uint32_t *base, size_t vl) { + return __riscv_th_vle32_v_u32m2(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_u32m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv8i32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m4_t test_th_vle32_v_u32m4(const uint32_t *base, size_t vl) { + return __riscv_th_vle32_v_u32m4(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle32_v_u32m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv16i32.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint32m8_t test_th_vle32_v_u32m8(const uint32_t *base, size_t vl) { + return __riscv_th_vle32_v_u32m8(base, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle64.c b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle64.c new file mode 100644 index 0000000000000..8759f260a8570 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle64.c @@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +xtheadvector \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_f64m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv1f64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m1_t test_th_vle64_v_f64m1(const double *base, size_t vl) { + return __riscv_th_vle64_v_f64m1(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_f64m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv2f64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m2_t test_th_vle64_v_f64m2(const double *base, size_t vl) { + return __riscv_th_vle64_v_f64m2(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_f64m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv4f64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m4_t test_th_vle64_v_f64m4(const double *base, size_t vl) { + return __riscv_th_vle64_v_f64m4(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_f64m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv8f64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat64m8_t test_th_vle64_v_f64m8(const double *base, size_t vl) { + return __riscv_th_vle64_v_f64m8(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_i64m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv1i64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m1_t test_th_vle64_v_i64m1(const int64_t *base, size_t vl) { + return __riscv_th_vle64_v_i64m1(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_i64m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv2i64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m2_t test_th_vle64_v_i64m2(const int64_t *base, size_t vl) { + return __riscv_th_vle64_v_i64m2(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_i64m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv4i64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m4_t test_th_vle64_v_i64m4(const int64_t *base, size_t vl) { + return __riscv_th_vle64_v_i64m4(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_i64m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv8i64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint64m8_t test_th_vle64_v_i64m8(const int64_t *base, size_t vl) { + return __riscv_th_vle64_v_i64m8(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_u64m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv1i64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m1_t test_th_vle64_v_u64m1(const uint64_t *base, size_t vl) { + return __riscv_th_vle64_v_u64m1(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_u64m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv2i64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m2_t test_th_vle64_v_u64m2(const uint64_t *base, size_t vl) { + return __riscv_th_vle64_v_u64m2(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_u64m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv4i64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m4_t test_th_vle64_v_u64m4(const uint64_t *base, size_t vl) { + return __riscv_th_vle64_v_u64m4(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle64_v_u64m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv8i64.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint64m8_t test_th_vle64_v_u64m8(const uint64_t *base, size_t vl) { + return __riscv_th_vle64_v_u64m8(base, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle8.c b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle8.c new file mode 100644 index 0000000000000..8b8ab812283a6 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vle8.c @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +xtheadvector \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_th_vle8_v_i8m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv8i8.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m1_t test_th_vle8_v_i8m1(const int8_t *base, size_t vl) { + return __riscv_th_vle8_v_i8m1(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle8_v_i8m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv16i8.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m2_t test_th_vle8_v_i8m2(const int8_t *base, size_t vl) { + return __riscv_th_vle8_v_i8m2(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle8_v_i8m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv32i8.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m4_t test_th_vle8_v_i8m4(const int8_t *base, size_t vl) { + return __riscv_th_vle8_v_i8m4(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle8_v_i8m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv64i8.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vint8m8_t test_th_vle8_v_i8m8(const int8_t *base, size_t vl) { + return __riscv_th_vle8_v_i8m8(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle8_v_u8m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv8i8.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m1_t test_th_vle8_v_u8m1(const uint8_t *base, size_t vl) { + return __riscv_th_vle8_v_u8m1(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle8_v_u8m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv16i8.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m2_t test_th_vle8_v_u8m2(const uint8_t *base, size_t vl) { + return __riscv_th_vle8_v_u8m2(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle8_v_u8m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv32i8.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m4_t test_th_vle8_v_u8m4(const uint8_t *base, size_t vl) { + return __riscv_th_vle8_v_u8m4(base, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_th_vle8_v_u8m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.th.vle.nxv64i8.i64( poison, ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vuint8m8_t test_th_vle8_v_u8m8(const uint8_t *base, size_t vl) { + return __riscv_th_vle8_v_u8m8(base, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse16.c b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse16.c new file mode 100644 index 0000000000000..b3a1f966e0376 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse16.c @@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +xtheadvector \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_f16m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv4f16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_f16m1(_Float16 *base, vfloat16m1_t value, size_t vl) { + return __riscv_th_vse16_v_f16m1(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_f16m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv8f16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_f16m2(_Float16 *base, vfloat16m2_t value, size_t vl) { + return __riscv_th_vse16_v_f16m2(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_f16m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv16f16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_f16m4(_Float16 *base, vfloat16m4_t value, size_t vl) { + return __riscv_th_vse16_v_f16m4(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_f16m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv32f16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_f16m8(_Float16 *base, vfloat16m8_t value, size_t vl) { + return __riscv_th_vse16_v_f16m8(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_i16m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv4i16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_i16m1(int16_t *base, vint16m1_t value, size_t vl) { + return __riscv_th_vse16_v_i16m1(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_i16m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv8i16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_i16m2(int16_t *base, vint16m2_t value, size_t vl) { + return __riscv_th_vse16_v_i16m2(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_i16m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv16i16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_i16m4(int16_t *base, vint16m4_t value, size_t vl) { + return __riscv_th_vse16_v_i16m4(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_i16m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv32i16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_i16m8(int16_t *base, vint16m8_t value, size_t vl) { + return __riscv_th_vse16_v_i16m8(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_u16m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv4i16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_u16m1(uint16_t *base, vuint16m1_t value, size_t vl) { + return __riscv_th_vse16_v_u16m1(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_u16m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv8i16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_u16m2(uint16_t *base, vuint16m2_t value, size_t vl) { + return __riscv_th_vse16_v_u16m2(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_u16m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv16i16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_u16m4(uint16_t *base, vuint16m4_t value, size_t vl) { + return __riscv_th_vse16_v_u16m4(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse16_v_u16m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv32i16.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse16_v_u16m8(uint16_t *base, vuint16m8_t value, size_t vl) { + return __riscv_th_vse16_v_u16m8(base, value, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse32.c b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse32.c new file mode 100644 index 0000000000000..23292f9c737e2 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse32.c @@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +xtheadvector \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_f32m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv2f32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_f32m1(float *base, vfloat32m1_t value, size_t vl) { + return __riscv_th_vse32_v_f32m1(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_f32m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv4f32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_f32m2(float *base, vfloat32m2_t value, size_t vl) { + return __riscv_th_vse32_v_f32m2(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_f32m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv8f32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_f32m4(float *base, vfloat32m4_t value, size_t vl) { + return __riscv_th_vse32_v_f32m4(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_f32m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv16f32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_f32m8(float *base, vfloat32m8_t value, size_t vl) { + return __riscv_th_vse32_v_f32m8(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_i32m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv2i32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_i32m1(int32_t *base, vint32m1_t value, size_t vl) { + return __riscv_th_vse32_v_i32m1(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_i32m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv4i32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_i32m2(int32_t *base, vint32m2_t value, size_t vl) { + return __riscv_th_vse32_v_i32m2(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_i32m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv8i32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_i32m4(int32_t *base, vint32m4_t value, size_t vl) { + return __riscv_th_vse32_v_i32m4(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_i32m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv16i32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_i32m8(int32_t *base, vint32m8_t value, size_t vl) { + return __riscv_th_vse32_v_i32m8(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_u32m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv2i32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_u32m1(uint32_t *base, vuint32m1_t value, size_t vl) { + return __riscv_th_vse32_v_u32m1(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_u32m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv4i32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_u32m2(uint32_t *base, vuint32m2_t value, size_t vl) { + return __riscv_th_vse32_v_u32m2(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_u32m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv8i32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_u32m4(uint32_t *base, vuint32m4_t value, size_t vl) { + return __riscv_th_vse32_v_u32m4(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse32_v_u32m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv16i32.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse32_v_u32m8(uint32_t *base, vuint32m8_t value, size_t vl) { + return __riscv_th_vse32_v_u32m8(base, value, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse64.c b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse64.c new file mode 100644 index 0000000000000..06dc7d45eebcc --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse64.c @@ -0,0 +1,126 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +xtheadvector \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_f64m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv1f64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_f64m1(double *base, vfloat64m1_t value, size_t vl) { + return __riscv_th_vse64_v_f64m1(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_f64m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv2f64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_f64m2(double *base, vfloat64m2_t value, size_t vl) { + return __riscv_th_vse64_v_f64m2(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_f64m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv4f64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_f64m4(double *base, vfloat64m4_t value, size_t vl) { + return __riscv_th_vse64_v_f64m4(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_f64m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv8f64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_f64m8(double *base, vfloat64m8_t value, size_t vl) { + return __riscv_th_vse64_v_f64m8(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_i64m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv1i64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_i64m1(int64_t *base, vint64m1_t value, size_t vl) { + return __riscv_th_vse64_v_i64m1(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_i64m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv2i64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_i64m2(int64_t *base, vint64m2_t value, size_t vl) { + return __riscv_th_vse64_v_i64m2(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_i64m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv4i64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_i64m4(int64_t *base, vint64m4_t value, size_t vl) { + return __riscv_th_vse64_v_i64m4(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_i64m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv8i64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_i64m8(int64_t *base, vint64m8_t value, size_t vl) { + return __riscv_th_vse64_v_i64m8(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_u64m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv1i64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_u64m1(uint64_t *base, vuint64m1_t value, size_t vl) { + return __riscv_th_vse64_v_u64m1(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_u64m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv2i64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_u64m2(uint64_t *base, vuint64m2_t value, size_t vl) { + return __riscv_th_vse64_v_u64m2(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_u64m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv4i64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_u64m4(uint64_t *base, vuint64m4_t value, size_t vl) { + return __riscv_th_vse64_v_u64m4(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse64_v_u64m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv8i64.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse64_v_u64m8(uint64_t *base, vuint64m8_t value, size_t vl) { + return __riscv_th_vse64_v_u64m8(base, value, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse8.c b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse8.c new file mode 100644 index 0000000000000..8137971e0d8fb --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv0p71-intrinsics-handcrafted/vse8.c @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -triple riscv64 -target-feature +xtheadvector \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | \ +// RUN: opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse8_v_i8m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv8i8.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse8_v_i8m1(int8_t *base, vint8m1_t value, size_t vl) { + return __riscv_th_vse8_v_i8m1(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse8_v_i8m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv16i8.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse8_v_i8m2(int8_t *base, vint8m2_t value, size_t vl) { + return __riscv_th_vse8_v_i8m2(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse8_v_i8m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv32i8.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse8_v_i8m4(int8_t *base, vint8m4_t value, size_t vl) { + return __riscv_th_vse8_v_i8m4(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse8_v_i8m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv64i8.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse8_v_i8m8(int8_t *base, vint8m8_t value, size_t vl) { + return __riscv_th_vse8_v_i8m8(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse8_v_u8m1 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv8i8.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse8_v_u8m1(uint8_t *base, vuint8m1_t value, size_t vl) { + return __riscv_th_vse8_v_u8m1(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse8_v_u8m2 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv16i8.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse8_v_u8m2(uint8_t *base, vuint8m2_t value, size_t vl) { + return __riscv_th_vse8_v_u8m2(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse8_v_u8m4 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv32i8.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse8_v_u8m4(uint8_t *base, vuint8m4_t value, size_t vl) { + return __riscv_th_vse8_v_u8m4(base, value, vl); +} + +// CHECK-RV64-LABEL: define dso_local void @test_th_vse8_v_u8m8 +// CHECK-RV64-SAME: (ptr noundef [[BASE:%.*]], [[VALUE:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: call void @llvm.riscv.th.vse.nxv64i8.i64( [[VALUE]], ptr [[BASE]], i64 [[VL]]) +// CHECK-RV64-NEXT: ret void +// +void test_th_vse8_v_u8m8(uint8_t *base, vuint8m8_t value, size_t vl) { + return __riscv_th_vse8_v_u8m8(base, value, vl); +}