diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td @@ -602,6 +602,47 @@ } } +multiclass VPatBinarySDNodeExt_V_WV { + foreach vti = AllWidenableIntVectors in { + def : Pat< + (vti.Vti.Vector + (riscv_trunc_vector_vl + (op (vti.Wti.Vector vti.Wti.RegClass:$rs2), + (vti.Wti.Vector (extop (vti.Vti.Vector vti.Vti.RegClass:$rs1)))), + (riscv_vmset_vl VLMax), + VLMax)), + (!cast(instruction_name#"_WV_"#vti.Vti.LMul.MX) + vti.Wti.RegClass:$rs2, vti.Vti.RegClass:$rs1, + vti.Vti.AVL, vti.Vti.Log2SEW)>; + } +} + +multiclass VPatBinarySDNodeExt_V_WX { + foreach vti = AllWidenableIntVectors in { + def : Pat< + (vti.Vti.Vector + (riscv_trunc_vector_vl + (op (vti.Wti.Vector vti.Wti.RegClass:$rs2), + (vti.Wti.Vector (extop (vti.Vti.Vector (SplatPat GPR:$rs1))))), + (riscv_vmset_vl VLMax), + VLMax)), + (!cast(instruction_name#"_WX_"#vti.Vti.LMul.MX) + vti.Wti.RegClass:$rs2, GPR:$rs1, + vti.Vti.AVL, vti.Vti.Log2SEW)>; + } +} + + +multiclass VPatBinarySDNode_V_WV { + defm : VPatBinarySDNodeExt_V_WV; + defm : VPatBinarySDNodeExt_V_WV; +} + +multiclass VPatBinarySDNode_V_WX { + defm : VPatBinarySDNodeExt_V_WX; + defm : VPatBinarySDNodeExt_V_WX; +} + //===----------------------------------------------------------------------===// // Patterns. //===----------------------------------------------------------------------===// @@ -696,6 +737,11 @@ } // 12.7. Vector Narrowing Integer Right Shift Instructions +defm : VPatBinarySDNode_V_WV; +defm : VPatBinarySDNode_V_WX; +defm : VPatBinarySDNode_V_WV; +defm : VPatBinarySDNode_V_WX; + foreach vtiTowti = AllWidenableIntVectors in { defvar vti = vtiTowti.Vti; defvar wti = vtiTowti.Wti; diff --git a/llvm/test/CodeGen/RISCV/rvv/vnsra-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vnsra-sdnode.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/vnsra-sdnode.ll @@ -0,0 +1,225 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+experimental-v -target-abi=ilp32 \ +; RUN: -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -target-abi=lp64 \ +; RUN: -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK + +define @vnsra_wv_nxv1i32_sext( %va, %vb) { +; CHECK-LABEL: vnsra_wv_nxv1i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, mu +; CHECK-NEXT: vnsra.wv v8, v8, v9 +; CHECK-NEXT: ret + %vc = sext %vb to + %x = ashr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsra_wx_i32_nxv1i32_sext( %va, i32 %b) { +; CHECK-LABEL: vnsra_wx_i32_nxv1i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, mu +; CHECK-NEXT: vnsra.wx v8, v8, a0 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = sext %splat to + %x = ashr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsra_wv_nxv2i32_sext( %va, %vb) { +; CHECK-LABEL: vnsra_wv_nxv2i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, mu +; CHECK-NEXT: vnsra.wv v11, v8, v10 +; CHECK-NEXT: vmv.v.v v8, v11 +; CHECK-NEXT: ret + %vc = sext %vb to + %x = ashr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsra_wx_i32_nxv2i32_sext( %va, i32 %b) { +; CHECK-LABEL: vnsra_wx_i32_nxv2i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, mu +; CHECK-NEXT: vnsra.wx v10, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v10 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = sext %splat to + %x = ashr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsra_wv_nxv4i32_sext( %va, %vb) { +; CHECK-LABEL: vnsra_wv_nxv4i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, mu +; CHECK-NEXT: vnsra.wv v14, v8, v12 +; CHECK-NEXT: vmv.v.v v8, v14 +; CHECK-NEXT: ret + %vc = sext %vb to + %x = ashr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsra_wx_i32_nxv4i32_sext( %va, i32 %b) { +; CHECK-LABEL: vnsra_wx_i32_nxv4i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, mu +; CHECK-NEXT: vnsra.wx v12, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v12 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = sext %splat to + %x = ashr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsra_wv_nxv8i32_sext( %va, %vb) { +; CHECK-LABEL: vnsra_wv_nxv8i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, mu +; CHECK-NEXT: vnsra.wv v20, v8, v16 +; CHECK-NEXT: vmv.v.v v8, v20 +; CHECK-NEXT: ret + %vc = sext %vb to + %x = ashr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsra_wx_i32_nxv8i32_sext( %va, i32 %b) { +; CHECK-LABEL: vnsra_wx_i32_nxv8i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m4, ta, mu +; CHECK-NEXT: vnsra.wx v16, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = sext %splat to + %x = ashr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsra_wv_nxv1i32_zext( %va, %vb) { +; CHECK-LABEL: vnsra_wv_nxv1i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, mu +; CHECK-NEXT: vnsra.wv v8, v8, v9 +; CHECK-NEXT: ret + %vc = zext %vb to + %x = ashr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsra_wx_i32_nxv1i32_zext( %va, i32 %b) { +; CHECK-LABEL: vnsra_wx_i32_nxv1i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, mu +; CHECK-NEXT: vnsra.wx v8, v8, a0 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = zext %splat to + %x = ashr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsra_wv_nxv2i32_zext( %va, %vb) { +; CHECK-LABEL: vnsra_wv_nxv2i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, mu +; CHECK-NEXT: vnsra.wv v11, v8, v10 +; CHECK-NEXT: vmv.v.v v8, v11 +; CHECK-NEXT: ret + %vc = zext %vb to + %x = ashr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsra_wx_i32_nxv2i32_zext( %va, i32 %b) { +; CHECK-LABEL: vnsra_wx_i32_nxv2i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, mu +; CHECK-NEXT: vnsra.wx v10, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v10 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = zext %splat to + %x = ashr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsra_wv_nxv4i32_zext( %va, %vb) { +; CHECK-LABEL: vnsra_wv_nxv4i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, mu +; CHECK-NEXT: vnsra.wv v14, v8, v12 +; CHECK-NEXT: vmv.v.v v8, v14 +; CHECK-NEXT: ret + %vc = zext %vb to + %x = ashr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsra_wx_i32_nxv4i32_zext( %va, i32 %b) { +; CHECK-LABEL: vnsra_wx_i32_nxv4i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, mu +; CHECK-NEXT: vnsra.wx v12, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v12 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = zext %splat to + %x = ashr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsra_wv_nxv8i32_zext( %va, %vb) { +; CHECK-LABEL: vnsra_wv_nxv8i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, mu +; CHECK-NEXT: vnsra.wv v20, v8, v16 +; CHECK-NEXT: vmv.v.v v8, v20 +; CHECK-NEXT: ret + %vc = zext %vb to + %x = ashr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsra_wx_i32_nxv8i32_zext( %va, i32 %b) { +; CHECK-LABEL: vnsra_wx_i32_nxv8i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m4, ta, mu +; CHECK-NEXT: vnsra.wx v16, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = zext %splat to + %x = ashr %va, %vb + %y = trunc %x to + ret %y +} diff --git a/llvm/test/CodeGen/RISCV/rvv/vnsrl-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vnsrl-sdnode.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/vnsrl-sdnode.ll @@ -0,0 +1,225 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+experimental-v -target-abi=ilp32 \ +; RUN: -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -target-abi=lp64 \ +; RUN: -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK + +define @vnsrl_wv_nxv1i32_sext( %va, %vb) { +; CHECK-LABEL: vnsrl_wv_nxv1i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, mu +; CHECK-NEXT: vnsrl.wv v8, v8, v9 +; CHECK-NEXT: ret + %vc = sext %vb to + %x = lshr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsrl_wx_i32_nxv1i32_sext( %va, i32 %b) { +; CHECK-LABEL: vnsrl_wx_i32_nxv1i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, mu +; CHECK-NEXT: vnsrl.wx v8, v8, a0 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = sext %splat to + %x = lshr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsrl_wv_nxv2i32_sext( %va, %vb) { +; CHECK-LABEL: vnsrl_wv_nxv2i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, mu +; CHECK-NEXT: vnsrl.wv v11, v8, v10 +; CHECK-NEXT: vmv.v.v v8, v11 +; CHECK-NEXT: ret + %vc = sext %vb to + %x = lshr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsrl_wx_i32_nxv2i32_sext( %va, i32 %b) { +; CHECK-LABEL: vnsrl_wx_i32_nxv2i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, mu +; CHECK-NEXT: vnsrl.wx v10, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v10 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = sext %splat to + %x = lshr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsrl_wv_nxv4i32_sext( %va, %vb) { +; CHECK-LABEL: vnsrl_wv_nxv4i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, mu +; CHECK-NEXT: vnsrl.wv v14, v8, v12 +; CHECK-NEXT: vmv.v.v v8, v14 +; CHECK-NEXT: ret + %vc = sext %vb to + %x = lshr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsrl_wx_i32_nxv4i32_sext( %va, i32 %b) { +; CHECK-LABEL: vnsrl_wx_i32_nxv4i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, mu +; CHECK-NEXT: vnsrl.wx v12, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v12 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = sext %splat to + %x = lshr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsrl_wv_nxv8i32_sext( %va, %vb) { +; CHECK-LABEL: vnsrl_wv_nxv8i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, mu +; CHECK-NEXT: vnsrl.wv v20, v8, v16 +; CHECK-NEXT: vmv.v.v v8, v20 +; CHECK-NEXT: ret + %vc = sext %vb to + %x = lshr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsrl_wx_i32_nxv8i32_sext( %va, i32 %b) { +; CHECK-LABEL: vnsrl_wx_i32_nxv8i32_sext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m4, ta, mu +; CHECK-NEXT: vnsrl.wx v16, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = sext %splat to + %x = lshr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsrl_wv_nxv1i32_zext( %va, %vb) { +; CHECK-LABEL: vnsrl_wv_nxv1i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, mu +; CHECK-NEXT: vnsrl.wv v8, v8, v9 +; CHECK-NEXT: ret + %vc = zext %vb to + %x = lshr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsrl_wx_i32_nxv1i32_zext( %va, i32 %b) { +; CHECK-LABEL: vnsrl_wx_i32_nxv1i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, mu +; CHECK-NEXT: vnsrl.wx v8, v8, a0 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = zext %splat to + %x = lshr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsrl_wv_nxv2i32_zext( %va, %vb) { +; CHECK-LABEL: vnsrl_wv_nxv2i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, mu +; CHECK-NEXT: vnsrl.wv v11, v8, v10 +; CHECK-NEXT: vmv.v.v v8, v11 +; CHECK-NEXT: ret + %vc = zext %vb to + %x = lshr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsrl_wx_i32_nxv2i32_zext( %va, i32 %b) { +; CHECK-LABEL: vnsrl_wx_i32_nxv2i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, mu +; CHECK-NEXT: vnsrl.wx v10, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v10 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = zext %splat to + %x = lshr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsrl_wv_nxv4i32_zext( %va, %vb) { +; CHECK-LABEL: vnsrl_wv_nxv4i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, mu +; CHECK-NEXT: vnsrl.wv v14, v8, v12 +; CHECK-NEXT: vmv.v.v v8, v14 +; CHECK-NEXT: ret + %vc = zext %vb to + %x = lshr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsrl_wx_i32_nxv4i32_zext( %va, i32 %b) { +; CHECK-LABEL: vnsrl_wx_i32_nxv4i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, mu +; CHECK-NEXT: vnsrl.wx v12, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v12 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = zext %splat to + %x = lshr %va, %vb + %y = trunc %x to + ret %y +} + +define @vnsrl_wv_nxv8i32_zext( %va, %vb) { +; CHECK-LABEL: vnsrl_wv_nxv8i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, mu +; CHECK-NEXT: vnsrl.wv v20, v8, v16 +; CHECK-NEXT: vmv.v.v v8, v20 +; CHECK-NEXT: ret + %vc = zext %vb to + %x = lshr %va, %vc + %y = trunc %x to + ret %y +} + +define @vnsrl_wx_i32_nxv8i32_zext( %va, i32 %b) { +; CHECK-LABEL: vnsrl_wx_i32_nxv8i32_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m4, ta, mu +; CHECK-NEXT: vnsrl.wx v16, v8, a0 +; CHECK-NEXT: vmv.v.v v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vb = zext %splat to + %x = lshr %va, %vb + %y = trunc %x to + ret %y +}