diff --git a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp index ab73b112e6dd8..9870279ad17c7 100644 --- a/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp +++ b/llvm/lib/Target/RISCV/RISCVVLOptimizer.cpp @@ -963,6 +963,15 @@ static bool isSupportedInstr(const MachineInstr &MI) { case RISCV::VMV_V_I: case RISCV::VMV_V_X: case RISCV::VMV_V_V: + // Vector Single-Width Averaging Add and Subtract + case RISCV::VAADDU_VV: + case RISCV::VAADDU_VX: + case RISCV::VAADD_VV: + case RISCV::VAADD_VX: + case RISCV::VASUBU_VV: + case RISCV::VASUBU_VX: + case RISCV::VASUB_VV: + case RISCV::VASUB_VX: // Vector Crypto case RISCV::VWSLL_VI: diff --git a/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll b/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll index da7917cae8ba6..ce79bd5d5ddcf 100644 --- a/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vl-opt-instrs.ll @@ -3595,3 +3595,179 @@ define @vmerge_vim( %a, % %2 = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %1, %1, iXLen %vl) ret %2 } + +define @vaadd_vv( %a, %b, iXLen %vl) { +; NOVLOPT-LABEL: vaadd_vv: +; NOVLOPT: # %bb.0: +; NOVLOPT-NEXT: csrwi vxrm, 0 +; NOVLOPT-NEXT: vsetvli a1, zero, e32, m2, ta, ma +; NOVLOPT-NEXT: vaadd.vv v8, v8, v10 +; NOVLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; NOVLOPT-NEXT: vadd.vv v8, v8, v10 +; NOVLOPT-NEXT: ret +; +; VLOPT-LABEL: vaadd_vv: +; VLOPT: # %bb.0: +; VLOPT-NEXT: csrwi vxrm, 0 +; VLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; VLOPT-NEXT: vaadd.vv v8, v8, v10 +; VLOPT-NEXT: vadd.vv v8, v8, v10 +; VLOPT-NEXT: ret + %1 = call @llvm.riscv.vaadd.nxv4i32.nxv4i32( poison, %a, %b, iXLen 0, iXLen -1) + %2 = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %1, %b, iXLen %vl) + ret %2 +} + +define @vaadd_vx( %a, i32 %b, iXLen %vl) { +; NOVLOPT-LABEL: vaadd_vx: +; NOVLOPT: # %bb.0: +; NOVLOPT-NEXT: csrwi vxrm, 0 +; NOVLOPT-NEXT: vsetvli a2, zero, e32, m2, ta, ma +; NOVLOPT-NEXT: vaadd.vx v10, v8, a0 +; NOVLOPT-NEXT: vsetvli zero, a1, e32, m2, ta, ma +; NOVLOPT-NEXT: vadd.vv v8, v10, v8 +; NOVLOPT-NEXT: ret +; +; VLOPT-LABEL: vaadd_vx: +; VLOPT: # %bb.0: +; VLOPT-NEXT: csrwi vxrm, 0 +; VLOPT-NEXT: vsetvli zero, a1, e32, m2, ta, ma +; VLOPT-NEXT: vaadd.vx v10, v8, a0 +; VLOPT-NEXT: vadd.vv v8, v10, v8 +; VLOPT-NEXT: ret + %1 = call @llvm.riscv.vaadd.nxv4i32.nxv4i32( poison, %a, i32 %b, iXLen 0, iXLen -1) + %2 = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %1, %a, iXLen %vl) + ret %2 +} + +define @vasub_vv( %a, %b, iXLen %vl) { +; NOVLOPT-LABEL: vasub_vv: +; NOVLOPT: # %bb.0: +; NOVLOPT-NEXT: csrwi vxrm, 0 +; NOVLOPT-NEXT: vsetvli a1, zero, e32, m2, ta, ma +; NOVLOPT-NEXT: vasub.vv v8, v8, v10 +; NOVLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; NOVLOPT-NEXT: vadd.vv v8, v8, v10 +; NOVLOPT-NEXT: ret +; +; VLOPT-LABEL: vasub_vv: +; VLOPT: # %bb.0: +; VLOPT-NEXT: csrwi vxrm, 0 +; VLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; VLOPT-NEXT: vasub.vv v8, v8, v10 +; VLOPT-NEXT: vadd.vv v8, v8, v10 +; VLOPT-NEXT: ret + %1 = call @llvm.riscv.vasub.nxv4i32.nxv4i32( poison, %a, %b, iXLen 0, iXLen -1) + %2 = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %1, %b, iXLen %vl) + ret %2 +} + +define @vasub_vx( %a, i32 %b, iXLen %vl) { +; NOVLOPT-LABEL: vasub_vx: +; NOVLOPT: # %bb.0: +; NOVLOPT-NEXT: csrwi vxrm, 0 +; NOVLOPT-NEXT: vsetvli a2, zero, e32, m2, ta, ma +; NOVLOPT-NEXT: vasub.vx v10, v8, a0 +; NOVLOPT-NEXT: vsetvli zero, a1, e32, m2, ta, ma +; NOVLOPT-NEXT: vadd.vv v8, v10, v8 +; NOVLOPT-NEXT: ret +; +; VLOPT-LABEL: vasub_vx: +; VLOPT: # %bb.0: +; VLOPT-NEXT: csrwi vxrm, 0 +; VLOPT-NEXT: vsetvli zero, a1, e32, m2, ta, ma +; VLOPT-NEXT: vasub.vx v10, v8, a0 +; VLOPT-NEXT: vadd.vv v8, v10, v8 +; VLOPT-NEXT: ret + %1 = call @llvm.riscv.vasub.nxv4i32.nxv4i32( poison, %a, i32 %b, iXLen 0, iXLen -1) + %2 = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %1, %a, iXLen %vl) + ret %2 +} + +define @vaaddu_vv( %a, %b, iXLen %vl) { +; NOVLOPT-LABEL: vaaddu_vv: +; NOVLOPT: # %bb.0: +; NOVLOPT-NEXT: csrwi vxrm, 0 +; NOVLOPT-NEXT: vsetvli a1, zero, e32, m2, ta, ma +; NOVLOPT-NEXT: vaaddu.vv v8, v8, v10 +; NOVLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; NOVLOPT-NEXT: vadd.vv v8, v8, v10 +; NOVLOPT-NEXT: ret +; +; VLOPT-LABEL: vaaddu_vv: +; VLOPT: # %bb.0: +; VLOPT-NEXT: csrwi vxrm, 0 +; VLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; VLOPT-NEXT: vaaddu.vv v8, v8, v10 +; VLOPT-NEXT: vadd.vv v8, v8, v10 +; VLOPT-NEXT: ret + %1 = call @llvm.riscv.vaaddu.nxv4i32.nxv4i32( poison, %a, %b, iXLen 0, iXLen -1) + %2 = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %1, %b, iXLen %vl) + ret %2 +} + +define @vaaddu_vx( %a, i32 %b, iXLen %vl) { +; NOVLOPT-LABEL: vaaddu_vx: +; NOVLOPT: # %bb.0: +; NOVLOPT-NEXT: csrwi vxrm, 0 +; NOVLOPT-NEXT: vsetvli a2, zero, e32, m2, ta, ma +; NOVLOPT-NEXT: vaaddu.vx v10, v8, a0 +; NOVLOPT-NEXT: vsetvli zero, a1, e32, m2, ta, ma +; NOVLOPT-NEXT: vadd.vv v8, v10, v8 +; NOVLOPT-NEXT: ret +; +; VLOPT-LABEL: vaaddu_vx: +; VLOPT: # %bb.0: +; VLOPT-NEXT: csrwi vxrm, 0 +; VLOPT-NEXT: vsetvli zero, a1, e32, m2, ta, ma +; VLOPT-NEXT: vaaddu.vx v10, v8, a0 +; VLOPT-NEXT: vadd.vv v8, v10, v8 +; VLOPT-NEXT: ret + %1 = call @llvm.riscv.vaaddu.nxv4i32.nxv4i32( poison, %a, i32 %b, iXLen 0, iXLen -1) + %2 = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %1, %a, iXLen %vl) + ret %2 +} + +define @vasubu_vv( %a, %b, iXLen %vl) { +; NOVLOPT-LABEL: vasubu_vv: +; NOVLOPT: # %bb.0: +; NOVLOPT-NEXT: csrwi vxrm, 0 +; NOVLOPT-NEXT: vsetvli a1, zero, e32, m2, ta, ma +; NOVLOPT-NEXT: vasubu.vv v8, v8, v10 +; NOVLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; NOVLOPT-NEXT: vadd.vv v8, v8, v10 +; NOVLOPT-NEXT: ret +; +; VLOPT-LABEL: vasubu_vv: +; VLOPT: # %bb.0: +; VLOPT-NEXT: csrwi vxrm, 0 +; VLOPT-NEXT: vsetvli zero, a0, e32, m2, ta, ma +; VLOPT-NEXT: vasubu.vv v8, v8, v10 +; VLOPT-NEXT: vadd.vv v8, v8, v10 +; VLOPT-NEXT: ret + %1 = call @llvm.riscv.vasubu.nxv4i32.nxv4i32( poison, %a, %b, iXLen 0, iXLen -1) + %2 = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %1, %b, iXLen %vl) + ret %2 +} + +define @vasubu_vx( %a, i32 %b, iXLen %vl) { +; NOVLOPT-LABEL: vasubu_vx: +; NOVLOPT: # %bb.0: +; NOVLOPT-NEXT: csrwi vxrm, 0 +; NOVLOPT-NEXT: vsetvli a2, zero, e32, m2, ta, ma +; NOVLOPT-NEXT: vasubu.vx v10, v8, a0 +; NOVLOPT-NEXT: vsetvli zero, a1, e32, m2, ta, ma +; NOVLOPT-NEXT: vadd.vv v8, v10, v8 +; NOVLOPT-NEXT: ret +; +; VLOPT-LABEL: vasubu_vx: +; VLOPT: # %bb.0: +; VLOPT-NEXT: csrwi vxrm, 0 +; VLOPT-NEXT: vsetvli zero, a1, e32, m2, ta, ma +; VLOPT-NEXT: vasubu.vx v10, v8, a0 +; VLOPT-NEXT: vadd.vv v8, v10, v8 +; VLOPT-NEXT: ret + %1 = call @llvm.riscv.vasubu.nxv4i32.nxv4i32( poison, %a, i32 %b, iXLen 0, iXLen -1) + %2 = call @llvm.riscv.vadd.nxv4i32.nxv4i32( poison, %1, %a, iXLen %vl) + ret %2 +}