[RISCV] Use maskedoff to decide mask policy for masked compare and vmsbf/vmsif/vmsof.

masked compare and vmsbf/vmsif/vmsof are always tail agnostic, we could
check maskedoff value to decide mask policy rather than have a addtional
policy operand.

Reviewed By: craig.topper, arcbbb

Differential Revision: https://reviews.llvm.org/D122456
This commit is contained in:
Zakk Chen 2022-03-29 17:28:28 -07:00
parent 10b2760da0
commit b578330754
4 changed files with 171 additions and 8 deletions

View file

@ -1108,11 +1108,16 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
SDValue V0 = CurDAG->getRegister(RISCV::V0, VT);
// Otherwise use
// vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
// vmslt{u}.vx vd, va, x, v0.t; if mask policy is agnostic.
SDValue Cmp = SDValue(
CurDAG->getMachineNode(VMSLTMaskOpcode, DL, VT,
{MaskedOff, Src1, Src2, V0, VL, SEW, Glue}),
0);
if (MaskedOff.isUndef()) {
ReplaceNode(Node, Cmp.getNode());
return;
}
// Need vmxor.mm vd, vd, v0 to assign inactive value.
ReplaceNode(Node, CurDAG->getMachineNode(VMXOROpcode, DL, VT,
{Cmp, Mask, VL, MaskSEW}));
return;

View file

@ -505,9 +505,7 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
// If the instruction has policy argument, use the argument.
// If there is no policy argument, default to tail agnostic unless the
// destination is tied to a source. Unless the source is undef. In that case
// the user would have some control over the policy values. Some pseudo
// instructions force a tail agnostic policy despite having a tied def.
bool ForceTailAgnostic = RISCVII::doesForceTailAgnostic(TSFlags);
// the user would have some control over the policy values.
bool TailAgnostic = true;
bool UsesMaskPolicy = RISCVII::UsesMaskPolicy(TSFlags);
// FIXME: Could we look at the above or below instructions to choose the
@ -528,7 +526,7 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
// have set the policy value explicitly, so compiler would not fix it.
TailAgnostic = Policy & RISCVII::TAIL_AGNOSTIC;
MaskAgnostic = Policy & RISCVII::MASK_AGNOSTIC;
} else if (!ForceTailAgnostic && MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
} else if (MI.isRegTiedToUseOperand(0, &UseOpIdx)) {
TailAgnostic = false;
if (UsesMaskPolicy)
MaskAgnostic = false;
@ -543,6 +541,10 @@ static VSETVLIInfo computeInfoForInstr(const MachineInstr &MI, uint64_t TSFlags,
MaskAgnostic = true;
}
}
// Some pseudo instructions force a tail agnostic policy despite having a
// tied def.
if (RISCVII::doesForceTailAgnostic(TSFlags))
TailAgnostic = true;
}
// Remove the tail policy so we can find the SEW and VL.

View file

@ -1192,9 +1192,7 @@ class VPseudoBinaryMOutMask<VReg RetClass,
let HasVLOp = 1;
let HasSEWOp = 1;
let HasMergeOp = 1;
// FIXME: In current design, we would not change the mask policy, so
// UsesMaskPolicy is false. We could fix after add the policy operand.
let UsesMaskPolicy = 0;
let UsesMaskPolicy = 1;
let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
}

View file

