diff --git a/clang/include/clang/Basic/riscv_sifive_vector.td b/clang/include/clang/Basic/riscv_sifive_vector.td index fb8561a05a0d4..7b98ac8906667 100644 --- a/clang/include/clang/Basic/riscv_sifive_vector.td +++ b/clang/include/clang/Basic/riscv_sifive_vector.td @@ -104,6 +104,14 @@ let SupportOverloading = false in { } } +multiclass RVVVFWMACCBuiltinSet> suffixes_prototypes> { + let OverloadedName = NAME, + Name = NAME, + HasMasked = false, + Log2LMUL = [-2, -1, 0, 1, 2] in + defm NAME : RVVOutOp1Op2BuiltinSet; +} + multiclass RVVVQMACCBuiltinSet> suffixes_prototypes> { let OverloadedName = NAME, Name = NAME, @@ -127,3 +135,7 @@ let UnMaskedPolicyScheme = HasPolicyOperand in defm sf_vqmaccus_4x8x4 : RVVVQMACCBuiltinSet<[["", "v", "vv(FixedSEW:8)SUv(FixedSEW:8)v"]]>; defm sf_vqmaccsu_4x8x4 : RVVVQMACCBuiltinSet<[["", "v", "vv(FixedSEW:8)Sv(FixedSEW:8)Uv"]]>; } + +let UnMaskedPolicyScheme = HasPolicyOperand in + let RequiredFeatures = ["Xsfvfwmaccqqq"] in + defm sf_vfwmacc_4x4x4 : RVVVFWMACCBuiltinSet<[["", "w", "wwSvv"]]>; diff --git a/clang/include/clang/Support/RISCVVIntrinsicUtils.h b/clang/include/clang/Support/RISCVVIntrinsicUtils.h index c455bb2c45889..3c7064c316863 100644 --- a/clang/include/clang/Support/RISCVVIntrinsicUtils.h +++ b/clang/include/clang/Support/RISCVVIntrinsicUtils.h @@ -485,17 +485,18 @@ enum RVVRequire : uint16_t { RVV_REQ_RV64 = 1 << 0, RVV_REQ_ZvfhminOrZvfh = 1 << 1, RVV_REQ_Xsfvcp = 1 << 2, - RVV_REQ_Xsfvqmaccdod = 1 << 3, - RVV_REQ_Xsfvqmaccqoq = 1 << 4, - RVV_REQ_Zvbb = 1 << 5, - RVV_REQ_Zvbc = 1 << 6, - RVV_REQ_Zvkb = 1 << 7, - RVV_REQ_Zvkg = 1 << 8, - RVV_REQ_Zvkned = 1 << 9, - RVV_REQ_Zvknha = 1 << 10, - RVV_REQ_Zvknhb = 1 << 11, - RVV_REQ_Zvksed = 1 << 12, - RVV_REQ_Zvksh = 1 << 13, + RVV_REQ_Xsfvfwmaccqqq = 1 << 3, + RVV_REQ_Xsfvqmaccdod = 1 << 4, + RVV_REQ_Xsfvqmaccqoq = 1 << 5, + RVV_REQ_Zvbb = 1 << 6, + RVV_REQ_Zvbc = 1 << 7, + RVV_REQ_Zvkb = 1 << 8, + RVV_REQ_Zvkg = 1 << 9, + RVV_REQ_Zvkned = 1 << 10, + RVV_REQ_Zvknha = 1 << 11, + RVV_REQ_Zvknhb = 1 << 12, + RVV_REQ_Zvksed = 1 << 13, + RVV_REQ_Zvksh = 1 << 14, LLVM_MARK_AS_BITMASK_ENUM(RVV_REQ_Zvksh) }; diff --git a/clang/lib/Sema/SemaRISCVVectorLookup.cpp b/clang/lib/Sema/SemaRISCVVectorLookup.cpp index 1ba68f54b6db1..e32b12b0e9e81 100644 --- a/clang/lib/Sema/SemaRISCVVectorLookup.cpp +++ b/clang/lib/Sema/SemaRISCVVectorLookup.cpp @@ -205,6 +205,7 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics( static const std::pair FeatureCheckList[] = { {"64bit", RVV_REQ_RV64}, {"xsfvcp", RVV_REQ_Xsfvcp}, + {"xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq}, {"xsfvqmaccdod", RVV_REQ_Xsfvqmaccdod}, {"xsfvqmaccqoq", RVV_REQ_Xsfvqmaccqoq}, {"experimental-zvbb", RVV_REQ_Zvbb}, diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfwmacc_4x4x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfwmacc_4x4x4.c new file mode 100644 index 0000000000000..185b8f236b62a --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/sf_vfwmacc_4x4x4.c @@ -0,0 +1,57 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvfh -target-feature +xsfvfwmaccqqq \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32mf2 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv1f32.nxv4f16.nxv1f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_sf_vfwmacc_4x4x4_f32mf2(vfloat32mf2_t vd, vfloat16m1_t vs1, vfloat16mf4_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_f32mf2(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m1 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv2f32.nxv4f16.nxv2f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_sf_vfwmacc_4x4x4_f32m1(vfloat32m1_t vd, vfloat16m1_t vs1, vfloat16mf2_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_f32m1(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m2 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv4f32.nxv4f16.nxv4f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_sf_vfwmacc_4x4x4_f32m2(vfloat32m2_t vd, vfloat16m1_t vs1, vfloat16m1_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_f32m2(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m4 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv8f32.nxv4f16.nxv8f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_sf_vfwmacc_4x4x4_f32m4(vfloat32m4_t vd, vfloat16m1_t vs1, vfloat16m2_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_f32m4(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m8 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv16f32.nxv4f16.nxv16f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_sf_vfwmacc_4x4x4_f32m8(vfloat32m8_t vd, vfloat16m1_t vs1, vfloat16m4_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_f32m8(vd, vs1, vs2, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vfwmacc_4x4x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vfwmacc_4x4x4.c new file mode 100644 index 0000000000000..a07782821327c --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/sf_vfwmacc_4x4x4.c @@ -0,0 +1,57 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvfh -target-feature +xsfvfwmaccqqq \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32mf2 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv1f32.nxv4f16.nxv1f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_sf_vfwmacc_4x4x4_f32mf2(vfloat32mf2_t vd, vfloat16m1_t vs1, vfloat16mf4_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m1 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv2f32.nxv4f16.nxv2f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_sf_vfwmacc_4x4x4_f32m1(vfloat32m1_t vd, vfloat16m1_t vs1, vfloat16mf2_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m2 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv4f32.nxv4f16.nxv4f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_sf_vfwmacc_4x4x4_f32m2(vfloat32m2_t vd, vfloat16m1_t vs1, vfloat16m1_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m4 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv8f32.nxv4f16.nxv8f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_sf_vfwmacc_4x4x4_f32m4(vfloat32m4_t vd, vfloat16m1_t vs1, vfloat16m2_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m8 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv16f32.nxv4f16.nxv16f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 3) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_sf_vfwmacc_4x4x4_f32m8(vfloat32m8_t vd, vfloat16m1_t vs1, vfloat16m4_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4(vd, vs1, vs2, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vfwmacc_4x4x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vfwmacc_4x4x4.c new file mode 100644 index 0000000000000..e55ecb324c740 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/sf_vfwmacc_4x4x4.c @@ -0,0 +1,57 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvfh -target-feature +xsfvfwmaccqqq \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32mf2_tu +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv1f32.nxv4f16.nxv1f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_sf_vfwmacc_4x4x4_f32mf2_tu(vfloat32mf2_t vd, vfloat16m1_t vs1, vfloat16mf4_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_f32mf2_tu(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m1 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv2f32.nxv4f16.nxv2f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_sf_vfwmacc_4x4x4_f32m1(vfloat32m1_t vd, vfloat16m1_t vs1, vfloat16mf2_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_f32m1_tu(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m2 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv4f32.nxv4f16.nxv4f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_sf_vfwmacc_4x4x4_f32m2(vfloat32m2_t vd, vfloat16m1_t vs1, vfloat16m1_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_f32m2_tu(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m4 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv8f32.nxv4f16.nxv8f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_sf_vfwmacc_4x4x4_f32m4(vfloat32m4_t vd, vfloat16m1_t vs1, vfloat16m2_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_f32m4_tu(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m8 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv16f32.nxv4f16.nxv16f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_sf_vfwmacc_4x4x4_f32m8(vfloat32m8_t vd, vfloat16m1_t vs1, vfloat16m4_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_f32m8_tu(vd, vs1, vs2, vl); +} diff --git a/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vfwmacc_4x4x4.c b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vfwmacc_4x4x4.c new file mode 100644 index 0000000000000..a7b26b3de36f9 --- /dev/null +++ b/clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/sf_vfwmacc_4x4x4.c @@ -0,0 +1,57 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 2 +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +zvfh -target-feature +xsfvfwmaccqqq \ +// RUN: -disable-O0-optnone -emit-llvm %s -o - | opt -S -passes=mem2reg | \ +// RUN: FileCheck --check-prefix=CHECK-RV64 %s + +#include + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32mf2_tu +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv1f32.nxv4f16.nxv1f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32mf2_t test_sf_vfwmacc_4x4x4_f32mf2_tu(vfloat32mf2_t vd, vfloat16m1_t vs1, vfloat16mf4_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_tu(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m1 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv2f32.nxv4f16.nxv2f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m1_t test_sf_vfwmacc_4x4x4_f32m1(vfloat32m1_t vd, vfloat16m1_t vs1, vfloat16mf2_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_tu(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m2 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv4f32.nxv4f16.nxv4f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m2_t test_sf_vfwmacc_4x4x4_f32m2(vfloat32m2_t vd, vfloat16m1_t vs1, vfloat16m1_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_tu(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m4 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv8f32.nxv4f16.nxv8f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m4_t test_sf_vfwmacc_4x4x4_f32m4(vfloat32m4_t vd, vfloat16m1_t vs1, vfloat16m2_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_tu(vd, vs1, vs2, vl); +} + +// CHECK-RV64-LABEL: define dso_local @test_sf_vfwmacc_4x4x4_f32m8 +// CHECK-RV64-SAME: ( [[VD:%.*]], [[VS1:%.*]], [[VS2:%.*]], i64 noundef [[VL:%.*]]) #[[ATTR0]] { +// CHECK-RV64-NEXT: entry: +// CHECK-RV64-NEXT: [[TMP0:%.*]] = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv16f32.nxv4f16.nxv16f16.i64( [[VD]], [[VS1]], [[VS2]], i64 [[VL]], i64 2) +// CHECK-RV64-NEXT: ret [[TMP0]] +// +vfloat32m8_t test_sf_vfwmacc_4x4x4_f32m8(vfloat32m8_t vd, vfloat16m1_t vs1, vfloat16m4_t vs2, size_t vl) { + return __riscv_sf_vfwmacc_4x4x4_tu(vd, vs1, vs2, vl); +} diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c index 3a0435f9c9790..7af9fffefe176 100644 --- a/clang/test/Preprocessor/riscv-target-features.c +++ b/clang/test/Preprocessor/riscv-target-features.c @@ -33,6 +33,7 @@ // CHECK-NOT: __riscv_xcvsimd {{.*$}} // CHECK-NOT: __riscv_xsfcie {{.*$}} // CHECK-NOT: __riscv_xsfvcp {{.*$}} +// CHECK-NOT: __riscv_xsfvfwmaccqqq {{.*$}} // CHECK-NOT: __riscv_xsfqmaccdod {{.*$}} // CHECK-NOT: __riscv_xsfvqmaccqoq {{.*$}} // CHECK-NOT: __riscv_xtheadba {{.*$}} @@ -325,6 +326,14 @@ // RUN: -o - | FileCheck --check-prefix=CHECK-XSFVCP-EXT %s // CHECK-XSFVCP-EXT: __riscv_xsfvcp 1000000{{$}} +// RUN: %clang --target=riscv32-unknown-linux-gnu \ +// RUN: -march=rv32ixsfvfwmaccqqq -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFVFWMACCQQQ-EXT %s +// RUN: %clang --target=riscv64-unknown-linux-gnu \ +// RUN: -march=rv64ixsfvfwmaccqqq -x c -E -dM %s \ +// RUN: -o - | FileCheck --check-prefix=CHECK-XSFVFWMACCQQQ-EXT %s +// CHECK-XSFVFWMACCQQQ-EXT: __riscv_xsfvfwmaccqqq 1000000{{$}} + // RUN: %clang --target=riscv32-unknown-linux-gnu \ // RUN: -march=rv32ixsfvqmaccdod -x c -E -dM %s \ // RUN: -o - | FileCheck --check-prefix=CHECK-XSFVQMACCDOD-EXT %s diff --git a/clang/test/Sema/rvv-required-features-invalid.c b/clang/test/Sema/rvv-required-features-invalid.c index 56f201a507ef7..7021b32cdf17a 100644 --- a/clang/test/Sema/rvv-required-features-invalid.c +++ b/clang/test/Sema/rvv-required-features-invalid.c @@ -23,3 +23,7 @@ void test_xsfvqmaccdod() { void test_xsfvqmaccqoq() { __riscv_sf_vqmacc_4x8x4(); // expected-error {{call to undeclared function '__riscv_sf_vqmacc_4x8x4'}} } + +void test_xsfvfwmaccqqq() { + __riscv_sf_vfwmacc_4x4x4(); // expected-error {{call to undeclared function '__riscv_sf_vfwmacc_4x4x4'}} +} diff --git a/clang/test/Sema/rvv-required-features.c b/clang/test/Sema/rvv-required-features.c index ed665c8ecbd49..2f6d3c1091190 100644 --- a/clang/test/Sema/rvv-required-features.c +++ b/clang/test/Sema/rvv-required-features.c @@ -1,6 +1,7 @@ // REQUIRES: riscv-registered-target // RUN: %clang_cc1 -triple riscv64 -target-feature +v -target-feature +xsfvcp \ -// RUN: -target-feature +xsfvqmaccdod -target-feature +xsfvqmaccqoq %s -fsyntax-only -verify +// RUN: -target-feature +xsfvqmaccdod -target-feature +xsfvqmaccqoq \ +// RUN: -target-feature +zvfh -target-feature +xsfvfwmaccqqq %s -fsyntax-only -verify // expected-no-diagnostics @@ -26,3 +27,7 @@ void test_xsfvqmaccdod(vint32m1_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { void test_xsfvqmaccqoq(vint32m1_t vd, vint8m1_t vs1, vint8m1_t vs2, size_t vl) { __riscv_sf_vqmacc_4x8x4(vd, vs1, vs2, vl); } + +void test_xsfvfwmaccqqq(vfloat32m1_t vd, vfloat16m1_t vs1, vfloat16mf2_t vs2, size_t vl) { + __riscv_sf_vfwmacc_4x4x4(vd, vs1, vs2, vl); +} diff --git a/clang/utils/TableGen/RISCVVEmitter.cpp b/clang/utils/TableGen/RISCVVEmitter.cpp index d697099e47733..ed4cdef0fddfc 100644 --- a/clang/utils/TableGen/RISCVVEmitter.cpp +++ b/clang/utils/TableGen/RISCVVEmitter.cpp @@ -656,6 +656,7 @@ void RVVEmitter::createRVVIntrinsics( .Case("RV64", RVV_REQ_RV64) .Case("ZvfhminOrZvfh", RVV_REQ_ZvfhminOrZvfh) .Case("Xsfvcp", RVV_REQ_Xsfvcp) + .Case("Xsfvfwmaccqqq", RVV_REQ_Xsfvfwmaccqqq) .Case("Xsfvqmaccdod", RVV_REQ_Xsfvqmaccdod) .Case("Xsfvqmaccqoq", RVV_REQ_Xsfvqmaccqoq) .Case("Zvbb", RVV_REQ_Zvbb) diff --git a/llvm/include/llvm/IR/IntrinsicsRISCVXsf.td b/llvm/include/llvm/IR/IntrinsicsRISCVXsf.td index 4381c55a3f91d..b7548abd0550b 100644 --- a/llvm/include/llvm/IR/IntrinsicsRISCVXsf.td +++ b/llvm/include/llvm/IR/IntrinsicsRISCVXsf.td @@ -152,4 +152,7 @@ let TargetPrefix = "riscv" in { def int_riscv_sf_vqmacc_4x8x4 : RISCVSFCustomVMACC; def int_riscv_sf_vqmaccus_4x8x4 : RISCVSFCustomVMACC; def int_riscv_sf_vqmaccsu_4x8x4 : RISCVSFCustomVMACC; + + // XSfvfwmaccqqq + def int_riscv_sf_vfwmacc_4x4x4 : RISCVSFCustomVMACC; } // TargetPrefix = "riscv" diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp index 71dadc466f359..9b0a0c8fe1453 100644 --- a/llvm/lib/Support/RISCVISAInfo.cpp +++ b/llvm/lib/Support/RISCVISAInfo.cpp @@ -73,6 +73,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = { {"xcvsimd", RISCVExtensionVersion{1, 0}}, {"xsfcie", RISCVExtensionVersion{1, 0}}, {"xsfvcp", RISCVExtensionVersion{1, 0}}, + {"xsfvfwmaccqqq", RISCVExtensionVersion{1, 0}}, {"xsfvqmaccdod", RISCVExtensionVersion{1, 0}}, {"xsfvqmaccqoq", RISCVExtensionVersion{1, 0}}, {"xtheadba", RISCVExtensionVersion{1, 0}}, @@ -993,6 +994,7 @@ static const char *ImpliedExtsF[] = {"zicsr"}; static const char *ImpliedExtsV[] = {"zvl128b", "zve64d"}; static const char *ImpliedExtsXTHeadVdot[] = {"v"}; static const char *ImpliedExtsXsfvcp[] = {"zve32x"}; +static const char *ImpliedExtsXsfvfwmaccqqq[] = {"zve32f"}; static const char *ImpliedExtsXsfvqmaccdod[] = {"zve32x"}; static const char *ImpliedExtsXsfvqmaccqoq[] = {"zve32x"}; static const char *ImpliedExtsZacas[] = {"a"}; @@ -1062,6 +1064,7 @@ static constexpr ImpliedExtsEntry ImpliedExts[] = { {{"f"}, {ImpliedExtsF}}, {{"v"}, {ImpliedExtsV}}, {{"xsfvcp"}, {ImpliedExtsXsfvcp}}, + {{"xsfvfwmaccqqq"}, {ImpliedExtsXsfvfwmaccqqq}}, {{"xsfvqmaccdod"}, {ImpliedExtsXsfvqmaccdod}}, {{"xsfvqmaccqoq"}, {ImpliedExtsXsfvqmaccqoq}}, {{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}}, diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp index 9bd7cacbf5f04..fd9e278e471a1 100644 --- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp +++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp @@ -550,6 +550,9 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, TRY_TO_DECODE_FEATURE( RISCV::FeatureVendorXSfvqmaccqoq, DecoderTableXSfvqmaccqoq32, "SiFive Matrix Multiplication (4x8 and 8x4) Instruction opcode table"); + TRY_TO_DECODE_FEATURE( + RISCV::FeatureVendorXSfvfwmaccqqq, DecoderTableXSfvfwmaccqqq32, + "SiFive Matrix Multiplication Instruction opcode table"); TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfcie, DecoderTableXSfcie32, "Sifive CIE custom opcode table"); TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip, diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td index 983449523f52a..88ebf1dca3480 100644 --- a/llvm/lib/Target/RISCV/RISCVFeatures.td +++ b/llvm/lib/Target/RISCV/RISCVFeatures.td @@ -836,6 +836,14 @@ def HasVendorXSfvqmaccqoq : Predicate<"Subtarget->hasVendorXSfvqmaccqoq()">, AssemblerPredicate<(all_of FeatureVendorXSfvqmaccqoq), "'XSfvqmaccqoq' (SiFive Int8 Matrix Multiplication Instructions (4-by-8 and 8-by-4))">; +def FeatureVendorXSfvfwmaccqqq + : SubtargetFeature<"xsfvfwmaccqqq", "HasVendorXSfvfwmaccqqq", "true", + "'XSfvfwmaccqqq' (SiFive Matrix Multiply Accumulate Instruction and 4-by-4))", + [FeatureStdExtZve32f]>; +def HasVendorXSfvfwmaccqqq : Predicate<"Subtarget->hasVendorXSfvfwmaccqqq()">, + AssemblerPredicate<(all_of FeatureVendorXSfvfwmaccqqq), + "'XSfvfwmaccqqq' (SiFive Matrix Multiply Accumulate Instruction and 4-by-4))">; + def FeatureVendorXCVbitmanip : SubtargetFeature<"xcvbitmanip", "HasVendorXCVbitmanip", "true", "'XCVbitmanip' (CORE-V Bit Manipulation)">; diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td index 781a34ba854bf..146786eb76c94 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td @@ -208,6 +208,10 @@ let Predicates = [HasVendorXSfvqmaccqoq], DecoderNamespace = "XSfvqmaccqoq" in { def VQMACCSU_4x8x4 : CustomSiFiveVMACC<0b111111, OPMVV, "sf.vqmaccsu.4x8x4">; } +let Predicates = [HasVendorXSfvfwmaccqqq], DecoderNamespace = "XSfvfwmaccqqq" in { + def VFWMACC_4x4x4 : CustomSiFiveVMACC<0b111100, OPFVV, "sf.vfwmacc.4x4x4">; +} + class VPseudoVC_X : Pseudo<(outs), @@ -341,6 +345,11 @@ multiclass VPseudoSiFiveVQMACC { defm NAME : VPseudoSiFiveVMACC; } +multiclass VPseudoSiFiveVFWMACC { + foreach m = MxListFW in + defm NAME : VPseudoSiFiveVMACC; +} + let Predicates = [HasVendorXSfvcp] in { foreach m = MxList in { defm X : VPseudoVC_X; @@ -383,6 +392,10 @@ let Predicates = [HasVendorXSfvqmaccqoq], DecoderNamespace = "XSfvqmaccqoq" in { defm VQMACCSU_4x8x4 : VPseudoSiFiveVQMACC; } +let Predicates = [HasVendorXSfvfwmaccqqq], DecoderNamespace = "XSfvfwmaccqqq" in { + defm VFWMACC_4x4x4 : VPseudoSiFiveVFWMACC; +} + class VPatVC_OP4 VQMACCInfoPairs = { multiclass VPatVQMACC : VPatVMACC; + +multiclass VPatVFWMACC + : VPatVMACC; + let Predicates = [HasVendorXSfvcp] in { foreach vti = AllVectors in { defm : VPatVC_X<"x", "X", vti, XLenVT, GPR>; @@ -586,6 +604,10 @@ let Predicates = [HasVendorXSfvqmaccqoq] in { defm : VPatVQMACC<"vqmaccsu_4x8x4", "VQMACCSU", "4x8x4">; } +let Predicates = [HasVendorXSfvfwmaccqqq] in { + defm : VPatVFWMACC<"vfwmacc_4x4x4", "VFWMACC", "4x4x4">; +} + let Predicates = [HasVendorXSfcie] in { let hasSideEffects = 1, mayLoad = 0, mayStore = 0, DecoderNamespace = "XSfcie" in { def SF_CFLUSH_D_L1 : RVInstI<0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1), "cflush.d.l1","$rs1">, diff --git a/llvm/test/CodeGen/RISCV/rvv/sf_vfwmacc_4x4x4.ll b/llvm/test/CodeGen/RISCV/rvv/sf_vfwmacc_4x4x4.ll new file mode 100644 index 0000000000000..0ba92c5f70e6e --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/sf_vfwmacc_4x4x4.ll @@ -0,0 +1,195 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+v,+experimental-zvfbfmin,+xsfvfwmaccqqq \ +; RUN: -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK +; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v,+experimental-zvfbfmin,+xsfvfwmaccqqq \ +; RUN: -verify-machineinstrs | FileCheck %s --check-prefixes=CHECK + +declare @llvm.riscv.sf.vfwmacc.4x4x4.nxv1f32.nxv4f16.nxv1f16( + , + , + , + iXLen, iXLen); + +define @intrinsic_vfwmacc_4x4x4_tu_f32mf2( %0, %1, %2, iXLen %3) nounwind { +; CHECK-LABEL: intrinsic_vfwmacc_4x4x4_tu_f32mf2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m1, tu, ma +; CHECK-NEXT: sf.vfwmacc.4x4x4 v8, v9, v10 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv1f32.nxv4f16.nxv1f16( + %0, + %1, + %2, + iXLen %3, iXLen 2) + + ret %a +} + +define @intrinsic_vfwmacc_4x4x4_ta_f32mf2( %0, %1, %2, iXLen %3) nounwind { +; CHECK-LABEL: intrinsic_vfwmacc_4x4x4_ta_f32mf2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m1, ta, ma +; CHECK-NEXT: sf.vfwmacc.4x4x4 v8, v9, v10 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv1f32.nxv4f16.nxv1f16( + %0, + %1, + %2, + iXLen %3, iXLen 3) + + ret %a +} + +declare @llvm.riscv.sf.vfwmacc.4x4x4.nxv2f32.nxv4f16.nxv2f16( + , + , + , + iXLen, iXLen); + +define @intrinsic_vfwmacc_4x4x4_tu_f32m1( %0, %1, %2, iXLen %3) nounwind { +; CHECK-LABEL: intrinsic_vfwmacc_4x4x4_tu_f32m1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m1, tu, ma +; CHECK-NEXT: sf.vfwmacc.4x4x4 v8, v9, v10 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv2f32.nxv4f16.nxv2f16( + %0, + %1, + %2, + iXLen %3, iXLen 2) + + ret %a +} + +define @intrinsic_vfwmacc_4x4x4_ta_f32m1( %0, %1, %2, iXLen %3) nounwind { +; CHECK-LABEL: intrinsic_vfwmacc_4x4x4_ta_f32m1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m1, ta, ma +; CHECK-NEXT: sf.vfwmacc.4x4x4 v8, v9, v10 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv2f32.nxv4f16.nxv2f16( + %0, + %1, + %2, + iXLen %3, iXLen 3) + + ret %a +} + +declare @llvm.riscv.sf.vfwmacc.4x4x4.nxv4f32.nxv4f16.nxv4f16( + , + , + , + iXLen, iXLen); + +define @intrinsic_vfwmacc_4x4x4_tu_f32m2( %0, %1, %2, iXLen %3) nounwind { +; CHECK-LABEL: intrinsic_vfwmacc_4x4x4_tu_f32m2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m1, tu, ma +; CHECK-NEXT: sf.vfwmacc.4x4x4 v8, v10, v11 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv4f32.nxv4f16.nxv4f16( + %0, + %1, + %2, + iXLen %3, iXLen 2) + + ret %a +} + +define @intrinsic_vfwmacc_4x4x4_ta_f32m2( %0, %1, %2, iXLen %3) nounwind { +; CHECK-LABEL: intrinsic_vfwmacc_4x4x4_ta_f32m2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m1, ta, ma +; CHECK-NEXT: sf.vfwmacc.4x4x4 v8, v10, v11 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv4f32.nxv4f16.nxv4f16( + %0, + %1, + %2, + iXLen %3, iXLen 3) + + ret %a +} + +declare @llvm.riscv.sf.vfwmacc.4x4x4.nxv8f32.nxv4f16.nxv8f16( + , + , + , + iXLen, iXLen); + +define @intrinsic_vfwmacc_4x4x4_tu_f32m4( %0, %1, %2, iXLen %3) nounwind { +; CHECK-LABEL: intrinsic_vfwmacc_4x4x4_tu_f32m4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m1, tu, ma +; CHECK-NEXT: sf.vfwmacc.4x4x4 v8, v12, v14 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv8f32.nxv4f16.nxv8f16( + %0, + %1, + %2, + iXLen %3, iXLen 2) + + ret %a +} + +define @intrinsic_vfwmacc_4x4x4_ta_f32m4( %0, %1, %2, iXLen %3) nounwind { +; CHECK-LABEL: intrinsic_vfwmacc_4x4x4_ta_f32m4: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m1, ta, ma +; CHECK-NEXT: sf.vfwmacc.4x4x4 v8, v12, v14 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv8f32.nxv4f16.nxv8f16( + %0, + %1, + %2, + iXLen %3, iXLen 3) + + ret %a +} + +declare @llvm.riscv.sf.vfwmacc.4x4x4.nxv16f32.nxv4f16.nxv16f16( + , + , + , + iXLen, iXLen); + +define @intrinsic_vfwmacc_4x4x4_tu_f32m8( %0, %1, %2, iXLen %3) nounwind { +; CHECK-LABEL: intrinsic_vfwmacc_4x4x4_tu_f32m8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m1, tu, ma +; CHECK-NEXT: sf.vfwmacc.4x4x4 v8, v16, v20 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv16f32.nxv4f16.nxv16f16( + %0, + %1, + %2, + iXLen %3, iXLen 2) + + ret %a +} + +define @intrinsic_vfwmacc_4x4x4_ta_f32m8( %0, %1, %2, iXLen %3) nounwind { +; CHECK-LABEL: intrinsic_vfwmacc_4x4x4_ta_f32m8: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m1, ta, ma +; CHECK-NEXT: sf.vfwmacc.4x4x4 v8, v16, v20 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.sf.vfwmacc.4x4x4.nxv16f32.nxv4f16.nxv16f16( + %0, + %1, + %2, + iXLen %3, iXLen 3) + + ret %a +} diff --git a/llvm/test/MC/RISCV/rvv/xsfvfwmacc.s b/llvm/test/MC/RISCV/rvv/xsfvfwmacc.s new file mode 100644 index 0000000000000..ba054fff2bd87 --- /dev/null +++ b/llvm/test/MC/RISCV/rvv/xsfvfwmacc.s @@ -0,0 +1,15 @@ +# RUN: llvm-mc -triple=riscv64 -show-encoding --mattr=+v,+xsfvfwmaccqqq %s \ +# RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +# RUN: not llvm-mc -triple=riscv64 -show-encoding %s 2>&1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-ERROR +# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+v,+xsfvfwmaccqqq %s \ +# RUN: | llvm-objdump -d --mattr=+v,+xsfvfwmaccqqq - \ +# RUN: | FileCheck %s --check-prefix=CHECK-INST +# RUN: llvm-mc -triple=riscv64 -filetype=obj --mattr=+v,+xsfvfwmaccqqq %s \ +# RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +sf.vfwmacc.4x4x4 v8, v4, v20 +# CHECK-INST: sf.vfwmacc.4x4x4 v8, v4, v20 +# CHECK-ENCODING: [0x5b,0x14,0x42,0xf3] +# CHECK-ERROR: instruction requires the following: 'XSfvfwmaccqqq' (SiFive Matrix Multiply Accumulate Instruction and 4-by-4)) +# CHECK-UNKNOWN: 5b 14 42 f3 diff --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp index 885ec88f8f697..76740bba32f72 100644 --- a/llvm/unittests/Support/RISCVISAInfoTest.cpp +++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp @@ -714,6 +714,7 @@ R"(All available -march extensions for RISC-V xcvsimd 1.0 xsfcie 1.0 xsfvcp 1.0 + xsfvfwmaccqqq 1.0 xsfvqmaccdod 1.0 xsfvqmaccqoq 1.0 xtheadba 1.0