diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoVSDPatterns.td @@ -547,6 +547,40 @@ vti.AVL, vti.Log2SEW, TAIL_AGNOSTIC)>; } +// 12.14 Vector Widening Integer Multiply-Add Instructions +multiclass VPatWidenMulAddSDNode_VV { + foreach vti = AllWidenableIntVectors in { + def : Pat< + (add (vti.Wti.Vector vti.Wti.RegClass:$rd), + (mul_oneuse (vti.Wti.Vector (extop1 (vti.Vti.Vector vti.Vti.RegClass:$rs1))), + (vti.Wti.Vector (extop2 (vti.Vti.Vector vti.Vti.RegClass:$rs2))))), + (!cast(instruction_name#"_VV_"#vti.Vti.LMul.MX) + vti.Wti.RegClass:$rd, vti.Vti.RegClass:$rs1, vti.Vti.RegClass:$rs2, + vti.Vti.AVL, vti.Vti.Log2SEW, TAIL_AGNOSTIC + )>; + } +} +multiclass VPatWidenMulAddSDNode_VX { + foreach vti = AllWidenableIntVectors in { + def : Pat< + (add (vti.Wti.Vector vti.Wti.RegClass:$rd), + (mul_oneuse (vti.Wti.Vector (extop1 (vti.Vti.Vector (SplatPat GPR:$rs1)))), + (vti.Wti.Vector (extop2 (vti.Vti.Vector vti.Vti.RegClass:$rs2))))), + (!cast(instruction_name#"_VX_"#vti.Vti.LMul.MX) + vti.Wti.RegClass:$rd, GPR:$rs1, vti.Vti.RegClass:$rs2, + vti.Vti.AVL, vti.Vti.Log2SEW, TAIL_AGNOSTIC + )>; + } +} + +defm : VPatWidenMulAddSDNode_VV; +defm : VPatWidenMulAddSDNode_VX; +defm : VPatWidenMulAddSDNode_VV; +defm : VPatWidenMulAddSDNode_VX; +defm : VPatWidenMulAddSDNode_VV; +defm : VPatWidenMulAddSDNode_VX; +defm : VPatWidenMulAddSDNode_VX; + // 12.15. Vector Integer Merge Instructions foreach vti = AllIntegerVectors in { def : Pat<(vti.Vector (vselect (vti.Mask V0), vti.RegClass:$rs1, diff --git a/llvm/test/CodeGen/RISCV/rvv/vwmacc-sdnode.ll b/llvm/test/CodeGen/RISCV/rvv/vwmacc-sdnode.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/RISCV/rvv/vwmacc-sdnode.ll @@ -0,0 +1,457 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=riscv32 -mattr=+experimental-v -target-abi=ilp32 \ +; RUN: -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK +; RUN: llc -mtriple=riscv64 -mattr=+experimental-v -target-abi=lp64 \ +; RUN: -verify-machineinstrs < %s | FileCheck %s --check-prefixes=CHECK + +define @vwmacc_vv_nxv1i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmacc_vv_nxv1i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, mu +; CHECK-NEXT: vwmacc.vv v10, v8, v9 +; CHECK-NEXT: vmv1r.v v8, v10 +; CHECK-NEXT: ret + %vd = sext %va to + %ve = sext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmacc_vx_nxv1i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmacc_vx_nxv1i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, mu +; CHECK-NEXT: vwmacc.vx v9, a0, v8 +; CHECK-NEXT: vmv1r.v v8, v9 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = sext %va to + %ve = sext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccu_vv_nxv1i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmaccu_vv_nxv1i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, mu +; CHECK-NEXT: vwmaccu.vv v10, v8, v9 +; CHECK-NEXT: vmv1r.v v8, v10 +; CHECK-NEXT: ret + %vd = zext %va to + %ve = zext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccu_vx_nxv1i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccu_vx_nxv1i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, mu +; CHECK-NEXT: vwmaccu.vx v9, a0, v8 +; CHECK-NEXT: vmv1r.v v8, v9 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = zext %va to + %ve = zext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccsu_vv_nxv1i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmaccsu_vv_nxv1i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, mf2, ta, mu +; CHECK-NEXT: vwmaccsu.vv v10, v9, v8 +; CHECK-NEXT: vmv1r.v v8, v10 +; CHECK-NEXT: ret + %vd = zext %va to + %ve = sext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccsu_vx_nxv1i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccsu_vx_nxv1i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, mu +; CHECK-NEXT: vwmaccsu.vx v9, a0, v8 +; CHECK-NEXT: vmv1r.v v8, v9 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = zext %va to + %ve = sext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccus_vx_nxv1i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccus_vx_nxv1i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, mf2, ta, mu +; CHECK-NEXT: vwmaccus.vx v9, a0, v8 +; CHECK-NEXT: vmv1r.v v8, v9 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = sext %va to + %ve = zext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmacc_vv_nxv2i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmacc_vv_nxv2i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, mu +; CHECK-NEXT: vwmacc.vv v10, v8, v9 +; CHECK-NEXT: vmv2r.v v8, v10 +; CHECK-NEXT: ret + %vd = sext %va to + %ve = sext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmacc_vx_nxv2i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmacc_vx_nxv2i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, mu +; CHECK-NEXT: vwmacc.vx v10, a0, v8 +; CHECK-NEXT: vmv2r.v v8, v10 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = sext %va to + %ve = sext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccu_vv_nxv2i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmaccu_vv_nxv2i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, mu +; CHECK-NEXT: vwmaccu.vv v10, v8, v9 +; CHECK-NEXT: vmv2r.v v8, v10 +; CHECK-NEXT: ret + %vd = zext %va to + %ve = zext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccu_vx_nxv2i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccu_vx_nxv2i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, mu +; CHECK-NEXT: vwmaccu.vx v10, a0, v8 +; CHECK-NEXT: vmv2r.v v8, v10 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = zext %va to + %ve = zext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccsu_vv_nxv2i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmaccsu_vv_nxv2i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, mu +; CHECK-NEXT: vwmaccsu.vv v10, v9, v8 +; CHECK-NEXT: vmv2r.v v8, v10 +; CHECK-NEXT: ret + %vd = zext %va to + %ve = sext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccsu_vx_nxv2i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccsu_vx_nxv2i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, mu +; CHECK-NEXT: vwmaccsu.vx v10, a0, v8 +; CHECK-NEXT: vmv2r.v v8, v10 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = zext %va to + %ve = sext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccus_vx_nxv2i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccus_vx_nxv2i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, mu +; CHECK-NEXT: vwmaccus.vx v10, a0, v8 +; CHECK-NEXT: vmv2r.v v8, v10 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = sext %va to + %ve = zext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmacc_vv_nxv4i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmacc_vv_nxv4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, mu +; CHECK-NEXT: vwmacc.vv v12, v8, v10 +; CHECK-NEXT: vmv4r.v v8, v12 +; CHECK-NEXT: ret + %vd = sext %va to + %ve = sext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmacc_vx_nxv4i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmacc_vx_nxv4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, mu +; CHECK-NEXT: vwmacc.vx v12, a0, v8 +; CHECK-NEXT: vmv4r.v v8, v12 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = sext %va to + %ve = sext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccu_vv_nxv4i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmaccu_vv_nxv4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, mu +; CHECK-NEXT: vwmaccu.vv v12, v8, v10 +; CHECK-NEXT: vmv4r.v v8, v12 +; CHECK-NEXT: ret + %vd = zext %va to + %ve = zext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccu_vx_nxv4i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccu_vx_nxv4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, mu +; CHECK-NEXT: vwmaccu.vx v12, a0, v8 +; CHECK-NEXT: vmv4r.v v8, v12 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = zext %va to + %ve = zext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccsu_vv_nxv4i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmaccsu_vv_nxv4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m2, ta, mu +; CHECK-NEXT: vwmaccsu.vv v12, v10, v8 +; CHECK-NEXT: vmv4r.v v8, v12 +; CHECK-NEXT: ret + %vd = zext %va to + %ve = sext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccsu_vx_nxv4i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccsu_vx_nxv4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, mu +; CHECK-NEXT: vwmaccsu.vx v12, a0, v8 +; CHECK-NEXT: vmv4r.v v8, v12 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = zext %va to + %ve = sext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccus_vx_nxv4i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccus_vx_nxv4i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m2, ta, mu +; CHECK-NEXT: vwmaccus.vx v12, a0, v8 +; CHECK-NEXT: vmv4r.v v8, v12 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = sext %va to + %ve = zext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmacc_vv_nxv8i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmacc_vv_nxv8i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, mu +; CHECK-NEXT: vwmacc.vv v16, v8, v12 +; CHECK-NEXT: vmv8r.v v8, v16 +; CHECK-NEXT: ret + %vd = sext %va to + %ve = sext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmacc_vx_nxv8i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmacc_vx_nxv8i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m4, ta, mu +; CHECK-NEXT: vwmacc.vx v16, a0, v8 +; CHECK-NEXT: vmv8r.v v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = sext %va to + %ve = sext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccu_vv_nxv8i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmaccu_vv_nxv8i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, mu +; CHECK-NEXT: vwmaccu.vv v16, v8, v12 +; CHECK-NEXT: vmv8r.v v8, v16 +; CHECK-NEXT: ret + %vd = zext %va to + %ve = zext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccu_vx_nxv8i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccu_vx_nxv8i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m4, ta, mu +; CHECK-NEXT: vwmaccu.vx v16, a0, v8 +; CHECK-NEXT: vmv8r.v v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = zext %va to + %ve = zext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccsu_vv_nxv8i32( %va, %vb, %vc) { +; CHECK-LABEL: vwmaccsu_vv_nxv8i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a0, zero, e32, m4, ta, mu +; CHECK-NEXT: vwmaccsu.vv v16, v12, v8 +; CHECK-NEXT: vmv8r.v v8, v16 +; CHECK-NEXT: ret + %vd = zext %va to + %ve = sext %vb to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccsu_vx_nxv8i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccsu_vx_nxv8i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m4, ta, mu +; CHECK-NEXT: vwmaccsu.vx v16, a0, v8 +; CHECK-NEXT: vmv8r.v v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = zext %va to + %ve = sext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +} + +define @vwmaccus_vx_nxv8i32( %va, i32 %b, %vc) { +; CHECK-LABEL: vwmaccus_vx_nxv8i32: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli a1, zero, e32, m4, ta, mu +; CHECK-NEXT: vwmaccus.vx v16, a0, v8 +; CHECK-NEXT: vmv8r.v v8, v16 +; CHECK-NEXT: ret + %head = insertelement undef, i32 %b, i32 0 + %splat = shufflevector %head, undef, zeroinitializer + %vd = sext %va to + %ve = zext %splat to + + %x = mul %vd, %ve + %y = add %x, %vc + ret %y +}