@ -1311,3 +1311,161 @@ entry:
ret <vscale x 1 x i8> %a
}
declare <vscale x 1 x i1> @llvm.riscv.vmsbf.mask.nxv1i1(
<vscale x 1 x i1>,
<vscale x 1 x i1>,
<vscale x 1 x i1>,
iXLen);
define <vscale x 1 x i1> @intrinsic_vmsbf_mask_m_nxv1i1_nxv1i1(<vscale x 1 x i1> %0, <vscale x 1 x i1> %1, iXLen %2) nounwind {
; CHECK-LABEL: intrinsic_vmsbf_mask_m_nxv1i1_nxv1i1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vmv1r.v v9, v0
; CHECK-NEXT: vsetvli zero, a0, e8, mf8, ta, ma
; CHECK-NEXT: vmv1r.v v0, v8
; CHECK-NEXT: vmsbf.m v8, v9, v0.t
; CHECK-NEXT: vmv1r.v v0, v8
; CHECK-NEXT: ret
entry:
%a = call <vscale x 1 x i1> @llvm.riscv.vmsbf.mask.nxv1i1(
<vscale x 1 x i1> undef,
<vscale x 1 x i1> %0,
<vscale x 1 x i1> %1,
iXLen %2)
ret <vscale x 1 x i1> %a
}
declare <vscale x 1 x i1> @llvm.riscv.vmfeq.mask.nxv1f16(
<vscale x 1 x i1>,
<vscale x 1 x half>,
<vscale x 1 x half>,
<vscale x 1 x i1>,
iXLen);
declare <vscale x 1 x i1> @llvm.riscv.vmfeq.nxv1f16(
<vscale x 1 x half>,
<vscale x 1 x half>,
iXLen);
define <vscale x 1 x i1> @intrinsic_vmfeq_mask_vv_nxv1f16_nxv1f16(<vscale x 1 x half> %0, <vscale x 1 x half> %1, <vscale x 1 x half> %2, iXLen %3) nounwind {
; CHECK-LABEL: intrinsic_vmfeq_mask_vv_nxv1f16_nxv1f16:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vsetvli zero, a0, e16, mf4, ta, mu
; CHECK-NEXT: vmfeq.vv v0, v9, v10
; CHECK-NEXT: vsetvli zero, zero, e16, mf4, ta, ma
; CHECK-NEXT: vmfeq.vv v0, v9, v10, v0.t
; CHECK-NEXT: ret
entry:
%mask = call <vscale x 1 x i1> @llvm.riscv.vmfeq.nxv1f16(
<vscale x 1 x half> %1,
<vscale x 1 x half> %2,
iXLen %3)
%a = call <vscale x 1 x i1> @llvm.riscv.vmfeq.mask.nxv1f16(
<vscale x 1 x i1> undef,
<vscale x 1 x half> %1,
<vscale x 1 x half> %2,
<vscale x 1 x i1> %mask,
iXLen %3)
ret <vscale x 1 x i1> %a
}
declare <vscale x 1 x i1> @llvm.riscv.vmseq.mask.nxv1i64.i64(
<vscale x 1 x i1>,
<vscale x 1 x i64>,
i64,
<vscale x 1 x i1>,
iXLen);
define <vscale x 1 x i1> @intrinsic_vmseq_mask_vx_nxv1i64_i64(<vscale x 1 x i64> %0, i64 %1, <vscale x 1 x i1> %2, iXLen %3) nounwind {
; RV32-LABEL: intrinsic_vmseq_mask_vx_nxv1i64_i64:
; RV32: # %bb.0: # %entry
; RV32-NEXT: addi sp, sp, -16
; RV32-NEXT: sw a1, 12(sp)
; RV32-NEXT: sw a0, 8(sp)
; RV32-NEXT: vsetvli zero, a2, e64, m1, ta, mu
; RV32-NEXT: addi a0, sp, 8
; RV32-NEXT: vlse64.v v9, (a0), zero
; RV32-NEXT: vsetvli zero, zero, e64, m1, ta, ma
; RV32-NEXT: vmseq.vv v0, v8, v9, v0.t
; RV32-NEXT: addi sp, sp, 16
; RV32-NEXT: ret
;
; RV64-LABEL: intrinsic_vmseq_mask_vx_nxv1i64_i64:
; RV64: # %bb.0: # %entry
; RV64-NEXT: vsetvli zero, a1, e64, m1, ta, ma
; RV64-NEXT: vmseq.vx v0, v8, a0, v0.t
; RV64-NEXT: ret
entry:
%a = call <vscale x 1 x i1> @llvm.riscv.vmseq.mask.nxv1i64.i64(
<vscale x 1 x i1> undef,
<vscale x 1 x i64> %0,
i64 %1,
<vscale x 1 x i1> %2,
iXLen %3)
ret <vscale x 1 x i1> %a
}
declare <vscale x 1 x i1> @llvm.riscv.vmsge.mask.nxv1i64.i64(
<vscale x 1 x i1>,
<vscale x 1 x i64>,
i64,
<vscale x 1 x i1>,
iXLen);
define <vscale x 1 x i1> @intrinsic_vmsge_mask_vx_nxv1i64_i64(<vscale x 1 x i64> %0, i64 %1, <vscale x 1 x i1> %2, iXLen %3) nounwind {
; RV32-LABEL: intrinsic_vmsge_mask_vx_nxv1i64_i64:
; RV32: # %bb.0: # %entry
; RV32-NEXT: addi sp, sp, -16
; RV32-NEXT: sw a1, 12(sp)
; RV32-NEXT: sw a0, 8(sp)
; RV32-NEXT: vsetvli zero, a2, e64, m1, ta, mu
; RV32-NEXT: addi a0, sp, 8
; RV32-NEXT: vlse64.v v9, (a0), zero
; RV32-NEXT: vsetvli zero, zero, e64, m1, ta, ma
; RV32-NEXT: vmsle.vv v0, v9, v8, v0.t
; RV32-NEXT: addi sp, sp, 16
; RV32-NEXT: ret
;
; RV64-LABEL: intrinsic_vmsge_mask_vx_nxv1i64_i64:
; RV64: # %bb.0: # %entry
; RV64-NEXT: vsetvli zero, a1, e64, m1, ta, ma
; RV64-NEXT: vmslt.vx v0, v8, a0, v0.t
; RV64-NEXT: ret
entry:
%a = call <vscale x 1 x i1> @llvm.riscv.vmsge.mask.nxv1i64.i64(
<vscale x 1 x i1> undef,
<vscale x 1 x i64> %0,
i64 %1,
<vscale x 1 x i1> %2,
iXLen %3)
ret <vscale x 1 x i1> %a
}
declare <vscale x 64 x i1> @llvm.riscv.vmsbf.mask.nxv64i1(
<vscale x 64 x i1>,
<vscale x 64 x i1>,
<vscale x 64 x i1>,
iXLen);
define <vscale x 64 x i1> @intrinsic_vmsbf_mask_m_nxv64i1_nxv64i1(<vscale x 64 x i1> %0, <vscale x 64 x i1> %1, iXLen %2) nounwind {
; CHECK-LABEL: intrinsic_vmsbf_mask_m_nxv64i1_nxv64i1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vmv1r.v v9, v0
; CHECK-NEXT: vsetvli zero, a0, e8, m8, ta, ma
; CHECK-NEXT: vmv1r.v v0, v8
; CHECK-NEXT: vmsbf.m v8, v9, v0.t
; CHECK-NEXT: vmv1r.v v0, v8
; CHECK-NEXT: ret
entry:
%a = call <vscale x 64 x i1> @llvm.riscv.vmsbf.mask.nxv64i1(
<vscale x 64 x i1> undef,
<vscale x 64 x i1> %0,
<vscale x 64 x i1> %1,
iXLen %2)
ret <vscale x 64 x i1> %a
}