diff --git a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp index c2b5e0135caea..e656e8bb99d86 100644 --- a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp +++ b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp @@ -747,6 +747,14 @@ getOperandLog2EEW(const MachineOperand &MO, const MachineRegisterInfo *MRI) { return TwoTimes ? MILog2SEW + 1 : MILog2SEW; } + // Vector Register Gather with 16-bit Index Elements Instruction + // Dest and source data EEW=SEW. Index vector EEW=16. + case RISCV::VRGATHEREI16_VV: { + if (MO.getOperandNo() == 2) + return 4; + return MILog2SEW; + } + default: return std::nullopt; } @@ -1058,6 +1066,11 @@ static bool isSupportedInstr(const MachineInstr &MI) { case RISCV::VSLIDEDOWN_VI: case RISCV::VSLIDE1UP_VX: case RISCV::VFSLIDE1UP_VF: + // Vector Register Gather Instructions + case RISCV::VRGATHER_VI: + case RISCV::VRGATHER_VV: + case RISCV::VRGATHER_VX: + case RISCV::VRGATHEREI16_VV: // Vector Single-Width Floating-Point Add/Subtract Instructions case RISCV::VFADD_VF: case RISCV::VFADD_VV: diff --git a/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll b/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll index a5bc04d66e49d..4883a4dcfcf67 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll @@ -5468,9 +5468,8 @@ define @vrgather_vi( %a, ; ; VLOPT-LABEL: vrgather_vi: ; VLOPT: # %bb.0: -; VLOPT-NEXT: vsetvli a1, zero, e32, m2, ta, ma -; VLOPT-NEXT: vrgather.vi v12, v8, 5 ; VLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; VLOPT-NEXT: vrgather.vi v12, v8, 5 ; VLOPT-NEXT: vadd.vv v8, v12, v10 ; VLOPT-NEXT: ret %1 = call @llvm.riscv.vrgather.vx.nxv4i32.iXLen( poison, %a, iXLen 5, iXLen -1) @@ -5489,9 +5488,8 @@ define @vrgather_vv( %a, ; ; VLOPT-LABEL: vrgather_vv: ; VLOPT: # %bb.0: -; VLOPT-NEXT: vsetvli a1, zero, e32, m2, ta, ma -; VLOPT-NEXT: vrgather.vv v12, v8, v10 ; VLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; VLOPT-NEXT: vrgather.vv v12, v8, v10 ; VLOPT-NEXT: vadd.vv v8, v12, v8 ; VLOPT-NEXT: ret %1 = call @llvm.riscv.vrgather.vv.nxv4i32( poison, %a, %idx, iXLen -1) @@ -5510,9 +5508,8 @@ define @vrgather_vx( %a, iXLen %idx, @llvm.riscv.vrgather.vx.nxv4i32.iXLen( poison, %a, iXLen %idx, iXLen -1) @@ -5531,9 +5528,8 @@ define @vrgatherei16_vv( %a, @llvm.riscv.vrgatherei16.vv.nxv4i32( poison, %a, %idx, iXLen -1) 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 b39ba422bd349..52cd3e35e6eb8 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir +++ b/llvm/test/CodeGen/RISCV/rvv/vl-opt-op-info.mir @@ -1801,4 +1801,63 @@ body: | ; CHECK-NEXT: %y:vr = PseudoVMAND_MM_B16 $noreg, %x, 1, 0 /* e8 */ %x:vr = PseudoVMSET_M_B8 -1, 0 %y:vr = PseudoVMAND_MM_B16 $noreg, %x, 1, 0 +... +--- +name: vrgatherei16_vv +body: | + bb.0: + ; CHECK-LABEL: name: vrgatherei16_vv + ; CHECK: early-clobber %x:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, $noreg, $noreg, 1, 5 /* e32 */, 0 /* tu, mu */ + ; CHECK-NEXT: %y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 5 /* e32 */, 0 /* tu, mu */ + %x:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, $noreg, $noreg, -1, 5 /* e32 */, 0 + %y:vr = PseudoVADD_VV_M1 $noreg, %x, $noreg, 1, 5 /* e32 */, 0 +... +--- +name: vrgatherei16_vv_incompatible_data_eew +body: | + bb.0: + ; CHECK-LABEL: name: vrgatherei16_vv_incompatible_data_eew + ; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 4 /* e16 */, 0 /* tu, mu */ + ; CHECK-NEXT: early-clobber %y:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, %x, $noreg, 1, 5 /* e32 */, 0 /* tu, mu */ + %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 4 /* e16 */, 0 + %y:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, %x, $noreg, 1, 5 /* e32 */, 0 +... --- +name: vrgatherei16_vv_incompatible_index_eew +body: | + bb.0: + ; CHECK-LABEL: name: vrgatherei16_vv_incompatible_index_eew + ; CHECK: %x:vr = PseudoVADD_VV_MF2 $noreg, $noreg, $noreg, -1, 4 /* e16 */, 0 /* tu, mu */ + ; CHECK-NEXT: early-clobber %y:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, $noreg, %x, 1, 5 /* e32 */, 0 /* tu, mu */ + %x:vr = PseudoVADD_VV_MF2 $noreg, $noreg, $noreg, -1, 4 /* e16 */, 0 + %y:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, $noreg, %x, 1, 5 /* e32 */, 0 +... +--- +name: vrgatherei16_vv_incompatible_dest_emul +body: | + bb.0: + ; CHECK-LABEL: name: vrgatherei16_vv_incompatible_dest_emul + ; CHECK: early-clobber %x:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, $noreg, $noreg, -1, 5 /* e32 */, 0 /* tu, mu */ + ; CHECK-NEXT: %y:vr = PseudoVADD_VV_MF2 $noreg, %x, $noreg, 1, 5 /* e32 */, 0 /* tu, mu */ + %x:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, $noreg, $noreg, -1, 5 /* e32 */, 0 + %y:vr = PseudoVADD_VV_MF2 $noreg, %x, $noreg, 1, 5 /* e32 */, 0 +... +--- +name: vrgatherei16_vv_incompatible_source_emul +body: | + bb.0: + ; CHECK-LABEL: name: vrgatherei16_vv_incompatible_source_emul + ; CHECK: %x:vr = PseudoVADD_VV_MF2 $noreg, $noreg, $noreg, -1, 5 /* e32 */, 0 /* tu, mu */ + ; CHECK-NEXT: early-clobber %y:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, %x, $noreg, 1, 5 /* e32 */, 0 /* tu, mu */ + %x:vr = PseudoVADD_VV_MF2 $noreg, $noreg, $noreg, -1, 5 /* e32 */, 0 + %y:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, %x, $noreg, 1, 5 /* e32 */, 0 +... +--- +name: vrgatherei16_vv_incompatible_index_emul +body: | + bb.0: + ; CHECK-LABEL: name: vrgatherei16_vv_incompatible_index_emul + ; CHECK: %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 4 /* e16 */, 0 /* tu, mu */ + ; CHECK-NEXT: early-clobber %y:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, $noreg, %x, 1, 5 /* e32 */, 0 /* tu, mu */ + %x:vr = PseudoVADD_VV_M1 $noreg, $noreg, $noreg, -1, 4 /* e16 */, 0 + %y:vr = PseudoVRGATHEREI16_VV_M1_E32_MF2 $noreg, $noreg, %x, 1, 5 /* e32 */, 0