Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21872,6 +21872,44 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
return N->getOperand(0);
break;
}
case RISCVISD::VMERGE_VL: {
// vmerge_vl allones, x, y, passthru, vl -> vmv_v_v passthru, x, vl
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realize that for VMERGE_VL, passthru is not the first operand just like others, why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure. Maybe it's trying to be like vp_merge where the mask is the first argument?

SDValue Mask = N->getOperand(0);
SDValue True = N->getOperand(1);
SDValue Passthru = N->getOperand(3);
SDValue VL = N->getOperand(4);

// Fixed vectors are wrapped in scalable containers, unwrap them.
using namespace SDPatternMatch;
SDValue SubVec;
if (sd_match(Mask, m_InsertSubvector(m_Undef(), m_Value(SubVec), m_Zero())))
Mask = SubVec;

if (!isOneOrOneSplat(Mask))
break;

return DAG.getNode(RISCVISD::VMV_V_V_VL, SDLoc(N), N->getSimpleValueType(0),
Passthru, True, VL);
}
case RISCVISD::VMV_V_V_VL: {
// vmv_v_v passthru, splat(x), vl -> vmv_v_x passthru, x, vl
SDValue Passthru = N->getOperand(0);
SDValue Src = N->getOperand(1);
SDValue VL = N->getOperand(2);

// Fixed vectors are wrapped in scalable containers, unwrap them.
using namespace SDPatternMatch;
SDValue SubVec;
if (sd_match(Src, m_InsertSubvector(m_Undef(), m_Value(SubVec), m_Zero())))
Src = SubVec;

SDValue SplatVal = DAG.getSplatValue(Src);
if (!SplatVal)
break;
MVT VT = N->getSimpleValueType(0);
return lowerScalarSplat(Passthru, SplatVal, VL, VT, SDLoc(N), DAG,
Subtarget);
}
case RISCVISD::VSLIDEDOWN_VL:
case RISCVISD::VSLIDEUP_VL:
if (N->getOperand(1)->isUndef())
Expand Down
45 changes: 45 additions & 0 deletions llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vpmerge.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1353,3 +1353,48 @@ define <32 x double> @vpmerge_vf_v32f64(double %a, <32 x double> %vb, <32 x i1>
%v = call <32 x double> @llvm.vp.merge.v32f64(<32 x i1> %m, <32 x double> %va, <32 x double> %vb, i32 %evl)
ret <32 x double> %v
}

define <4 x i32> @splat_v4i32(i32 %x, i32 zeroext %evl) {
; CHECK-LABEL: splat_v4i32:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
; CHECK-NEXT: vmv.v.x v8, a0
; CHECK-NEXT: ret
%head = insertelement <4 x i32> poison, i32 %x, i32 0
%splat = shufflevector <4 x i32> %head, <4 x i32> poison, <4 x i32> zeroinitializer
%v = call <4 x i32> @llvm.vp.merge(<4 x i1> splat (i1 true), <4 x i32> %splat, <4 x i32> poison, i32 %evl)
ret <4 x i32> %v
}

define <4 x float> @splat_v4f32(float %x, i32 zeroext %evl) {
; CHECK-LABEL: splat_v4f32:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
; CHECK-NEXT: vfmv.v.f v8, fa0
; CHECK-NEXT: ret
%head = insertelement <4 x float> poison, float %x, i32 0
%splat = shufflevector <4 x float> %head, <4 x float> poison, <4 x i32> zeroinitializer
%v = call <4 x float> @llvm.vp.merge(<4 x i1> splat (i1 true), <4 x float> %splat, <4 x float> poison, i32 %evl)
ret <4 x float> %v
}

define <4 x i32> @splat_v4i32_const(i32 zeroext %evl) {
; CHECK-LABEL: splat_v4i32_const:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
; CHECK-NEXT: vmv.v.i v8, 1
; CHECK-NEXT: ret
%v = call <4 x i32> @llvm.vp.merge(<4 x i1> splat (i1 true), <4 x i32> splat (i32 1), <4 x i32> poison, i32 %evl)
ret <4 x i32> %v
}

