diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -1108,11 +1108,16 @@ 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 policyt 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 assgin inactive value. ReplaceNode(Node, CurDAG->getMachineNode(VMXOROpcode, DL, VT, {Cmp, Mask, VL, MaskSEW})); return; diff --git a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp --- a/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp +++ b/llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp @@ -505,9 +505,7 @@ // 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 @@ // 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 @@ 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. diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVPseudos.td @@ -1192,9 +1192,7 @@ 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(PseudoToVInst.VInst); } diff --git a/llvm/test/CodeGen/RISCV/rvv/masked-tama.ll b/llvm/test/CodeGen/RISCV/rvv/masked-tama.ll --- a/llvm/test/CodeGen/RISCV/rvv/masked-tama.ll +++ b/llvm/test/CodeGen/RISCV/rvv/masked-tama.ll @@ -1311,3 +1311,161 @@ ret %a } + +declare @llvm.riscv.vmsbf.mask.nxv1i1( + , + , + , + iXLen); + +define @intrinsic_vmsbf_mask_m_nxv1i1_nxv1i1( %0, %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 @llvm.riscv.vmsbf.mask.nxv1i1( + undef, + %0, + %1, + iXLen %2) + ret %a +} + +declare @llvm.riscv.vmfeq.mask.nxv1f16( + , + , + , + , + iXLen); + +declare @llvm.riscv.vmfeq.nxv1f16( + , + , + iXLen); + +define @intrinsic_vmfeq_mask_vv_nxv1f16_nxv1f16( %0, %1, %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 @llvm.riscv.vmfeq.nxv1f16( + %1, + %2, + iXLen %3) + %a = call @llvm.riscv.vmfeq.mask.nxv1f16( + undef, + %1, + %2, + %mask, + iXLen %3) + + ret %a +} + +declare @llvm.riscv.vmseq.mask.nxv1i64.i64( + , + , + i64, + , + iXLen); + +define @intrinsic_vmseq_mask_vx_nxv1i64_i64( %0, i64 %1, %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 @llvm.riscv.vmseq.mask.nxv1i64.i64( + undef, + %0, + i64 %1, + %2, + iXLen %3) + + ret %a +} + +declare @llvm.riscv.vmsge.mask.nxv1i64.i64( + , + , + i64, + , + iXLen); + +define @intrinsic_vmsge_mask_vx_nxv1i64_i64( %0, i64 %1, %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 @llvm.riscv.vmsge.mask.nxv1i64.i64( + undef, + %0, + i64 %1, + %2, + iXLen %3) + + ret %a +} + +declare @llvm.riscv.vmsbf.mask.nxv64i1( + , + , + , + iXLen); + +define @intrinsic_vmsbf_mask_m_nxv64i1_nxv64i1( %0, %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 @llvm.riscv.vmsbf.mask.nxv64i1( + undef, + %0, + %1, + iXLen %2) + + ret %a +}