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 @@ -1498,6 +1498,7 @@ def int_aarch64_sve_compact : AdvSIMD_Pred1VectorArg_Intrinsic; def int_aarch64_sve_dupq_lane : AdvSIMD_SVE_DUPQ_Intrinsic; def int_aarch64_sve_ext : AdvSIMD_2VectorArgIndexed_Intrinsic; +def int_aarch64_sve_sel : AdvSIMD_Pred2VectorArg_Intrinsic; def int_aarch64_sve_lasta : AdvSIMD_SVE_Reduce_Intrinsic; def int_aarch64_sve_lastb : AdvSIMD_SVE_Reduce_Intrinsic; def int_aarch64_sve_rev : AdvSIMD_1VectorArg_Intrinsic; diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -11296,6 +11296,9 @@ return LowerSVEIntrinsicDUP(N, DAG); case Intrinsic::aarch64_sve_ext: return LowerSVEIntrinsicEXT(N, DAG); + case Intrinsic::aarch64_sve_sel: + return DAG.getNode(ISD::VSELECT, SDLoc(N), N->getValueType(0), + N->getOperand(1), N->getOperand(2), N->getOperand(3)); case Intrinsic::aarch64_sve_cmpeq_wide: return tryConvertSVEWideCompare(N, Intrinsic::aarch64_sve_cmpeq, false, DCI, DAG); diff --git a/llvm/test/CodeGen/AArch64/sve-intrinsics-sel.ll b/llvm/test/CodeGen/AArch64/sve-intrinsics-sel.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve-intrinsics-sel.ll @@ -0,0 +1,94 @@ +; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s + +; +; SEL (Vectors) +; + +define @sel_i1( %pg, %a, %b) { +; CHECK-LABEL: sel_i1: +; CHECK: sel p0.b, p0, p1.b, p2.b +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.sel.nxv16i1( %pg, + %a, + %b) + ret %out +} + +define @sel_i8( %pg, %a, %b) { +; CHECK-LABEL: sel_i8: +; CHECK: sel z0.b, p0, z0.b, z1.b +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.sel.nxv16i8( %pg, + %a, + %b) + ret %out +} + +define @sel_i16( %pg, %a, %b) { +; CHECK-LABEL: sel_i16: +; CHECK: sel z0.h, p0, z0.h, z1.h +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.sel.nxv8i16( %pg, + %a, + %b) + ret %out +} + +define @sel_i32( %pg, %a, %b) { +; CHECK-LABEL: sel_i32: +; CHECK: sel z0.s, p0, z0.s, z1.s +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.sel.nxv4i32( %pg, + %a, + %b) + ret %out +} + +define @sel_i64( %pg, %a, %b) { +; CHECK-LABEL: sel_i64: +; CHECK: sel z0.d, p0, z0.d, z1.d +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.sel.nxv2i64( %pg, + %a, + %b) + ret %out +} + +define @sel_f16( %pg, %a, %b) { +; CHECK-LABEL: sel_f16: +; CHECK: sel z0.h, p0, z0.h, z1.h +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.sel.nxv8f16( %pg, + %a, + %b) + ret %out +} + +define @sel_f32( %pg, %a, %b) { +; CHECK-LABEL: sel_f32: +; CHECK: sel z0.s, p0, z0.s, z1.s +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.sel.nxv4f32( %pg, + %a, + %b) + ret %out +} + +define @sel_f64( %pg, %a, %b) { +; CHECK-LABEL: sel_f64: +; CHECK: sel z0.d, p0, z0.d, z1.d +; CHECK-NEXT: ret + %out = call @llvm.aarch64.sve.sel.nxv2f64( %pg, + %a, + %b) + ret %out +} + +declare @llvm.aarch64.sve.sel.nxv16i1(, , ) +declare @llvm.aarch64.sve.sel.nxv16i8(, , ) +declare @llvm.aarch64.sve.sel.nxv8i16(, , ) +declare @llvm.aarch64.sve.sel.nxv4i32(, , ) +declare @llvm.aarch64.sve.sel.nxv2i64(, , ) +declare @llvm.aarch64.sve.sel.nxv8f16(, , ) +declare @llvm.aarch64.sve.sel.nxv4f32(, , ) +declare @llvm.aarch64.sve.sel.nxv2f64(, , )