diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td index f80cbc9e2fb5e..fe36def4fda2f 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVVLPatterns.td @@ -497,6 +497,16 @@ let HasOneUse = 1 in { node:$E), (riscv_add_vl node:$A, node:$B, node:$C, node:$D, node:$E)>; + def riscv_or_vl_is_add_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, + node:$E), + (riscv_or_vl node:$A, node:$B, node:$C, + node:$D, node:$E), [{ + if (N->getFlags().hasDisjoint()) + return true; + KnownBits Known0 = CurDAG->computeKnownBits(N->getOperand(0), 0); + KnownBits Known1 = CurDAG->computeKnownBits(N->getOperand(1), 0); + return KnownBits::haveNoCommonBitsSet(Known0, Known1); + }]>; def riscv_sub_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D, node:$E), (riscv_sub_vl node:$A, node:$B, node:$C, @@ -2016,6 +2026,41 @@ foreach vtiToWti = AllWidenableIntVectors in { } } +// DAGCombiner::hoistLogicOpWithSameOpcodeHands may hoist disjoint ors +// to (ext (or disjoint (a, b))) +multiclass VPatWidenOrDisjointVL_VV_VX { + foreach vtiToWti = AllWidenableIntVectors in { + defvar vti = vtiToWti.Vti; + defvar wti = vtiToWti.Wti; + let Predicates = !listconcat(GetVTypePredicates.Predicates, + GetVTypePredicates.Predicates) in { + def : Pat<(wti.Vector + (extop + (vti.Vector + (riscv_or_vl_is_add_oneuse + vti.RegClass:$rs2, vti.RegClass:$rs1, + undef, srcvalue, srcvalue)), + VMV0:$vm, VLOpFrag)), + (!cast(instruction_name#"_VV_"#vti.LMul.MX#"_MASK") + (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, + vti.RegClass:$rs1, VMV0:$vm, GPR:$vl, vti.Log2SEW, TA_MA)>; + def : Pat<(wti.Vector + (extop + (vti.Vector + (riscv_or_vl_is_add_oneuse + vti.RegClass:$rs2, (SplatPat (XLenVT GPR:$rs1)), + undef, srcvalue, srcvalue)), + VMV0:$vm, VLOpFrag)), + (!cast(instruction_name#"_VX_"#vti.LMul.MX#"_MASK") + (wti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs2, + GPR:$rs1, VMV0:$vm, GPR:$vl, vti.Log2SEW, TA_MA)>; + } + } +} + +defm : VPatWidenOrDisjointVL_VV_VX; +defm : VPatWidenOrDisjointVL_VV_VX; + // 11.3. Vector Integer Extension defm : VPatExtendVL_V; diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vwadd.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vwadd.ll index 4346e90a1f5f7..b39fff64b1090 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vwadd.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vwadd.ll @@ -899,9 +899,8 @@ define <4 x i32> @vwaddu_vv_disjoint_or(<4 x i16> %x.i16, <4 x i16> %y.i16) { ; CHECK-LABEL: vwaddu_vv_disjoint_or: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma -; CHECK-NEXT: vor.vv v9, v8, v9 -; CHECK-NEXT: vsetvli zero, zero, e32, m1, ta, ma -; CHECK-NEXT: vzext.vf2 v8, v9 +; CHECK-NEXT: vwaddu.vv v10, v8, v9 +; CHECK-NEXT: vmv1r.v v8, v10 ; CHECK-NEXT: ret %x.i32 = zext <4 x i16> %x.i16 to <4 x i32> %y.i32 = zext <4 x i16> %y.i16 to <4 x i32> @@ -913,9 +912,8 @@ define <4 x i32> @vwadd_vv_disjoint_or(<4 x i16> %x.i16, <4 x i16> %y.i16) { ; CHECK-LABEL: vwadd_vv_disjoint_or: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma -; CHECK-NEXT: vor.vv v9, v8, v9 -; CHECK-NEXT: vsetvli zero, zero, e32, m1, ta, ma -; CHECK-NEXT: vsext.vf2 v8, v9 +; CHECK-NEXT: vwadd.vv v10, v8, v9 +; CHECK-NEXT: vmv1r.v v8, v10 ; CHECK-NEXT: ret %x.i32 = sext <4 x i16> %x.i16 to <4 x i32> %y.i32 = sext <4 x i16> %y.i16 to <4 x i32> @@ -927,9 +925,8 @@ define <4 x i32> @vwaddu_vx_disjoint_or(<4 x i16> %x.i16, i16 %y.i16) { ; CHECK-LABEL: vwaddu_vx_disjoint_or: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma -; CHECK-NEXT: vor.vx v9, v8, a0 -; CHECK-NEXT: vsetvli zero, zero, e32, m1, ta, ma -; CHECK-NEXT: vzext.vf2 v8, v9 +; CHECK-NEXT: vwaddu.vx v9, v8, a0 +; CHECK-NEXT: vmv1r.v v8, v9 ; CHECK-NEXT: ret %x.i32 = zext <4 x i16> %x.i16 to <4 x i32> %y.head = insertelement <4 x i16> poison, i16 %y.i16, i32 0 @@ -943,9 +940,8 @@ define <4 x i32> @vwadd_vx_disjoint_or(<4 x i16> %x.i16, i16 %y.i16) { ; CHECK-LABEL: vwadd_vx_disjoint_or: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 4, e16, mf2, ta, ma -; CHECK-NEXT: vor.vx v9, v8, a0 -; CHECK-NEXT: vsetvli zero, zero, e32, m1, ta, ma -; CHECK-NEXT: vsext.vf2 v8, v9 +; CHECK-NEXT: vwadd.vx v9, v8, a0 +; CHECK-NEXT: vmv1r.v v8, v9 ; CHECK-NEXT: ret %x.i32 = sext <4 x i16> %x.i16 to <4 x i32> %y.head = insertelement <4 x i16> poison, i16 %y.i16, i32 0