diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td @@ -733,6 +733,27 @@ defm : VPatWidenBinarySDNode_VV_VX_WV_WX; defm : VPatWidenBinarySDNode_VV_VX_WV_WX; +// shl (ext v, splat 1) is a special case of widening add. +foreach vtiToWti = AllWidenableIntVectors in { + defvar vti = vtiToWti.Vti; + defvar wti = vtiToWti.Wti; + let Predicates = !listconcat(GetVTypePredicates.Predicates, + GetVTypePredicates.Predicates) in { + def : Pat<(shl (wti.Vector (sext_oneuse (vti.Vector vti.RegClass:$rs1))), + (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))), + (!cast("PseudoVWADD_VV_"#vti.LMul.MX) + vti.RegClass:$rs1, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>; + def : Pat<(shl (wti.Vector (zext_oneuse (vti.Vector vti.RegClass:$rs1))), + (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))), + (!cast("PseudoVWADDU_VV_"#vti.LMul.MX) + vti.RegClass:$rs1, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>; + def : Pat<(shl (wti.Vector (anyext_oneuse (vti.Vector vti.RegClass:$rs1))), + (wti.Vector (riscv_vmv_v_x_vl (wti.Vector undef), 1, (XLenVT srcvalue)))), + (!cast("PseudoVWADDU_VV_"#vti.LMul.MX) + vti.RegClass:$rs1, vti.RegClass:$rs1, vti.AVL, vti.Log2SEW)>; + } +} + // 11.3. Vector Integer Extension defm : VPatExtendSDNode_V<[zext, anyext], "PseudoVZEXT", "VF2", AllFractionableVF2IntVectors>; diff --git a/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll --- a/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/mgather-sdnode.ll @@ -549,10 +549,8 @@ define @mgather_baseidx_nxv8i16(ptr %base, %idxs, %m, %passthru) { ; RV32-LABEL: mgather_baseidx_nxv8i16: ; RV32: # %bb.0: -; RV32-NEXT: vsetvli a1, zero, e32, m4, ta, ma -; RV32-NEXT: vsext.vf2 v12, v8 -; RV32-NEXT: vadd.vv v12, v12, v12 -; RV32-NEXT: vsetvli zero, zero, e16, m2, ta, mu +; RV32-NEXT: vsetvli a1, zero, e16, m2, ta, mu +; RV32-NEXT: vwadd.vv v12, v8, v8 ; RV32-NEXT: vluxei32.v v10, (a0), v12, v0.t ; RV32-NEXT: vmv.v.v v8, v10 ; RV32-NEXT: ret @@ -1510,10 +1508,8 @@ define @mgather_baseidx_nxv8f16(ptr %base, %idxs, %m, %passthru) { ; RV32-LABEL: mgather_baseidx_nxv8f16: ; RV32: # %bb.0: -; RV32-NEXT: vsetvli a1, zero, e32, m4, ta, ma -; RV32-NEXT: vsext.vf2 v12, v8 -; RV32-NEXT: vadd.vv v12, v12, v12 -; RV32-NEXT: vsetvli zero, zero, e16, m2, ta, mu +; RV32-NEXT: vsetvli a1, zero, e16, m2, ta, mu +; RV32-NEXT: vwadd.vv v12, v8, v8 ; RV32-NEXT: vluxei32.v v10, (a0), v12, v0.t ; RV32-NEXT: vmv.v.v v8, v10 ; RV32-NEXT: ret diff --git a/llvm/test/CodeGen/RISCV/rvv/mscatter-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/mscatter-sdnode.ll --- a/llvm/test/CodeGen/RISCV/rvv/mscatter-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/mscatter-sdnode.ll @@ -406,10 +406,8 @@ define void @mscatter_baseidx_nxv8i16( %val, ptr %base, %idxs, %m) { ; RV32-LABEL: mscatter_baseidx_nxv8i16: ; RV32: # %bb.0: -; RV32-NEXT: vsetvli a1, zero, e32, m4, ta, ma -; RV32-NEXT: vsext.vf2 v12, v10 -; RV32-NEXT: vadd.vv v12, v12, v12 -; RV32-NEXT: vsetvli zero, zero, e16, m2, ta, ma +; RV32-NEXT: vsetvli a1, zero, e16, m2, ta, ma +; RV32-NEXT: vwadd.vv v12, v10, v10 ; RV32-NEXT: vsoxei32.v v8, (a0), v12, v0.t ; RV32-NEXT: ret ; @@ -1192,10 +1190,8 @@ define void @mscatter_baseidx_nxv8f16( %val, ptr %base, %idxs, %m) { ; RV32-LABEL: mscatter_baseidx_nxv8f16: ; RV32: # %bb.0: -; RV32-NEXT: vsetvli a1, zero, e32, m4, ta, ma -; RV32-NEXT: vsext.vf2 v12, v10 -; RV32-NEXT: vadd.vv v12, v12, v12 -; RV32-NEXT: vsetvli zero, zero, e16, m2, ta, ma +; RV32-NEXT: vsetvli a1, zero, e16, m2, ta, ma +; RV32-NEXT: vwadd.vv v12, v10, v10 ; RV32-NEXT: vsoxei32.v v8, (a0), v12, v0.t ; RV32-NEXT: ret ; diff --git a/llvm/test/CodeGen/RISCV/rvv/vpgather-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vpgather-sdnode.ll --- a/llvm/test/CodeGen/RISCV/rvv/vpgather-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vpgather-sdnode.ll @@ -601,9 +601,8 @@ define @vpgather_baseidx_nxv8i16(ptr %base, %idxs, %m, i32 zeroext %evl) { ; RV32-LABEL: vpgather_baseidx_nxv8i16: ; RV32: # %bb.0: -; RV32-NEXT: vsetvli a2, zero, e32, m4, ta, ma -; RV32-NEXT: vsext.vf2 v12, v8 -; RV32-NEXT: vadd.vv v12, v12, v12 +; RV32-NEXT: vsetvli a2, zero, e16, m2, ta, ma +; RV32-NEXT: vwadd.vv v12, v8, v8 ; RV32-NEXT: vsetvli zero, a1, e16, m2, ta, ma ; RV32-NEXT: vluxei32.v v8, (a0), v12, v0.t ; RV32-NEXT: ret @@ -1423,9 +1422,8 @@ define @vpgather_baseidx_nxv8f16(ptr %base, %idxs, %m, i32 zeroext %evl) { ; RV32-LABEL: vpgather_baseidx_nxv8f16: ; RV32: # %bb.0: -; RV32-NEXT: vsetvli a2, zero, e32, m4, ta, ma -; RV32-NEXT: vsext.vf2 v12, v8 -; RV32-NEXT: vadd.vv v12, v12, v12 +; RV32-NEXT: vsetvli a2, zero, e16, m2, ta, ma +; RV32-NEXT: vwadd.vv v12, v8, v8 ; RV32-NEXT: vsetvli zero, a1, e16, m2, ta, ma ; RV32-NEXT: vluxei32.v v8, (a0), v12, v0.t ; RV32-NEXT: ret diff --git a/llvm/test/CodeGen/RISCV/rvv/vpscatter-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vpscatter-sdnode.ll --- a/llvm/test/CodeGen/RISCV/rvv/vpscatter-sdnode.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vpscatter-sdnode.ll @@ -400,9 +400,8 @@ define void @vpscatter_baseidx_nxv8i16( %val, ptr %base, %idxs, %m, i32 zeroext %evl) { ; RV32-LABEL: vpscatter_baseidx_nxv8i16: ; RV32: # %bb.0: -; RV32-NEXT: vsetvli a2, zero, e32, m4, ta, ma -; RV32-NEXT: vsext.vf2 v12, v10 -; RV32-NEXT: vadd.vv v12, v12, v12 +; RV32-NEXT: vsetvli a2, zero, e16, m2, ta, ma +; RV32-NEXT: vwadd.vv v12, v10, v10 ; RV32-NEXT: vsetvli zero, a1, e16, m2, ta, ma ; RV32-NEXT: vsoxei32.v v8, (a0), v12, v0.t ; RV32-NEXT: ret @@ -1181,9 +1180,8 @@ define void @vpscatter_baseidx_nxv8f16( %val, ptr %base, %idxs, %m, i32 zeroext %evl) { ; RV32-LABEL: vpscatter_baseidx_nxv8f16: ; RV32: # %bb.0: -; RV32-NEXT: vsetvli a2, zero, e32, m4, ta, ma -; RV32-NEXT: vsext.vf2 v12, v10 -; RV32-NEXT: vadd.vv v12, v12, v12 +; RV32-NEXT: vsetvli a2, zero, e16, m2, ta, ma +; RV32-NEXT: vwadd.vv v12, v10, v10 ; RV32-NEXT: vsetvli zero, a1, e16, m2, ta, ma ; RV32-NEXT: vsoxei32.v v8, (a0), v12, v0.t ; RV32-NEXT: ret