Index: llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -2117,6 +2117,20 @@ def : InstAlias<"fcmlt $Zd, $Pg/z, $Zm, $Zn", (FCMGT_PPzZZ_D PPR64:$Zd, PPR3bAny:$Pg, ZPR64:$Zn, ZPR64:$Zm), 0>; + class AddSubFoldPattern + : Pat<(op (Zty ZPR:$Za), + (vselect (PTy PPR:$gp), (Zty ZPR:$Zb), (SVEDup0))), + (!cast(I # "_ZPmZ_" # size) PPR:$gp, ZPR:$Za, ZPR:$Zb)>; + multiclass add_sub_folds { + def : AddSubFoldPattern; + def : AddSubFoldPattern; + def : AddSubFoldPattern; + def : AddSubFoldPattern; + } + defm : add_sub_folds; + defm : add_sub_folds; + // Pseudo instructions representing unpredicated LDR and STR for ZPR2,3,4. // These get expanded to individual LDR_ZXI/STR_ZXI instructions in // AArch64ExpandPseudoInsts. Index: llvm/test/CodeGen/AArch64/sve-masked-add-sub.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/AArch64/sve-masked-add-sub.ll @@ -0,0 +1,90 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve < %s | FileCheck %s + +; +; Masked Additions +; + +define @masked_add_nxv16i8( %a, %b, %mask) { +; CHECK-LABEL: masked_add_nxv16i8: +; CHECK: // %bb.0: +; CHECK-NEXT: add z0.b, p0/m, z0.b, z1.b +; CHECK-NEXT: ret + %select = select %mask, %b, zeroinitializer + %ret = add %a, %select + ret %ret +} + +define @masked_add_nxv8i16( %a, %b, %mask) { +; CHECK-LABEL: masked_add_nxv8i16: +; CHECK: // %bb.0: +; CHECK-NEXT: add z0.h, p0/m, z0.h, z1.h +; CHECK-NEXT: ret + %select = select %mask, %b, zeroinitializer + %ret = add %a, %select + ret %ret +} + +define @masked_add_nxv4i32( %a, %b, %mask) { +; CHECK-LABEL: masked_add_nxv4i32: +; CHECK: // %bb.0: +; CHECK-NEXT: add z0.s, p0/m, z0.s, z1.s +; CHECK-NEXT: ret + %select = select %mask, %b, zeroinitializer + %ret = add %a, %select + ret %ret +} + +define @masked_add_nxv2i64( %a, %b, %mask) { +; CHECK-LABEL: masked_add_nxv2i64: +; CHECK: // %bb.0: +; CHECK-NEXT: add z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %select = select %mask, %b, zeroinitializer + %ret = add %a, %select + ret %ret +} + +; +; Masked Subtractions +; + +define @masked_sub_nxv16i8( %a, %b, %mask) { +; CHECK-LABEL: masked_sub_nxv16i8: +; CHECK: // %bb.0: +; CHECK-NEXT: sub z0.b, p0/m, z0.b, z1.b +; CHECK-NEXT: ret + %select = select %mask, %b, zeroinitializer + %ret = sub %a, %select + ret %ret +} + +define @masked_sub_nxv8i16( %a, %b, %mask) { +; CHECK-LABEL: masked_sub_nxv8i16: +; CHECK: // %bb.0: +; CHECK-NEXT: sub z0.h, p0/m, z0.h, z1.h +; CHECK-NEXT: ret + %select = select %mask, %b, zeroinitializer + %ret = sub %a, %select + ret %ret +} + +define @masked_sub_nxv4i32( %a, %b, %mask) { +; CHECK-LABEL: masked_sub_nxv4i32: +; CHECK: // %bb.0: +; CHECK-NEXT: sub z0.s, p0/m, z0.s, z1.s +; CHECK-NEXT: ret + %select = select %mask, %b, zeroinitializer + %ret = sub %a, %select + ret %ret +} + +define @masked_sub_nxv2i64( %a, %b, %mask) { +; CHECK-LABEL: masked_sub_nxv2i64: +; CHECK: // %bb.0: +; CHECK-NEXT: sub z0.d, p0/m, z0.d, z1.d +; CHECK-NEXT: ret + %select = select %mask, %b, zeroinitializer + %ret = sub %a, %select + ret %ret +}