diff --git a/llvm/include/llvm/IR/IntrinsicsAArch64.td b/llvm/include/llvm/IR/IntrinsicsAArch64.td --- a/llvm/include/llvm/IR/IntrinsicsAArch64.td +++ b/llvm/include/llvm/IR/IntrinsicsAArch64.td @@ -2098,13 +2098,16 @@ def int_aarch64_sve_pmullb_pair : AdvSIMD_2VectorArg_Intrinsic; def int_aarch64_sve_pmullt_pair : AdvSIMD_2VectorArg_Intrinsic; +// // SVE2 bitwise ternary operations. +// def int_aarch64_sve_eor3 : AdvSIMD_3VectorArg_Intrinsic; def int_aarch64_sve_bcax : AdvSIMD_3VectorArg_Intrinsic; def int_aarch64_sve_bsl : AdvSIMD_3VectorArg_Intrinsic; def int_aarch64_sve_bsl1n : AdvSIMD_3VectorArg_Intrinsic; def int_aarch64_sve_bsl2n : AdvSIMD_3VectorArg_Intrinsic; def int_aarch64_sve_nbsl : AdvSIMD_3VectorArg_Intrinsic; +def int_aarch64_sve_xar : AdvSIMD_2VectorArgIndexed_Intrinsic; // // SVE2 - Optional AES, SHA-3 and SM4 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 @@ -1908,7 +1908,7 @@ defm NBSL_ZZZZ : sve2_int_bitwise_ternary_op<0b111, "nbsl", int_aarch64_sve_nbsl>; // SVE2 bitwise xor and rotate right by immediate - defm XAR_ZZZI : sve2_int_rotate_right_imm<"xar">; + defm XAR_ZZZI : sve2_int_rotate_right_imm<"xar", int_aarch64_sve_xar>; // SVE2 extract vector (immediate offset, constructive) def EXT_ZZI_B : sve2_int_perm_extract_i_cons<"ext">; 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 @@ -3927,7 +3927,7 @@ let ElementSize = ElementSizeNone; } -multiclass sve2_int_rotate_right_imm { +multiclass sve2_int_rotate_right_imm { def _B : sve2_int_rotate_right_imm<{0,0,0,1}, asm, ZPR8, vecshiftR8>; def _H : sve2_int_rotate_right_imm<{0,0,1,?}, asm, ZPR16, vecshiftR16> { let Inst{19} = imm{3}; @@ -3939,6 +3939,10 @@ let Inst{22} = imm{5}; let Inst{20-19} = imm{4-3}; } + def : SVE_3_Op_Imm_Pat(NAME # _B)>; + def : SVE_3_Op_Imm_Pat(NAME # _H)>; + def : SVE_3_Op_Imm_Pat(NAME # _S)>; + def : SVE_3_Op_Imm_Pat(NAME # _D)>; } //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/AArch64/sve2-bitwise-ternary.ll b/llvm/test/CodeGen/AArch64/sve2-bitwise-ternary.ll --- a/llvm/test/CodeGen/AArch64/sve2-bitwise-ternary.ll +++ b/llvm/test/CodeGen/AArch64/sve2-bitwise-ternary.ll @@ -258,6 +258,50 @@ ret %res } +; +; XAR (vector, bitwise, unpredicated) +; + +define @xar_b( %a, %b) { +; CHECK-LABEL: xar_b: +; CHECK: xar z0.b, z0.b, z1.b, #1 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.xar.nxv16i8( %a, + %b, + i32 1) + ret %out +} + +define @xar_h( %a, %b) { +; CHECK-LABEL: xar_h: +; CHECK: xar z0.h, z0.h, z1.h, #2 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.xar.nxv8i16( %a, + %b, + i32 2) + ret %out +} + +define @xar_s( %a, %b) { +; CHECK-LABEL: xar_s: +; CHECK: xar z0.s, z0.s, z1.s, #3 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.xar.nxv4i32( %a, + %b, + i32 3) + ret %out +} + +define @xar_d( %a, %b) { +; CHECK-LABEL: xar_d: +; CHECK: xar z0.d, z0.d, z1.d, #4 +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.xar.nxv2i64( %a, + %b, + i32 4) + ret %out +} + declare @llvm.aarch64.sve.eor3.nxv16i8(,,) declare @llvm.aarch64.sve.eor3.nxv8i16(,,) declare @llvm.aarch64.sve.eor3.nxv4i32(,,) @@ -282,3 +326,7 @@ declare @llvm.aarch64.sve.nbsl.nxv8i16(,,) declare @llvm.aarch64.sve.nbsl.nxv4i32(,,) declare @llvm.aarch64.sve.nbsl.nxv2i64(,,) +declare @llvm.aarch64.sve.xar.nxv16i8(, , i32) +declare @llvm.aarch64.sve.xar.nxv8i16(, , i32) +declare @llvm.aarch64.sve.xar.nxv4i32(, , i32) +declare @llvm.aarch64.sve.xar.nxv2i64(, , i32)