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 @@ -1566,6 +1566,33 @@ defm : VPatBinaryWVL_VV_VX_WV_WX; defm : VPatBinaryWVL_VV_VX_WV_WX; +// shl_vl (ext_vl 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<(riscv_shl_vl (wti.Vector (riscv_sext_vl_oneuse + (vti.Vector vti.RegClass:$rs1), + (vti.Mask V0), VLOpFrag)), + (wti.Vector (riscv_vmv_v_x_vl + (wti.Vector undef), 1, VLOpFrag)), + wti.RegClass:$merge, (vti.Mask V0), VLOpFrag), + (!cast("PseudoVWADD_VV_"#vti.LMul.MX#"_MASK") + wti.RegClass:$merge, vti.RegClass:$rs1, vti.RegClass:$rs1, + (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; + def : Pat<(riscv_shl_vl (wti.Vector (riscv_zext_vl_oneuse + (vti.Vector vti.RegClass:$rs1), + (vti.Mask V0), VLOpFrag)), + (wti.Vector (riscv_vmv_v_x_vl + (wti.Vector undef), 1, VLOpFrag)), + wti.RegClass:$merge, (vti.Mask V0), VLOpFrag), + (!cast("PseudoVWADDU_VV_"#vti.LMul.MX#"_MASK") + wti.RegClass:$merge, vti.RegClass:$rs1, vti.RegClass:$rs1, + (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; + } +} + // 11.3. Vector Integer Extension defm : VPatExtendVL_V; diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-gather.ll @@ -1863,10 +1863,8 @@ define <8 x i16> @mgather_baseidx_v8i16(ptr %base, <8 x i16> %idxs, <8 x i1> %m, <8 x i16> %passthru) { ; RV32-LABEL: mgather_baseidx_v8i16: ; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; RV32-NEXT: vsext.vf2 v10, v8 -; RV32-NEXT: vadd.vv v10, v10, v10 -; RV32-NEXT: vsetvli zero, zero, e16, m1, ta, mu +; RV32-NEXT: vsetivli zero, 8, e16, m1, ta, mu +; RV32-NEXT: vwadd.vv v10, v8, v8 ; RV32-NEXT: vluxei32.v v9, (a0), v10, v0.t ; RV32-NEXT: vmv.v.v v8, v9 ; RV32-NEXT: ret @@ -7802,10 +7800,8 @@ define <8 x half> @mgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m, <8 x half> %passthru) { ; RV32-LABEL: mgather_baseidx_v8f16: ; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; RV32-NEXT: vsext.vf2 v10, v8 -; RV32-NEXT: vadd.vv v10, v10, v10 -; RV32-NEXT: vsetvli zero, zero, e16, m1, ta, mu +; RV32-NEXT: vsetivli zero, 8, e16, m1, ta, mu +; RV32-NEXT: vwadd.vv v10, v8, v8 ; RV32-NEXT: vluxei32.v v9, (a0), v10, v0.t ; RV32-NEXT: vmv.v.v v8, v9 ; RV32-NEXT: ret diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-scatter.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-scatter.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-scatter.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-masked-scatter.ll @@ -1444,10 +1444,8 @@ define void @mscatter_baseidx_v8i16(<8 x i16> %val, ptr %base, <8 x i16> %idxs, <8 x i1> %m) { ; RV32-LABEL: mscatter_baseidx_v8i16: ; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; RV32-NEXT: vsext.vf2 v10, v9 -; RV32-NEXT: vadd.vv v10, v10, v10 -; RV32-NEXT: vsetvli zero, zero, e16, m1, ta, ma +; RV32-NEXT: vsetivli zero, 8, e16, m1, ta, ma +; RV32-NEXT: vwadd.vv v10, v9, v9 ; RV32-NEXT: vsoxei32.v v8, (a0), v10, v0.t ; RV32-NEXT: ret ; @@ -6699,10 +6697,8 @@ define void @mscatter_baseidx_v8f16(<8 x half> %val, ptr %base, <8 x i16> %idxs, <8 x i1> %m) { ; RV32-LABEL: mscatter_baseidx_v8f16: ; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; RV32-NEXT: vsext.vf2 v10, v9 -; RV32-NEXT: vadd.vv v10, v10, v10 -; RV32-NEXT: vsetvli zero, zero, e16, m1, ta, ma +; RV32-NEXT: vsetivli zero, 8, e16, m1, ta, ma +; RV32-NEXT: vwadd.vv v10, v9, v9 ; RV32-NEXT: vsoxei32.v v8, (a0), v10, v0.t ; RV32-NEXT: ret ; diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpgather.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpgather.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpgather.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpgather.ll @@ -555,9 +555,8 @@ define <8 x i16> @vpgather_baseidx_v8i16(ptr %base, <8 x i16> %idxs, <8 x i1> %m, i32 zeroext %evl) { ; RV32-LABEL: vpgather_baseidx_v8i16: ; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; RV32-NEXT: vsext.vf2 v10, v8 -; RV32-NEXT: vadd.vv v10, v10, v10 +; RV32-NEXT: vsetivli zero, 8, e16, m1, ta, ma +; RV32-NEXT: vwadd.vv v10, v8, v8 ; RV32-NEXT: vsetvli zero, a1, e16, m1, ta, ma ; RV32-NEXT: vluxei32.v v8, (a0), v10, v0.t ; RV32-NEXT: ret @@ -1319,9 +1318,8 @@ define <8 x half> @vpgather_baseidx_v8f16(ptr %base, <8 x i16> %idxs, <8 x i1> %m, i32 zeroext %evl) { ; RV32-LABEL: vpgather_baseidx_v8f16: ; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; RV32-NEXT: vsext.vf2 v10, v8 -; RV32-NEXT: vadd.vv v10, v10, v10 +; RV32-NEXT: vsetivli zero, 8, e16, m1, ta, ma +; RV32-NEXT: vwadd.vv v10, v8, v8 ; RV32-NEXT: vsetvli zero, a1, e16, m1, ta, ma ; RV32-NEXT: vluxei32.v v8, (a0), v10, v0.t ; RV32-NEXT: ret diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpscatter.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpscatter.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpscatter.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpscatter.ll @@ -400,9 +400,8 @@ define void @vpscatter_baseidx_v8i16(<8 x i16> %val, ptr %base, <8 x i16> %idxs, <8 x i1> %m, i32 zeroext %evl) { ; RV32-LABEL: vpscatter_baseidx_v8i16: ; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; RV32-NEXT: vsext.vf2 v10, v9 -; RV32-NEXT: vadd.vv v10, v10, v10 +; RV32-NEXT: vsetivli zero, 8, e16, m1, ta, ma +; RV32-NEXT: vwadd.vv v10, v9, v9 ; RV32-NEXT: vsetvli zero, a1, e16, m1, ta, ma ; RV32-NEXT: vsoxei32.v v8, (a0), v10, v0.t ; RV32-NEXT: ret @@ -1127,9 +1126,8 @@ define void @vpscatter_baseidx_v8f16(<8 x half> %val, ptr %base, <8 x i16> %idxs, <8 x i1> %m, i32 zeroext %evl) { ; RV32-LABEL: vpscatter_baseidx_v8f16: ; RV32: # %bb.0: -; RV32-NEXT: vsetivli zero, 8, e32, m2, ta, ma -; RV32-NEXT: vsext.vf2 v10, v9 -; RV32-NEXT: vadd.vv v10, v10, v10 +; RV32-NEXT: vsetivli zero, 8, e16, m1, ta, ma +; RV32-NEXT: vwadd.vv v10, v9, v9 ; RV32-NEXT: vsetvli zero, a1, e16, m1, ta, ma ; RV32-NEXT: vsoxei32.v v8, (a0), v10, v0.t ; RV32-NEXT: ret