CarolineConcatto created this revision.
Herald added subscribers: kristof.beyls, tschuett.
Herald added a project: All.
CarolineConcatto requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

As described in: https://github.com/ARM-software/acle/pull/257

Patch by : Sander de Smalen<sander.desma...@arm.com>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D151197

Files:
  clang/include/clang/Basic/arm_sve.td
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_psel.c
  clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp

Index: clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp
===================================================================
--- clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp
+++ clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_imm.cpp
@@ -27,6 +27,28 @@
   svpext_lane_c64_x2(c, 2); // expected-error {{argument value 2 is outside the valid range [0, 1]}}
 }
 
+void test_svpsel_lane_imm() {
+  svpsel_lane_b8(svptrue_b8(),   svptrue_b8(),  0, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 15]}}
+  svpsel_lane_b16(svptrue_b16(), svptrue_b16(), 0, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 7]}}
+  svpsel_lane_b32(svptrue_b32(), svptrue_b32(), 0, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 3]}}
+  svpsel_lane_b64(svptrue_b64(), svptrue_b64(), 0, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 1]}}
+
+  svpsel_lane_b8(svptrue_b8(),   svptrue_b8(),  0, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+  svpsel_lane_b16(svptrue_b16(), svptrue_b16(), 0, 8);  // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+  svpsel_lane_b32(svptrue_b32(), svptrue_b32(), 0, 4);  // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+  svpsel_lane_b64(svptrue_b64(), svptrue_b64(), 0, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+
+  svpsel_lane_c8(svptrue_c8(),   svptrue_b8(),  0, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 15]}}
+  svpsel_lane_c16(svptrue_c16(), svptrue_b16(), 0, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 7]}}
+  svpsel_lane_c32(svptrue_c32(), svptrue_b32(), 0, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 3]}}
+  svpsel_lane_c64(svptrue_c64(), svptrue_b64(), 0, -1); // expected-error {{argument value 18446744073709551615 is outside the valid range [0, 1]}}
+
+  svpsel_lane_c8(svptrue_c8(),   svptrue_b8(),  0, 16); // expected-error {{argument value 16 is outside the valid range [0, 15]}}
+  svpsel_lane_c16(svptrue_c16(), svptrue_b16(), 0, 8);  // expected-error {{argument value 8 is outside the valid range [0, 7]}}
+  svpsel_lane_c32(svptrue_c32(), svptrue_b32(), 0, 4);  // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+  svpsel_lane_c64(svptrue_c64(), svptrue_b64(), 0, 2);  // expected-error {{argument value 2 is outside the valid range [0, 1]}}
+}
+
 void test_cntp(svcount_t c) {
   svcntp_c8(c, 1);  // expected-error {{argument value 1 is outside the valid range [2, 4]}}
   svcntp_c11(c, 1); // expected-error {{argument value 1 is outside the valid range [2, 4]}}
Index: clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_psel.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/aarch64-sve2p1-intrinsics/acle_sve2p1_psel.c
@@ -0,0 +1,164 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu \
+// RUN:   -target-feature +sve2p1 -S -O1 -Werror -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-none-linux-gnu \
+// RUN:   -target-feature +sve2p1 -S -O1 -Werror -emit-llvm -o - -x c++ %s | FileCheck %s -check-prefix=CPP-CHECK
+
+#include <arm_sve.h>
+
+// CHECK-LABEL: @test_svpsel_lane_b8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[IDX:%.*]], 15
+// CHECK-NEXT:    [[TMP1:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv16i1(<vscale x 16 x i1> [[P1:%.*]], <vscale x 16 x i1> [[P2:%.*]], i32 [[TMP0]])
+// CHECK-NEXT:    ret <vscale x 16 x i1> [[TMP1]]
+//
+// CPP-CHECK-LABEL: @_Z19test_svpsel_lane_b8u10__SVBool_tu10__SVBool_tj(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[IDX:%.*]], 15
+// CPP-CHECK-NEXT:    [[TMP1:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv16i1(<vscale x 16 x i1> [[P1:%.*]], <vscale x 16 x i1> [[P2:%.*]], i32 [[TMP0]])
+// CPP-CHECK-NEXT:    ret <vscale x 16 x i1> [[TMP1]]
+//
+svbool_t test_svpsel_lane_b8(svbool_t p1, svbool_t p2, uint32_t idx) {
+  return svpsel_lane_b8(p1, p2, idx, 15);
+}
+
+// CHECK-LABEL: @test_svpsel_lane_b16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[P2:%.*]])
+// CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[IDX:%.*]], 7
+// CHECK-NEXT:    [[TMP2:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv8i1(<vscale x 16 x i1> [[P1:%.*]], <vscale x 8 x i1> [[TMP0]], i32 [[TMP1]])
+// CHECK-NEXT:    ret <vscale x 16 x i1> [[TMP2]]
+//
+// CPP-CHECK-LABEL: @_Z20test_svpsel_lane_b16u10__SVBool_tu10__SVBool_tj(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[P2:%.*]])
+// CPP-CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[IDX:%.*]], 7
+// CPP-CHECK-NEXT:    [[TMP2:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv8i1(<vscale x 16 x i1> [[P1:%.*]], <vscale x 8 x i1> [[TMP0]], i32 [[TMP1]])
+// CPP-CHECK-NEXT:    ret <vscale x 16 x i1> [[TMP2]]
+//
+svbool_t test_svpsel_lane_b16(svbool_t p1, svbool_t p2, uint32_t idx) {
+  return svpsel_lane_b16(p1, p2, idx, 7);
+}
+
+// CHECK-LABEL: @test_svpsel_lane_b32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[P2:%.*]])
+// CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[IDX:%.*]], 3
+// CHECK-NEXT:    [[TMP2:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv4i1(<vscale x 16 x i1> [[P1:%.*]], <vscale x 4 x i1> [[TMP0]], i32 [[TMP1]])
+// CHECK-NEXT:    ret <vscale x 16 x i1> [[TMP2]]
+//
+// CPP-CHECK-LABEL: @_Z20test_svpsel_lane_b32u10__SVBool_tu10__SVBool_tj(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[P2:%.*]])
+// CPP-CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[IDX:%.*]], 3
+// CPP-CHECK-NEXT:    [[TMP2:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv4i1(<vscale x 16 x i1> [[P1:%.*]], <vscale x 4 x i1> [[TMP0]], i32 [[TMP1]])
+// CPP-CHECK-NEXT:    ret <vscale x 16 x i1> [[TMP2]]
+//
+svbool_t test_svpsel_lane_b32(svbool_t p1, svbool_t p2, uint32_t idx) {
+  return svpsel_lane_b32(p1, p2, idx, 3);
+}
+
+// CHECK-LABEL: @test_svpsel_lane_b64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[P2:%.*]])
+// CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[IDX:%.*]], 1
+// CHECK-NEXT:    [[TMP2:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv2i1(<vscale x 16 x i1> [[P1:%.*]], <vscale x 2 x i1> [[TMP0]], i32 [[TMP1]])
+// CHECK-NEXT:    ret <vscale x 16 x i1> [[TMP2]]
+//
+// CPP-CHECK-LABEL: @_Z20test_svpsel_lane_b64u10__SVBool_tu10__SVBool_tj(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[P2:%.*]])
+// CPP-CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[IDX:%.*]], 1
+// CPP-CHECK-NEXT:    [[TMP2:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv2i1(<vscale x 16 x i1> [[P1:%.*]], <vscale x 2 x i1> [[TMP0]], i32 [[TMP1]])
+// CPP-CHECK-NEXT:    ret <vscale x 16 x i1> [[TMP2]]
+//
+svbool_t test_svpsel_lane_b64(svbool_t p1, svbool_t p2, uint32_t idx) {
+  return svpsel_lane_b64(p1, p2, idx, 1);
+}
+
+// CHECK-LABEL: @test_svpsel_lane_c8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[P1:%.*]])
+// CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[IDX:%.*]], 15
+// CHECK-NEXT:    [[TMP2:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv16i1(<vscale x 16 x i1> [[TMP0]], <vscale x 16 x i1> [[P2:%.*]], i32 [[TMP1]])
+// CHECK-NEXT:    [[TMP3:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[TMP2]])
+// CHECK-NEXT:    ret target("aarch64.svcount") [[TMP3]]
+//
+// CPP-CHECK-LABEL: @_Z19test_svpsel_lane_c8u11__SVCount_tu10__SVBool_tj(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[P1:%.*]])
+// CPP-CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[IDX:%.*]], 15
+// CPP-CHECK-NEXT:    [[TMP2:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv16i1(<vscale x 16 x i1> [[TMP0]], <vscale x 16 x i1> [[P2:%.*]], i32 [[TMP1]])
+// CPP-CHECK-NEXT:    [[TMP3:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[TMP2]])
+// CPP-CHECK-NEXT:    ret target("aarch64.svcount") [[TMP3]]
+//
+svcount_t test_svpsel_lane_c8(svcount_t p1, svbool_t p2, uint32_t idx) {
+  return svpsel_lane_c8(p1, p2, idx, 15);
+}
+
+// CHECK-LABEL: @test_svpsel_lane_c16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[P1:%.*]])
+// CHECK-NEXT:    [[TMP1:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[P2:%.*]])
+// CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[IDX:%.*]], 7
+// CHECK-NEXT:    [[TMP3:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv8i1(<vscale x 16 x i1> [[TMP0]], <vscale x 8 x i1> [[TMP1]], i32 [[TMP2]])
+// CHECK-NEXT:    [[TMP4:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[TMP3]])
+// CHECK-NEXT:    ret target("aarch64.svcount") [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z20test_svpsel_lane_c16u11__SVCount_tu10__SVBool_tj(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[P1:%.*]])
+// CPP-CHECK-NEXT:    [[TMP1:%.*]] = tail call <vscale x 8 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv8i1(<vscale x 16 x i1> [[P2:%.*]])
+// CPP-CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[IDX:%.*]], 7
+// CPP-CHECK-NEXT:    [[TMP3:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv8i1(<vscale x 16 x i1> [[TMP0]], <vscale x 8 x i1> [[TMP1]], i32 [[TMP2]])
+// CPP-CHECK-NEXT:    [[TMP4:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[TMP3]])
+// CPP-CHECK-NEXT:    ret target("aarch64.svcount") [[TMP4]]
+//
+svcount_t test_svpsel_lane_c16(svcount_t p1, svbool_t p2, uint32_t idx) {
+  return svpsel_lane_c16(p1, p2, idx, 7);
+}
+
+// CHECK-LABEL: @test_svpsel_lane_c32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[P1:%.*]])
+// CHECK-NEXT:    [[TMP1:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[P2:%.*]])
+// CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[IDX:%.*]], 3
+// CHECK-NEXT:    [[TMP3:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv4i1(<vscale x 16 x i1> [[TMP0]], <vscale x 4 x i1> [[TMP1]], i32 [[TMP2]])
+// CHECK-NEXT:    [[TMP4:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[TMP3]])
+// CHECK-NEXT:    ret target("aarch64.svcount") [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z20test_svpsel_lane_c32u11__SVCount_tu10__SVBool_tj(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[P1:%.*]])
+// CPP-CHECK-NEXT:    [[TMP1:%.*]] = tail call <vscale x 4 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv4i1(<vscale x 16 x i1> [[P2:%.*]])
+// CPP-CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[IDX:%.*]], 3
+// CPP-CHECK-NEXT:    [[TMP3:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv4i1(<vscale x 16 x i1> [[TMP0]], <vscale x 4 x i1> [[TMP1]], i32 [[TMP2]])
+// CPP-CHECK-NEXT:    [[TMP4:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[TMP3]])
+// CPP-CHECK-NEXT:    ret target("aarch64.svcount") [[TMP4]]
+//
+svcount_t test_svpsel_lane_c32(svcount_t p1, svbool_t p2, uint32_t idx) {
+  return svpsel_lane_c32(p1, p2, idx, 3);
+}
+
+// CHECK-LABEL: @test_svpsel_lane_c64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[P1:%.*]])
+// CHECK-NEXT:    [[TMP1:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[P2:%.*]])
+// CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[IDX:%.*]], 1
+// CHECK-NEXT:    [[TMP3:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv2i1(<vscale x 16 x i1> [[TMP0]], <vscale x 2 x i1> [[TMP1]], i32 [[TMP2]])
+// CHECK-NEXT:    [[TMP4:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[TMP3]])
+// CHECK-NEXT:    ret target("aarch64.svcount") [[TMP4]]
+//
+// CPP-CHECK-LABEL: @_Z20test_svpsel_lane_c64u11__SVCount_tu10__SVBool_tj(
+// CPP-CHECK-NEXT:  entry:
+// CPP-CHECK-NEXT:    [[TMP0:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.convert.to.svbool.taarch64.svcountt(target("aarch64.svcount") [[P1:%.*]])
+// CPP-CHECK-NEXT:    [[TMP1:%.*]] = tail call <vscale x 2 x i1> @llvm.aarch64.sve.convert.from.svbool.nxv2i1(<vscale x 16 x i1> [[P2:%.*]])
+// CPP-CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[IDX:%.*]], 1
+// CPP-CHECK-NEXT:    [[TMP3:%.*]] = tail call <vscale x 16 x i1> @llvm.aarch64.sve.psel.nxv2i1(<vscale x 16 x i1> [[TMP0]], <vscale x 2 x i1> [[TMP1]], i32 [[TMP2]])
+// CPP-CHECK-NEXT:    [[TMP4:%.*]] = tail call target("aarch64.svcount") @llvm.aarch64.sve.convert.from.svbool.taarch64.svcountt(<vscale x 16 x i1> [[TMP3]])
+// CPP-CHECK-NEXT:    ret target("aarch64.svcount") [[TMP4]]
+//
+svcount_t test_svpsel_lane_c64(svcount_t p1, svbool_t p2, uint32_t idx) {
+  return svpsel_lane_c64(p1, p2, idx, 1);
+}
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -2984,6 +2984,10 @@
       if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 3))
         HasError = true;
       break;
