diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -223,7 +223,7 @@ defm CPY_ZPmV : sve_int_perm_cpy_v<"cpy">; // Select elements from either vector (predicated) - defm SEL_ZPZZ : sve_int_sel_vvv<"sel">; + defm SEL_ZPZZ : sve_int_sel_vvv<"sel", vselect>; defm SPLICE_ZPZ : sve_int_perm_splice<"splice">; defm COMPACT_ZPZ : sve_int_perm_compact<"compact">; diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -1027,12 +1027,22 @@ let Inst{4-0} = Zd; } -multiclass sve_int_sel_vvv { +multiclass sve_int_sel_vvv { def _B : sve_int_sel_vvv<0b00, asm, ZPR8>; def _H : sve_int_sel_vvv<0b01, asm, ZPR16>; def _S : sve_int_sel_vvv<0b10, asm, ZPR32>; def _D : sve_int_sel_vvv<0b11, asm, ZPR64>; + def : SVE_3_Op_Pat(NAME # _B)>; + def : SVE_3_Op_Pat(NAME # _H)>; + def : SVE_3_Op_Pat(NAME # _S)>; + def : SVE_3_Op_Pat(NAME # _D)>; + + def : SVE_3_Op_Pat(NAME # _H)>; + def : SVE_3_Op_Pat(NAME # _S)>; + def : SVE_3_Op_Pat(NAME # _D)>; + def : SVE_3_Op_Pat(NAME # _D)>; + def : InstAlias<"mov $Zd, $Pg/m, $Zn", (!cast(NAME # _B) ZPR8:$Zd, PPRAny:$Pg, ZPR8:$Zn, ZPR8:$Zd), 1>; def : InstAlias<"mov $Zd, $Pg/m, $Zn", diff --git a/llvm/test/CodeGen/AArch64/sve-select.ll b/llvm/test/CodeGen/AArch64/sve-select.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve-select.ll @@ -0,0 +1,95 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; +; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s + +; Integer vector select + +define @sel_nxv16i8( %p, +; CHECK-LABEL: sel_nxv16i8: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z0.b, p0/m, z1.b +; CHECK-NEXT: ret + %dst, + %a) { + %sel = select %p, %a, %dst + ret %sel +} + +define @sel_nxv8i16( %p, +; CHECK-LABEL: sel_nxv8i16: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z0.h, p0/m, z1.h +; CHECK-NEXT: ret + %dst, + %a) { + %sel = select %p, %a, %dst + ret %sel +} + +define @sel_nxv4i32( %p, +; CHECK-LABEL: sel_nxv4i32: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z0.s, p0/m, z1.s +; CHECK-NEXT: ret + %dst, + %a) { + %sel = select %p, %a, %dst + ret %sel +} + +define @sel_nxv2i64( %p, +; CHECK-LABEL: sel_nxv2i64: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z0.d, p0/m, z1.d +; CHECK-NEXT: ret + %dst, + %a) { + %sel = select %p, %a, %dst + ret %sel +} + +; Floating point vector select + +define @sel_nxv8f16( %p, +; CHECK-LABEL: sel_nxv8f16: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z0.h, p0/m, z1.h +; CHECK-NEXT: ret + %dst, + %a) { + %sel = select %p, %a, %dst + ret %sel +} + +define @sel_nxv4f32( %p, +; CHECK-LABEL: sel_nxv4f32: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z0.s, p0/m, z1.s +; CHECK-NEXT: ret + %dst, + %a) { + %sel = select %p, %a, %dst + ret %sel +} + +define @sel_nxv2f32( %p, +; CHECK-LABEL: sel_nxv2f32: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z0.d, p0/m, z1.d +; CHECK-NEXT: ret + %dst, + %a) { + %sel = select %p, %a, %dst + ret %sel +} + +define @sel_nxv8f64( %p, +; CHECK-LABEL: sel_nxv8f64: +; CHECK: // %bb.0: +; CHECK-NEXT: mov z0.d, p0/m, z1.d +; CHECK-NEXT: ret + %dst, + %a) { + %sel = select %p, %a, %dst + ret %sel +}