Index: llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp =================================================================== --- llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -2394,7 +2394,8 @@ .addOperand(Inst.getOperand(0)) .addOperand(Inst.getOperand(0)) .addReg(RISCV::V0)); - } else if (Inst.getNumOperands() == 5) { + } else if (Inst.getNumOperands() == 5 && + Inst.getOperand(0).getReg() == RISCV::V0) { // masked va >= x, vd == v0 // // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt @@ -2412,6 +2413,30 @@ .addOperand(Inst.getOperand(0)) .addOperand(Inst.getOperand(0)) .addOperand(Inst.getOperand(1))); + } else if (Inst.getNumOperands() == 5) { + // masked va >= x, any vd + // + // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt + // expansion: vmslt{u}.vx vt, va, x; vmandnot.mm vt, v0, vt; vmandnot.mm vd, + // vd, v0; vmor.mm vd, vt, vd + emitToStreamer(Out, MCInstBuilder(Opcode) + .addOperand(Inst.getOperand(1)) + .addOperand(Inst.getOperand(2)) + .addOperand(Inst.getOperand(3)) + .addReg(RISCV::NoRegister)); + emitToStreamer(Out, MCInstBuilder(RISCV::VMANDNOT_MM) + .addOperand(Inst.getOperand(1)) + .addReg(RISCV::V0) + .addOperand(Inst.getOperand(1))); + emitToStreamer(Out, MCInstBuilder(RISCV::VMANDNOT_MM) + .addOperand(Inst.getOperand(0)) + .addOperand(Inst.getOperand(0)) + .addReg(RISCV::V0)); + emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM) + .addOperand(Inst.getOperand(0)) + .addOperand(Inst.getOperand(1)) + .addOperand(Inst.getOperand(0))); + } } Index: llvm/lib/Target/RISCV/RISCVInstrInfoV.td =================================================================== --- llvm/lib/Target/RISCV/RISCVInstrInfoV.td +++ llvm/lib/Target/RISCV/RISCVInstrInfoV.td @@ -662,10 +662,10 @@ def PseudoVMSGE_VX_M : Pseudo<(outs VRNoV0:$vd), (ins VR:$vs2, GPR:$rs1, VMaskOp:$vm), [], "vmsge.vx", "$vd, $vs2, $rs1$vm">; -def PseudoVMSGEU_VX_M_T : Pseudo<(outs VMV0:$vd, VR:$scratch), +def PseudoVMSGEU_VX_M_T : Pseudo<(outs VR:$vd, VR:$scratch), (ins VR:$vs2, GPR:$rs1, VMaskOp:$vm), [], "vmsgeu.vx", "$vd, $vs2, $rs1$vm, $scratch">; -def PseudoVMSGE_VX_M_T : Pseudo<(outs VMV0:$vd, VR:$scratch), +def PseudoVMSGE_VX_M_T : Pseudo<(outs VR:$vd, VR:$scratch), (ins VR:$vs2, GPR:$rs1, VMaskOp:$vm), [], "vmsge.vx", "$vd, $vs2, $rs1$vm, $scratch">; } Index: llvm/test/MC/RISCV/rvv/compare.s =================================================================== --- llvm/test/MC/RISCV/rvv/compare.s +++ llvm/test/MC/RISCV/rvv/compare.s @@ -436,3 +436,34 @@ # CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) # CHECK-UNKNOWN: 57 41 45 6c # CHECK-UNKNOWN: 57 20 01 62 + + +vmsgeu.vx v9, v4, a0, v0.t, v2 +# CHECK-INST: vmsltu.vx v2, v4, a0 +# CHECK-INST: vmandnot.mm v2, v0, v2 +# CHECK-INST: vmandnot.mm v9, v9, v0 +# CHECK-INST: vmor.mm v9, v2, v9 +# CHECK-ENCODING: [0x57,0x41,0x45,0x6a] +# CHECK-ENCODING: [0x57,0x21,0x01,0x62] +# CHECK-ENCODING: [0xd7,0x24,0x90,0x62] +# CHECK-ENCODING: [0xd7,0xa4,0x24,0x6a] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 41 45 6a +# CHECK-UNKNOWN: 57 21 01 62 +# CHECK-UNKNOWN: d7 24 90 62 +# CHECK-UNKNOWN: d7 a4 24 6a + +vmsge.vx v8, v4, a0, v0.t, v2 +# CHECK-INST: vmslt.vx v2, v4, a0 +# CHECK-INST: vmandnot.mm v2, v0, v2 +# CHECK-INST: vmandnot.mm v8, v8, v0 +# CHECK-INST: vmor.mm v8, v2, v8 +# CHECK-ENCODING: [0x57,0x41,0x45,0x6e] +# CHECK-ENCODING: [0x57,0x21,0x01,0x62] +# CHECK-ENCODING: [0x57,0x24,0x80,0x62] +# CHECK-ENCODING: [0x57,0x24,0x24,0x6a] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Instructions) +# CHECK-UNKNOWN: 57 41 45 6e +# CHECK-UNKNOWN: 57 21 01 62 +# CHECK-UNKNOWN: 57 24 80 62 +# CHECK-UNKNOWN: 57 24 24 6a \ No newline at end of file Index: llvm/test/MC/RISCV/rvv/invalid.s =================================================================== --- llvm/test/MC/RISCV/rvv/invalid.s +++ llvm/test/MC/RISCV/rvv/invalid.s @@ -551,10 +551,6 @@ # CHECK-ERROR: too few operands for instruction # CHECK-ERROR-LABEL: vmsge.vx v0, v4, a0, v0.t -vmsge.vx v8, v4, a0, v0.t, v2 -# CHECK-ERROR: invalid operand for instruction -# CHECK-ERROR-LABEL: vmsge.vx v8, v4, a0, v0.t, v2 - vmerge.vim v0, v1, 1, v0 # CHECK-ERROR: The destination vector register group cannot be V0. # CHECK-ERROR-LABEL: vmerge.vim v0, v1, 1, v0