diff --git a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp index a9e5bb6ecd9b8..e8719d02cfa0a 100644 --- a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp +++ b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp @@ -412,6 +412,8 @@ static OperandInfo getOperandInfo(const MachineOperand &MO, // Vector Compress Instruction // EMUL=LMUL. EEW=SEW. case RISCV::VCOMPRESS_VM: + // Vector Element Index Instruction + case RISCV::VID_V: return OperandInfo(MIVLMul, MILog2SEW); // Vector Widening Integer Add/Subtract @@ -527,6 +529,15 @@ static OperandInfo getOperandInfo(const MachineOperand &MO, return OperandInfo(RISCVVType::getEMULEqualsEEWDivSEWTimesLMUL(0, MI), 0); } + // Vector Iota Instruction + // EEW=SEW and EMUL=LMUL, except the mask operand has EEW=1 and EMUL= + // (EEW/SEW)*LMUL. Mask operand is not handled before this switch. + case RISCV::VIOTA_M: { + if (IsMODef || MO.getOperandNo() == 1) + return OperandInfo(MIVLMul, MILog2SEW); + return OperandInfo(RISCVVType::getEMULEqualsEEWDivSEWTimesLMUL(0, MI), 0); + } + // Vector Integer Compare Instructions // Dest EEW=1 and EMUL=(EEW/SEW)*LMUL. Source EEW=SEW and EMUL=LMUL. case RISCV::VMSEQ_VI: @@ -738,6 +749,8 @@ static bool isSupportedInstr(const MachineInstr &MI) { // vmsbf.m set-before-first mask bit // vmsif.m set-including-first mask bit // vmsof.m set-only-first mask bit + // Vector Iota Instruction + // Vector Element Index Instruction case RISCV::VMAND_MM: case RISCV::VMNAND_MM: case RISCV::VMANDN_MM: @@ -749,6 +762,8 @@ static bool isSupportedInstr(const MachineInstr &MI) { case RISCV::VMSBF_M: case RISCV::VMSIF_M: case RISCV::VMSOF_M: + case RISCV::VIOTA_M: + case RISCV::VID_V: return true; } diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector-shuffle.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector-shuffle.ll index 245b4a8a9c100..3012831ed873e 100644 --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector-shuffle.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-insert-subvector-shuffle.ll @@ -55,9 +55,9 @@ define <4 x i32> @insert_subvector_load_foldable_passthru_v4i32_v4i32(<4 x i32> define <4 x i32> @insert_subvector_add_v4i32_v4i32(<4 x i32> %v1, <4 x i32> %v2) { ; CHECK-LABEL: insert_subvector_add_v4i32_v4i32: ; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma ; CHECK-NEXT: vid.v v10 -; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, ma +; CHECK-NEXT: vsetvli zero, zero, e32, m1, tu, ma ; CHECK-NEXT: vadd.vv v8, v9, v10 ; CHECK-NEXT: ret %v3 = add <4 x i32> %v2, @@ -166,9 +166,9 @@ define <4 x i32> @insert_subvector_vp_load_v4i32_v8i32(<4 x i32> %v1, ptr %p, <8 define <4 x i32> @insert_subvector_add_v4i32_v8i32(<4 x i32> %v1, <8 x i32> %v2) { ; CHECK-LABEL: insert_subvector_add_v4i32_v8i32: ; CHECK: # %bb.0: -; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma +; CHECK-NEXT: vsetivli zero, 2, e32, m1, ta, ma ; CHECK-NEXT: vid.v v9 -; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, ma +; CHECK-NEXT: vsetvli zero, zero, e32, m1, tu, ma ; CHECK-NEXT: vadd.vv v8, v10, v9 ; CHECK-NEXT: ret %v3 = add <8 x i32> %v2, diff --git a/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll b/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll index faa41ec61cd12..55a50a15c788c 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll @@ -2885,3 +2885,43 @@ define @vmsof_m( %a, %c, %3 = call @llvm.riscv.vadd.mask.nxv1i32.nxv1i32( %c, %c, %c, %2, iXLen %vl, iXLen 0) ret %3 } + +define @viota_m( %a, %c, iXLen %vl) { +; NOVLOPT-LABEL: viota_m: +; NOVLOPT: # %bb.0: +; NOVLOPT-NEXT: vsetvli a1, zero, e32, m2, ta, ma +; NOVLOPT-NEXT: viota.m v10, v0 +; NOVLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; NOVLOPT-NEXT: vadd.vv v8, v10, v8 +; NOVLOPT-NEXT: ret +; +; VLOPT-LABEL: viota_m: +; VLOPT: # %bb.0: +; VLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; VLOPT-NEXT: viota.m v10, v0 +; VLOPT-NEXT: vadd.vv v8, v10, v8 +; VLOPT-NEXT: ret + %1 = call @llvm.riscv.viota.nxv4i32( poison, %a, iXLen -1) + %2 = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %1, %c, iXLen %vl) + ret %2 +} + +define @vid.v( %c, iXLen %vl) { +; NOVLOPT-LABEL: vid.v: +; NOVLOPT: # %bb.0: +; NOVLOPT-NEXT: vsetvli a1, zero, e32, m2, ta, ma +; NOVLOPT-NEXT: vid.v v10 +; NOVLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; NOVLOPT-NEXT: vadd.vv v8, v10, v8 +; NOVLOPT-NEXT: ret +; +; VLOPT-LABEL: vid.v: +; VLOPT: # %bb.0: +; VLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; VLOPT-NEXT: vid.v v10 +; VLOPT-NEXT: vadd.vv v8, v10, v8 +; VLOPT-NEXT: ret + %1 = call @llvm.riscv.vid.nxv4i32( poison, iXLen -1) + %2 = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %1, %c, iXLen %vl) + ret %2 +} diff --git a/llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir b/llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir index 8587ec136afd8..808f1d4e939c1 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir +++ b/llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir @@ -892,3 +892,73 @@ body: | %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 3 /* e8 */, 0 %y:vr = PseudoVMV_V_V_MF2 $noreg, %x, 1, 3 /* e8 */, 0 ... +--- +name: viota_m_dest +body: | + bb.0: + ; CHECK-LABEL: name: viota_m_dest + ; CHECK: early-clobber %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */ + ; CHECK-NEXT: %y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */ + %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, -1, 3 /* e8 */, 0 + %y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 3 /* e8 */, 0 +... +--- +name: viota_m_dest_incompatible_eew +body: | + bb.0: + ; CHECK-LABEL: name: viota_m_dest_incompatible_eew + ; CHECK: early-clobber %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, -1, 3 /* e8 */, 0 /* tu, mu */ + ; CHECK-NEXT: %y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 4 /* e16 */, 0 /* tu, mu */ + %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, -1, 3 /* e8 */, 0 + %y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 4 /* e16 */, 0 +... +--- +name: viota_m_dest_incompatible_emul +body: | + bb.0: + ; CHECK-LABEL: name: viota_m_dest_incompatible_emul + ; CHECK: early-clobber %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, -1, 3 /* e8 */, 0 /* tu, mu */ + ; CHECK-NEXT: %y:vr = PseudoVADD_VV_MF2 $noreg, %x, $noreg, 1, 3 /* e8 */, 0 /* tu, mu */ + %x:vr = PseudoVIOTA_M_M1 $noreg, $noreg, -1, 3 /* e8 */, 0 + %y:vr = PseudoVADD_VV_MF2 $noreg, %x, $noreg, 1, 3 /* e8 */, 0 +... +--- +name: viota_m_mask +body: | + bb.0: + ; CHECK-LABEL: name: viota_m_mask + ; CHECK: %x:vr = PseudoVMSEQ_VV_M1 $noreg, $noreg, 1, 3 /* e8 */ + ; CHECK-NEXT: early-clobber %y:vr = PseudoVIOTA_M_M1 $noreg, %x, 1, 3 /* e8 */, 0 /* tu, mu */ + %x:vr = PseudoVMSEQ_VV_M1 $noreg, $noreg, -1, 3 /* e8 */ + %y:vr = PseudoVIOTA_M_M1 $noreg, %x, 1, 3 /* e8 */, 0 +... +--- +name: viota_m_mask_scale_mask +body: | + bb.0: + ; CHECK-LABEL: name: viota_m_mask_scale_mask + ; CHECK: early-clobber %x:vr = PseudoVMSEQ_VV_M2 $noreg, $noreg, 1, 4 /* e16 */ + ; CHECK-NEXT: early-clobber %y:vr = PseudoVIOTA_M_M1 $noreg, %x, 1, 3 /* e8 */, 0 /* tu, mu */ + %x:vr = PseudoVMSEQ_VV_M2 $noreg, $noreg, -1, 4 /* e16 */ + %y:vr = PseudoVIOTA_M_M1 $noreg, %x, 1, 3 /* e8 */, 0 +... +--- +name: viota_m_mask_incompatible_emul_from_sew +body: | + bb.0: + ; CHECK-LABEL: name: viota_m_mask_incompatible_emul_from_sew + ; CHECK: %x:vr = PseudoVMAND_MM_B1 $noreg, $noreg, -1, 0 /* e8 */ + ; CHECK-NEXT: early-clobber %y:vr = PseudoVIOTA_M_M1 $noreg, %x, 1, 4 /* e16 */, 0 /* tu, mu */ + %x:vr = PseudoVMAND_MM_B1 $noreg, $noreg, -1, 0 + %y:vr = PseudoVIOTA_M_M1 $noreg, %x, 1, 4 /* e16 */, 0 +... +--- +name: viota_m_mask_incompatible_emul_from_lmul +body: | + bb.0: + ; CHECK-LABEL: name: viota_m_mask_incompatible_emul_from_lmul + ; CHECK: %x:vr = PseudoVMAND_MM_B1 $noreg, $noreg, -1, 0 /* e8 */ + ; CHECK-NEXT: early-clobber %y:vr = PseudoVIOTA_M_MF2 $noreg, %x, 1, 3 /* e8 */, 0 /* tu, mu */ + %x:vr = PseudoVMAND_MM_B1 $noreg, $noreg, -1, 0 + %y:vr = PseudoVIOTA_M_MF2 $noreg, %x, 1, 3 /* e8 */, 0 +...