define <4 x float> @splat_v4f32_const(i32 zeroext %evl) {
; CHECK-LABEL: splat_v4f32_const:
; CHECK: # %bb.0:
; CHECK-NEXT: lui a1, 270976
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
; CHECK-NEXT: vmv.v.x v8, a1
; CHECK-NEXT: ret
%v = call <4 x float> @llvm.vp.merge(<4 x i1> splat (i1 true), <4 x float> splat (float 42.0), <4 x float> poison, i32 %evl)
ret <4 x float> %v
}
45 changes: 45 additions & 0 deletions llvm/test/CodeGen/RISCV/rvv/vpmerge-sdnode.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1663,3 +1663,48 @@ define <vscale x 8 x double> @vpmerge_vf_nxv8f64(double %a, <vscale x 8 x double
%v = call <vscale x 8 x double> @llvm.vp.merge.nxv8f64(<vscale x 8 x i1> %m, <vscale x 8 x double> %va, <vscale x 8 x double> %vb, i32 %evl)
ret <vscale x 8 x double> %v
}

define <vscale x 2 x i32> @splat_nxv2i32(i32 %x, i32 zeroext %evl) {
; CHECK-LABEL: splat_nxv2i32:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
; CHECK-NEXT: vmv.v.x v8, a0
; CHECK-NEXT: ret
%head = insertelement <vscale x 2 x i32> poison, i32 %x, i32 0
%splat = shufflevector <vscale x 2 x i32> %head, <vscale x 2 x i32> poison, <vscale x 2 x i32> zeroinitializer
%v = call <vscale x 2 x i32> @llvm.vp.merge(<vscale x 2 x i1> splat (i1 true), <vscale x 2 x i32> %splat, <vscale x 2 x i32> poison, i32 %evl)
ret <vscale x 2 x i32> %v
}

define <vscale x 2 x float> @splat_nxv2f32(float %x, i32 zeroext %evl) {
; CHECK-LABEL: splat_nxv2f32:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
; CHECK-NEXT: vfmv.v.f v8, fa0
; CHECK-NEXT: ret
%head = insertelement <vscale x 2 x float> poison, float %x, i32 0
%splat = shufflevector <vscale x 2 x float> %head, <vscale x 2 x float> poison, <vscale x 2 x i32> zeroinitializer
%v = call <vscale x 2 x float> @llvm.vp.merge(<vscale x 2 x i1> splat (i1 true), <vscale x 2 x float> %splat, <vscale x 2 x float> poison, i32 %evl)
ret <vscale x 2 x float> %v
}

define <vscale x 2 x i32> @splat_nxv2i32_const(i32 zeroext %evl) {
; CHECK-LABEL: splat_nxv2i32_const:
; CHECK: # %bb.0:
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
; CHECK-NEXT: vmv.v.i v8, 1
; CHECK-NEXT: ret
%v = call <vscale x 2 x i32> @llvm.vp.merge(<vscale x 2 x i1> splat (i1 true), <vscale x 2 x i32> splat (i32 1), <vscale x 2 x i32> poison, i32 %evl)
ret <vscale x 2 x i32> %v
}

define <vscale x 2 x float> @splat_nxv2f32_const(i32 zeroext %evl) {
; CHECK-LABEL: splat_nxv2f32_const:
; CHECK: # %bb.0:
; CHECK-NEXT: lui a1, 270976
; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma
; CHECK-NEXT: vmv.v.x v8, a1
; CHECK-NEXT: ret
%v = call <vscale x 2 x float> @llvm.vp.merge(<vscale x 2 x i1> splat (i1 true), <vscale x 2 x float> splat (float 42.0), <vscale x 2 x float> poison, i32 %evl)
ret <vscale x 2 x float> %v
}
Loading