+    case SVETypeFlags::ImmCheck0_15:
+      if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 0, 15))
+        HasError = true;
+      break;
     case SVETypeFlags::ImmCheck2_4_Mul2:
       if (SemaBuiltinConstantArgRange(TheCall, ArgNum, 2, 4) ||
           SemaBuiltinConstantArgMultiple(TheCall, ArgNum, 2))
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -9430,6 +9430,13 @@
   return {DefaultType};
 }
 
+static llvm::Value *getSVESliceIndex(CGBuilderTy &Builder, llvm::Value *Base,
+                                     llvm::Value *Offset) {
+  llvm::APInt OffsetVal = cast<ConstantInt>(Offset)->getValue().trunc(32);
+  Offset = ConstantInt::get(Base->getType(), OffsetVal);
+  return Builder.CreateAdd(Base, Offset);
+}
+
 Value *CodeGenFunction::EmitSVETupleSetOrGet(const SVETypeFlags &TypeFlags,
                                              llvm::Type *Ty,
                                              ArrayRef<Value *> Ops) {
@@ -9615,7 +9622,34 @@
   switch (BuiltinID) {
   default:
     return nullptr;
-
+  case SVE::BI__builtin_sve_svpsel_lane_b8:
+  case SVE::BI__builtin_sve_svpsel_lane_b16:
+  case SVE::BI__builtin_sve_svpsel_lane_b32:
+  case SVE::BI__builtin_sve_svpsel_lane_b64:
+  case SVE::BI__builtin_sve_svpsel_lane_c8:
+  case SVE::BI__builtin_sve_svpsel_lane_c16:
+  case SVE::BI__builtin_sve_svpsel_lane_c32:
+  case SVE::BI__builtin_sve_svpsel_lane_c64: {
+    bool IsSVCount = isa<TargetExtType>(Ops[0]->getType());
+    assert(((!IsSVCount || cast<TargetExtType>(Ops[0]->getType())->getName() ==
+                               "aarch64.svcount")) &&
+           "Unexpected TargetExtType");
+    auto SVCountTy =
+        llvm::TargetExtType::get(getLLVMContext(), "aarch64.svcount");
+    Function *CastFromSVCountF =
+        CGM.getIntrinsic(Intrinsic::aarch64_sve_convert_to_svbool, SVCountTy);
+    Function *CastToSVCountF =
+        CGM.getIntrinsic(Intrinsic::aarch64_sve_convert_from_svbool, SVCountTy);
+
+    auto OverloadedTy = getSVEType(SVETypeFlags(Builtin->TypeModifier));
+    Function *F = CGM.getIntrinsic(Intrinsic::aarch64_sve_psel, OverloadedTy);
+    llvm::Value *Ops0 =
+        IsSVCount ? Builder.CreateCall(CastFromSVCountF, Ops[0]) : Ops[0];
+    llvm::Value *Ops1 = EmitSVEPredicateCast(Ops[1], OverloadedTy);
+    llvm::Value *Ops2 = getSVESliceIndex(Builder, Ops[2], Ops[3]);
+    llvm::Value *PSel = Builder.CreateCall(F, {Ops0, Ops1, Ops2});
+    return IsSVCount ? Builder.CreateCall(CastToSVCountF, PSel) : PSel;
+  }
   case SVE::BI__builtin_sve_svmov_b_z: {
     // svmov_b_z(pg, op) <=> svand_b_z(pg, op, op)
     SVETypeFlags TypeFlags(Builtin->TypeModifier);
Index: clang/include/clang/Basic/arm_sve.td
===================================================================
--- clang/include/clang/Basic/arm_sve.td
+++ clang/include/clang/Basic/arm_sve.td
@@ -233,6 +233,7 @@
 def ImmCheck0_1                 : ImmCheckType<13>; // 0..1
 def ImmCheck0_2                 : ImmCheckType<14>; // 0..2
 def ImmCheck0_3                 : ImmCheckType<15>; // 0..3
+def ImmCheck0_15                : ImmCheckType<16>; // 0..15
 def ImmCheck2_4_Mul2            : ImmCheckType<24>; // 2, 4
 
 class ImmCheck<int arg, ImmCheckType kind, int eltSizeArg = -1> {
@@ -2118,9 +2119,20 @@
 
 def SVPEXT_SINGLE : SInst<"svpext_lane_{d}", "P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext", [], [ImmCheck<1, ImmCheck0_3>]>;
 def SVPEXT_X2     : SInst<"svpext_lane_{d}_x2", "2.P}i", "QcQsQiQl", MergeNone, "aarch64_sve_pext_x2", [], [ImmCheck<1, ImmCheck0_1>]>;
+
+def SVPSEL_COUNT_ALIAS_B : SInst<"svpsel_lane_c8",  "}}Pmi", "Pc", MergeNone, "", [], [ImmCheck<3, ImmCheck0_15>]>;
+def SVPSEL_COUNT_ALIAS_H : SInst<"svpsel_lane_c16", "}}Pmi", "Ps", MergeNone, "", [], [ImmCheck<3, ImmCheck0_7>]>;
+def SVPSEL_COUNT_ALIAS_S : SInst<"svpsel_lane_c32", "}}Pmi", "Pi", MergeNone, "", [], [ImmCheck<3, ImmCheck0_3>]>;
+def SVPSEL_COUNT_ALIAS_D : SInst<"svpsel_lane_c64", "}}Pmi", "Pl", MergeNone, "", [], [ImmCheck<3, ImmCheck0_1>]>;
+
 }
 
 let TargetGuard = "sve2p1" in {
 def SVSCLAMP : SInst<"svclamp[_{d}]", "dddd", "csil",     MergeNone, "aarch64_sve_sclamp", [], []>;
 def SVUCLAMP : SInst<"svclamp[_{d}]", "dddd", "UcUsUiUl", MergeNone, "aarch64_sve_uclamp", [], []>;
+
+def SVPSEL_B : SInst<"svpsel_lane_b8",  "PPPmi", "Pc", MergeNone, "", [], [ImmCheck<3, ImmCheck0_15>]>;
+def SVPSEL_H : SInst<"svpsel_lane_b16", "PPPmi", "Ps", MergeNone, "", [], [ImmCheck<3, ImmCheck0_7>]>;
+def SVPSEL_S : SInst<"svpsel_lane_b32", "PPPmi", "Pi", MergeNone, "", [], [ImmCheck<3, ImmCheck0_3>]>;
+def SVPSEL_D : SInst<"svpsel_lane_b64", "PPPmi", "Pl", MergeNone, "", [], [ImmCheck<3, ImmCheck0_1>]>;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to