diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td index 8cdaa7f2e5ea4..deebac115208c 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td @@ -761,6 +761,11 @@ class GetVTypePredicates { true : [HasVInstructions]); } +class GetVTypeScalarPredicates { + list Predicates = !cond(!eq(vti.Scalar, bf16) : [HasStdExtZfbfmin], + true : []); +} + class VPseudoUSLoadNoMask : Pseudo<(outs RetClass:$rd), diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td index b4c6ba7e9723d..da761ae856706 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td @@ -1454,8 +1454,9 @@ foreach fvtiToFWti = AllWidenableFloatVectors in { // Vector Splats //===----------------------------------------------------------------------===// -foreach fvti = AllFloatVectors in { - let Predicates = GetVTypePredicates.Predicates in +foreach fvti = !listconcat(AllFloatVectors, AllBFloatVectors) in { + let Predicates = !listconcat(GetVTypePredicates.Predicates, + GetVTypeScalarPredicates.Predicates) in def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl undef, fvti.ScalarRegClass:$rs1, srcvalue)), (!cast("PseudoVFMV_V_"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) (fvti.Vector (IMPLICIT_DEF)), diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td index cc44092700c66..27db523584671 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td @@ -2591,7 +2591,12 @@ foreach fvti = AllFloatVectors in { fvti.RegClass:$merge, fvti.RegClass:$rs2, (fvti.Scalar fvti.ScalarRegClass:$rs1), (fvti.Mask V0), GPR:$vl, fvti.Log2SEW)>; + } +} +foreach fvti = !listconcat(AllFloatVectors, AllBFloatVectors) in { + let Predicates = !listconcat(GetVTypePredicates.Predicates, + GetVTypeScalarPredicates.Predicates) in { // 13.16. Vector Floating-Point Move Instruction // If we're splatting fpimm0, use vmv.v.x vd, x0. def : Pat<(fvti.Vector (riscv_vfmv_v_f_vl diff --git a/llvm/test/CodeGen/RISCV/rvv/vfmv.v.f.ll b/llvm/test/CodeGen/RISCV/rvv/vfmv.v.f.ll index 237ef11d154ba..c00433eba5481 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vfmv.v.f.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vfmv.v.f.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+v,+zfh,+zvfh \ +; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+v,+zfh,+zvfh,+experimental-zfbfmin,+experimental-zvfbfmin \ ; RUN: -verify-machineinstrs -target-abi=ilp32d | FileCheck %s -; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v,+zfh,+zvfh \ +; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+v,+zfh,+zvfh,+experimental-zfbfmin,+experimental-zvfbfmin \ ; RUN: -verify-machineinstrs -target-abi=lp64d | FileCheck %s declare @llvm.riscv.vfmv.v.f.nxv1f16( @@ -528,3 +528,123 @@ entry: ret %a } + +declare @llvm.riscv.vfmv.v.f.nxv1bf16( + , + bfloat, + iXLen); + +define @intrinsic_vfmv.v.f_f_nxv1bf16(bfloat %0, iXLen %1) nounwind { +; CHECK-LABEL: intrinsic_vfmv.v.f_f_nxv1bf16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, mf4, ta, ma +; CHECK-NEXT: vfmv.v.f v8, fa0 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.vfmv.v.f.nxv1bf16( + undef, + bfloat %0, + iXLen %1) + + ret %a +} + +declare @llvm.riscv.vfmv.v.f.nxv2bf16( + , + bfloat, + iXLen); + +define @intrinsic_vfmv.v.f_f_nxv2bf16(bfloat %0, iXLen %1) nounwind { +; CHECK-LABEL: intrinsic_vfmv.v.f_f_nxv2bf16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, mf2, ta, ma +; CHECK-NEXT: vfmv.v.f v8, fa0 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.vfmv.v.f.nxv2bf16( + undef, + bfloat %0, + iXLen %1) + + ret %a +} + +declare @llvm.riscv.vfmv.v.f.nxv4bf16( + , + bfloat, + iXLen); + +define @intrinsic_vfmv.v.f_f_nxv4bf16(bfloat %0, iXLen %1) nounwind { +; CHECK-LABEL: intrinsic_vfmv.v.f_f_nxv4bf16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m1, ta, ma +; CHECK-NEXT: vfmv.v.f v8, fa0 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.vfmv.v.f.nxv4bf16( + undef, + bfloat %0, + iXLen %1) + + ret %a +} + +declare @llvm.riscv.vfmv.v.f.nxv8bf16( + , + bfloat, + iXLen); + +define @intrinsic_vfmv.v.f_f_nxv8bf16(bfloat %0, iXLen %1) nounwind { +; CHECK-LABEL: intrinsic_vfmv.v.f_f_nxv8bf16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m2, ta, ma +; CHECK-NEXT: vfmv.v.f v8, fa0 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.vfmv.v.f.nxv8bf16( + undef, + bfloat %0, + iXLen %1) + + ret %a +} + +declare @llvm.riscv.vfmv.v.f.nxv16bf16( + , + bfloat, + iXLen); + +define @intrinsic_vfmv.v.f_f_nxv16bf16(bfloat %0, iXLen %1) nounwind { +; CHECK-LABEL: intrinsic_vfmv.v.f_f_nxv16bf16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m4, ta, ma +; CHECK-NEXT: vfmv.v.f v8, fa0 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.vfmv.v.f.nxv16bf16( + undef, + bfloat %0, + iXLen %1) + + ret %a +} + +declare @llvm.riscv.vfmv.v.f.nxv32bf16( + , + bfloat, + iXLen); + +define @intrinsic_vfmv.v.f_f_nxv32bf16(bfloat %0, iXLen %1) nounwind { +; CHECK-LABEL: intrinsic_vfmv.v.f_f_nxv32bf16: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: vsetvli zero, a0, e16, m8, ta, ma +; CHECK-NEXT: vfmv.v.f v8, fa0 +; CHECK-NEXT: ret +entry: + %a = call @llvm.riscv.vfmv.v.f.nxv32bf16( + undef, + bfloat %0, + iXLen %1) + + ret %a +}