[clang] 91a4a59 - [SveEmitter] Add SVE tuple types and builtins for svundef.

Sander de Smalen via cfe-commits cfe-commits at lists.llvm.org
Sun Jun 14 23:38:12 PDT 2020


Author: Sander de Smalen
Date: 2020-06-15T07:36:01+01:00
New Revision: 91a4a592edb01ca1968b5e5abe3da21709bb72d6

URL: https://github.com/llvm/llvm-project/commit/91a4a592edb01ca1968b5e5abe3da21709bb72d6
DIFF: https://github.com/llvm/llvm-project/commit/91a4a592edb01ca1968b5e5abe3da21709bb72d6.diff

LOG: [SveEmitter] Add SVE tuple types and builtins for svundef.

This patch adds new SVE types to Clang that describe tuples of SVE
vectors. For example `svint32x2_t` which maps to the twice-as-wide
vector `<vscale x 8 x i32>`. Similarly, `svint32x3_t` will map to
`<vscale x 12 x i32>`.

It also adds builtins to return an `undef` vector for a given
SVE type.

Reviewers: c-rhodes, david-arm, ctetreau, efriedma, rengolin

Reviewed By: c-rhodes

Tags: #clang

Differential Revision: https://reviews.llvm.org/D81459

Added: 
    clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef.c
    clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c
    clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c
    clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c

Modified: 
    clang/include/clang/Basic/AArch64SVEACLETypes.def
    clang/include/clang/Basic/TargetBuiltins.h
    clang/include/clang/Basic/arm_sve.td
    clang/lib/CodeGen/CGBuiltin.cpp
    clang/lib/CodeGen/CodeGenTypes.cpp
    clang/utils/TableGen/SveEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/AArch64SVEACLETypes.def b/clang/include/clang/Basic/AArch64SVEACLETypes.def
index afa651841861..2daf4c76a1ad 100644
--- a/clang/include/clang/Basic/AArch64SVEACLETypes.def
+++ b/clang/include/clang/Basic/AArch64SVEACLETypes.def
@@ -63,6 +63,57 @@ SVE_VECTOR_TYPE("__SVFloat16_t", SveFloat16, SveFloat16Ty, 8, 16, true, true)
 SVE_VECTOR_TYPE("__SVFloat32_t", SveFloat32, SveFloat32Ty, 4, 32, true, true)
 SVE_VECTOR_TYPE("__SVFloat64_t", SveFloat64, SveFloat64Ty, 2, 64, true, true)
 
+//
+// x2
+//
+SVE_VECTOR_TYPE("__SVInt8x2_t",  SveInt8x2, SveInt8x2Ty, 32, 8, true, false)
+SVE_VECTOR_TYPE("__SVInt16x2_t", SveInt16x2, SveInt16x2Ty, 16, 16, true, false)
+SVE_VECTOR_TYPE("__SVInt32x2_t", SveInt32x2, SveInt32x2Ty, 8, 32, true, false)
+SVE_VECTOR_TYPE("__SVInt64x2_t", SveInt64x2, SveInt64x2Ty, 4, 64, true, false)
+
+SVE_VECTOR_TYPE("__SVUint8x2_t",  SveUint8x2, SveUint8x2Ty, 32, 8, false, false)
+SVE_VECTOR_TYPE("__SVUint16x2_t", SveUint16x2, SveUint16x2Ty, 16, 16, false, false)
+SVE_VECTOR_TYPE("__SVUint32x2_t", SveUint32x2, SveUint32x2Ty, 8, 32, false, false)
+SVE_VECTOR_TYPE("__SVUint64x2_t", SveUint64x2, SveUint64x2Ty, 4, 64, false, false)
+
+SVE_VECTOR_TYPE("__SVFloat16x2_t", SveFloat16x2, SveFloat16x2Ty, 16, 16, true, true)
+SVE_VECTOR_TYPE("__SVFloat32x2_t", SveFloat32x2, SveFloat32x2Ty, 8, 32, true, true)
+SVE_VECTOR_TYPE("__SVFloat64x2_t", SveFloat64x2, SveFloat64x2Ty, 4, 64, true, true)
+
+//
+// x3
+//
+SVE_VECTOR_TYPE("__SVInt8x3_t",  SveInt8x3, SveInt8x3Ty, 48, 8, true, false)
+SVE_VECTOR_TYPE("__SVInt16x3_t", SveInt16x3, SveInt16x3Ty, 24, 16, true, false)
+SVE_VECTOR_TYPE("__SVInt32x3_t", SveInt32x3, SveInt32x3Ty, 12, 32, true, false)
+SVE_VECTOR_TYPE("__SVInt64x3_t", SveInt64x3, SveInt64x3Ty, 6, 64, true, false)
+
+SVE_VECTOR_TYPE("__SVUint8x3_t",  SveUint8x3, SveUint8x3Ty, 48, 8, false, false)
+SVE_VECTOR_TYPE("__SVUint16x3_t", SveUint16x3, SveUint16x3Ty, 24, 16, false, false)
+SVE_VECTOR_TYPE("__SVUint32x3_t", SveUint32x3, SveUint32x3Ty, 12, 32, false, false)
+SVE_VECTOR_TYPE("__SVUint64x3_t", SveUint64x3, SveUint64x3Ty, 6, 64, false, false)
+
+SVE_VECTOR_TYPE("__SVFloat16x3_t", SveFloat16x3, SveFloat16x3Ty, 24, 16, true, true)
+SVE_VECTOR_TYPE("__SVFloat32x3_t", SveFloat32x3, SveFloat32x3Ty, 12, 32, true, true)
+SVE_VECTOR_TYPE("__SVFloat64x3_t", SveFloat64x3, SveFloat64x3Ty, 6, 64, true, true)
+
+//
+// x4
+//
+SVE_VECTOR_TYPE("__SVInt8x4_t",  SveInt8x4, SveInt8x4Ty, 64, 8, true, false)
+SVE_VECTOR_TYPE("__SVInt16x4_t", SveInt16x4, SveInt16x4Ty, 32, 16, true, false)
+SVE_VECTOR_TYPE("__SVInt32x4_t", SveInt32x4, SveInt32x4Ty, 16, 32, true, false)
+SVE_VECTOR_TYPE("__SVInt64x4_t", SveInt64x4, SveInt64x4Ty, 8, 64, true, false)
+
+SVE_VECTOR_TYPE("__SVUint8x4_t",  SveUint8x4, SveUint8x4Ty, 64, 8, false, false)
+SVE_VECTOR_TYPE("__SVUint16x4_t", SveUint16x4, SveUint16x4Ty, 32, 16, false, false)
+SVE_VECTOR_TYPE("__SVUint32x4_t", SveUint32x4, SveUint32x4Ty, 16, 32, false, false)
+SVE_VECTOR_TYPE("__SVUint64x4_t", SveUint64x4, SveUint64x4Ty, 8, 64, false, false)
+
+SVE_VECTOR_TYPE("__SVFloat16x4_t", SveFloat16x4, SveFloat16x4Ty, 32, 16, true, true)
+SVE_VECTOR_TYPE("__SVFloat32x4_t", SveFloat32x4, SveFloat32x4Ty, 16, 32, true, true)
+SVE_VECTOR_TYPE("__SVFloat64x4_t", SveFloat64x4, SveFloat64x4Ty, 8, 64, true, true)
+
 SVE_PREDICATE_TYPE("__SVBool_t", SveBool, SveBoolTy, 16)
 
 #undef SVE_VECTOR_TYPE

diff  --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h
index 5fa5f9f0bcef..899f6b5b6f3c 100644
--- a/clang/include/clang/Basic/TargetBuiltins.h
+++ b/clang/include/clang/Basic/TargetBuiltins.h
@@ -246,6 +246,7 @@ namespace clang {
     bool isInsertOp1SVALL() const { return Flags & IsInsertOp1SVALL; }
     bool isGatherPrefetch() const { return Flags & IsGatherPrefetch; }
     bool isReverseUSDOT() const { return Flags & ReverseUSDOT; }
+    bool isUndef() const { return Flags & IsUndef; }
 
     uint64_t getBits() const { return Flags; }
     bool isFlagSet(uint64_t Flag) const { return Flags & Flag; }

diff  --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td
index 756607dda1c6..b79a245ebd04 100644
--- a/clang/include/clang/Basic/arm_sve.td
+++ b/clang/include/clang/Basic/arm_sve.td
@@ -58,6 +58,7 @@
 // -------------------
 // prototype: return (arg, arg, ...)
 //
+// 2,3,4: array of default vectors
 // v: void
 // x: vector of signed integers
 // u: vector of unsigned integers
@@ -198,6 +199,7 @@ def IsPrefetch                : FlagType<0x08000000>; // Contiguous prefetches.
 def IsGatherPrefetch          : FlagType<0x10000000>;
 def ReverseCompare            : FlagType<0x20000000>; // Compare operands must be swapped.
 def ReverseUSDOT              : FlagType<0x40000000>; // Unsigned/signed operands must be swapped.
+def IsUndef                   : FlagType<0x80000000>; // Codegen `undef` of given type.
 
 // These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h
 class ImmCheckType<int val> {
@@ -1264,6 +1266,12 @@ let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64)" in {
 def SVMLLA_F64 : SInst<"svmmla[_f64]", "dddd","d", MergeNone, "aarch64_sve_fmmla">;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Vector creation
+def SVUNDEF_1 : SInst<"svundef_{d}",  "d", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>;
+def SVUNDEF_2 : SInst<"svundef2_{d}", "2", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>;
+def SVUNDEF_3 : SInst<"svundef3_{d}", "3", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>;
+def SVUNDEF_4 : SInst<"svundef4_{d}", "4", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>;
 
 ////////////////////////////////////////////////////////////////////////////////
 // SVE2 WhileGE/GT

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index a2e6050ae1f3..85bff3d9a674 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -8036,6 +8036,8 @@ Value *CodeGenFunction::EmitAArch64SVEBuiltinExpr(unsigned BuiltinID,
     return EmitSVEPrefetchLoad(TypeFlags, Ops, Builtin->LLVMIntrinsic);
   else if (TypeFlags.isGatherPrefetch())
     return EmitSVEGatherPrefetch(TypeFlags, Ops, Builtin->LLVMIntrinsic);
+  else if (TypeFlags.isUndef())
+    return UndefValue::get(Ty);
   else if (Builtin->LLVMIntrinsic != 0) {
     if (TypeFlags.getMergeType() == SVETypeFlags::MergeZeroExp)
       InsertExplicitZeroOperand(Builder, Ty, Ops);

diff  --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index bae934bca8ef..b57ce4e8d4b5 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -533,44 +533,91 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
     case BuiltinType::OCLReserveID:
       ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty);
       break;
+#define GET_SVE_INT_VEC(BITS, ELTS)                                            \
+  llvm::ScalableVectorType::get(                                               \
+      llvm::IntegerType::get(getLLVMContext(), BITS), ELTS);
     case BuiltinType::SveInt8:
     case BuiltinType::SveUint8:
-      return llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 8),
-                                   {16, true});
+      return GET_SVE_INT_VEC(8, 16);
+    case BuiltinType::SveInt8x2:
+    case BuiltinType::SveUint8x2:
+      return GET_SVE_INT_VEC(8, 32);
+    case BuiltinType::SveInt8x3:
+    case BuiltinType::SveUint8x3:
+      return GET_SVE_INT_VEC(8, 48);
+    case BuiltinType::SveInt8x4:
+    case BuiltinType::SveUint8x4:
+      return GET_SVE_INT_VEC(8, 64);
     case BuiltinType::SveInt16:
     case BuiltinType::SveUint16:
-      return llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 16),
-                                   {8, true});
+      return GET_SVE_INT_VEC(16, 8);
+    case BuiltinType::SveInt16x2:
+    case BuiltinType::SveUint16x2:
+      return GET_SVE_INT_VEC(16, 16);
+    case BuiltinType::SveInt16x3:
+    case BuiltinType::SveUint16x3:
+      return GET_SVE_INT_VEC(16, 24);
+    case BuiltinType::SveInt16x4:
+    case BuiltinType::SveUint16x4:
+      return GET_SVE_INT_VEC(16, 32);
     case BuiltinType::SveInt32:
     case BuiltinType::SveUint32:
-      return llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 32),
-                                   {4, true});
+      return GET_SVE_INT_VEC(32, 4);
+    case BuiltinType::SveInt32x2:
+    case BuiltinType::SveUint32x2:
+      return GET_SVE_INT_VEC(32, 8);
+    case BuiltinType::SveInt32x3:
+    case BuiltinType::SveUint32x3:
+      return GET_SVE_INT_VEC(32, 12);
+    case BuiltinType::SveInt32x4:
+    case BuiltinType::SveUint32x4:
+      return GET_SVE_INT_VEC(32, 16);
     case BuiltinType::SveInt64:
     case BuiltinType::SveUint64:
-      return llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 64),
-                                   {2, true});
+      return GET_SVE_INT_VEC(64, 2);
+    case BuiltinType::SveInt64x2:
+    case BuiltinType::SveUint64x2:
+      return GET_SVE_INT_VEC(64, 4);
+    case BuiltinType::SveInt64x3:
+    case BuiltinType::SveUint64x3:
+      return GET_SVE_INT_VEC(64, 6);
+    case BuiltinType::SveInt64x4:
+    case BuiltinType::SveUint64x4:
+      return GET_SVE_INT_VEC(64, 8);
+    case BuiltinType::SveBool:
+      return GET_SVE_INT_VEC(1, 16);
+#undef GET_SVE_INT_VEC
+#define GET_SVE_FP_VEC(TY, ISFP16, ELTS)                                       \
+  llvm::ScalableVectorType::get(                                               \
+      getTypeForFormat(getLLVMContext(),                                       \
+                       Context.getFloatTypeSemantics(Context.TY),              \
+                       /* UseNativeHalf = */ ISFP16),                          \
+      ELTS);
     case BuiltinType::SveFloat16:
-      return llvm::VectorType::get(
-          getTypeForFormat(getLLVMContext(),
-                           Context.getFloatTypeSemantics(Context.HalfTy),
-                           /* UseNativeHalf = */ true),
-          {8, true});
+      return GET_SVE_FP_VEC(HalfTy, true, 8);
+    case BuiltinType::SveFloat16x2:
+      return GET_SVE_FP_VEC(HalfTy, true, 16);
+    case BuiltinType::SveFloat16x3:
+      return GET_SVE_FP_VEC(HalfTy, true, 24);
+    case BuiltinType::SveFloat16x4:
+      return GET_SVE_FP_VEC(HalfTy, true, 32);
     case BuiltinType::SveFloat32:
-      return llvm::VectorType::get(
-          getTypeForFormat(getLLVMContext(),
-                           Context.getFloatTypeSemantics(Context.FloatTy),
-                           /* UseNativeHalf = */ false),
-          {4, true});
+      return GET_SVE_FP_VEC(FloatTy, false, 4);
+    case BuiltinType::SveFloat32x2:
+      return GET_SVE_FP_VEC(FloatTy, false, 8);
+    case BuiltinType::SveFloat32x3:
+      return GET_SVE_FP_VEC(FloatTy, false, 12);
+    case BuiltinType::SveFloat32x4:
+      return GET_SVE_FP_VEC(FloatTy, false, 16);
     case BuiltinType::SveFloat64:
-      return llvm::VectorType::get(
-          getTypeForFormat(getLLVMContext(),
-                           Context.getFloatTypeSemantics(Context.DoubleTy),
-                           /* UseNativeHalf = */ false),
-          {2, true});
-    case BuiltinType::SveBool:
-      return llvm::VectorType::get(llvm::IntegerType::get(getLLVMContext(), 1),
-                                   {16, true});
-      break;
+      return GET_SVE_FP_VEC(DoubleTy, false, 2);
+    case BuiltinType::SveFloat64x2:
+      return GET_SVE_FP_VEC(DoubleTy, false, 4);
+    case BuiltinType::SveFloat64x3:
+      return GET_SVE_FP_VEC(DoubleTy, false, 6);
+    case BuiltinType::SveFloat64x4:
+      return GET_SVE_FP_VEC(DoubleTy, false, 8);
+#undef GET_SVE_FP_VEC
     case BuiltinType::Dependent:
 #define BUILTIN_TYPE(Id, SingletonId)
 #define PLACEHOLDER_TYPE(Id, SingletonId) \

diff  --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef.c
new file mode 100644
index 000000000000..731f740846d0
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef.c
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O1 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
+
+#include <arm_sve.h>
+
+svint8_t test_svundef_s8()
+{
+  // CHECK-LABEL: test_svundef_s8
+  // CHECK: ret <vscale x 16 x i8> undef
+  return svundef_s8();
+}
+
+svint16_t test_svundef_s16()
+{
+  // CHECK-LABEL: test_svundef_s16
+  // CHECK: ret <vscale x 8 x i16> undef
+  return svundef_s16();
+}
+
+svint32_t test_svundef_s32()
+{
+  // CHECK-LABEL: test_svundef_s32
+  // CHECK: ret <vscale x 4 x i32> undef
+  return svundef_s32();
+}
+
+svint64_t test_svundef_s64()
+{
+  // CHECK-LABEL: test_svundef_s64
+  // CHECK: ret <vscale x 2 x i64> undef
+  return svundef_s64();
+}
+
+svuint8_t test_svundef_u8()
+{
+  // CHECK-LABEL: test_svundef_u8
+  // CHECK: ret <vscale x 16 x i8> undef
+  return svundef_u8();
+}
+
+svuint16_t test_svundef_u16()
+{
+  // CHECK-LABEL: test_svundef_u16
+  // CHECK: ret <vscale x 8 x i16> undef
+  return svundef_u16();
+}
+
+svuint32_t test_svundef_u32()
+{
+  // CHECK-LABEL: test_svundef_u32
+  // CHECK: ret <vscale x 4 x i32> undef
+  return svundef_u32();
+}
+
+svuint64_t test_svundef_u64()
+{
+  // CHECK-LABEL: test_svundef_u64
+  // CHECK: ret <vscale x 2 x i64> undef
+  return svundef_u64();
+}
+
+svfloat16_t test_svundef_f16()
+{
+  // CHECK-LABEL: test_svundef_f16
+  // CHECK: ret <vscale x 8 x half> undef
+  return svundef_f16();
+}
+
+svfloat32_t test_svundef_f32()
+{
+  // CHECK-LABEL: test_svundef_f32
+  // CHECK: ret <vscale x 4 x float> undef
+  return svundef_f32();
+}
+
+svfloat64_t test_svundef_f64()
+{
+  // CHECK-LABEL: test_svundef_f64
+  // CHECK: ret <vscale x 2 x double> undef
+  return svundef_f64();
+}

diff  --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c
new file mode 100644
index 000000000000..ab5fb1cc691c
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef2.c
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
+
+#include <arm_sve.h>
+
+svint8x2_t test_svundef2_s8()
+{
+  // CHECK-LABEL: test_svundef2_s8
+  // CHECK: ret <vscale x 32 x i8> undef
+  return svundef2_s8();
+}
+
+svint16x2_t test_svundef2_s16()
+{
+  // CHECK-LABEL: test_svundef2_s16
+  // CHECK: ret <vscale x 16 x i16> undef
+  return svundef2_s16();
+}
+
+svint32x2_t test_svundef2_s32()
+{
+  // CHECK-LABEL: test_svundef2_s32
+  // CHECK: ret <vscale x 8 x i32> undef
+  return svundef2_s32();
+}
+
+svint64x2_t test_svundef2_s64()
+{
+  // CHECK-LABEL: test_svundef2_s64
+  // CHECK: ret <vscale x 4 x i64> undef
+  return svundef2_s64();
+}
+
+svuint8x2_t test_svundef2_u8()
+{
+  // CHECK-LABEL: test_svundef2_u8
+  // CHECK: ret <vscale x 32 x i8> undef
+  return svundef2_u8();
+}
+
+svuint16x2_t test_svundef2_u16()
+{
+  // CHECK-LABEL: test_svundef2_u16
+  // CHECK: ret <vscale x 16 x i16> undef
+  return svundef2_u16();
+}
+
+svuint32x2_t test_svundef2_u32()
+{
+  // CHECK-LABEL: test_svundef2_u32
+  // CHECK: ret <vscale x 8 x i32> undef
+  return svundef2_u32();
+}
+
+svuint64x2_t test_svundef2_u64()
+{
+  // CHECK-LABEL: test_svundef2_u64
+  // CHECK: ret <vscale x 4 x i64> undef
+  return svundef2_u64();
+}
+
+svfloat16x2_t test_svundef2_f16()
+{
+  // CHECK-LABEL: test_svundef2_f16
+  // CHECK: ret <vscale x 16 x half> undef
+  return svundef2_f16();
+}
+
+svfloat32x2_t test_svundef2_f32()
+{
+  // CHECK-LABEL: test_svundef2_f32
+  // CHECK: ret <vscale x 8 x float> undef
+  return svundef2_f32();
+}
+
+svfloat64x2_t test_svundef2_f64()
+{
+  // CHECK-LABEL: test_svundef2_f64
+  // CHECK: ret <vscale x 4 x double> undef
+  return svundef2_f64();
+}

diff  --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c
new file mode 100644
index 000000000000..925e5aa43779
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef3.c
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
+
+#include <arm_sve.h>
+
+svint8x3_t test_svundef3_s8()
+{
+  // CHECK-LABEL: test_svundef3_s8
+  // CHECK: ret <vscale x 48 x i8> undef
+  return svundef3_s8();
+}
+
+svint16x3_t test_svundef3_s16()
+{
+  // CHECK-LABEL: test_svundef3_s16
+  // CHECK: ret <vscale x 24 x i16> undef
+  return svundef3_s16();
+}
+
+svint32x3_t test_svundef3_s32()
+{
+  // CHECK-LABEL: test_svundef3_s32
+  // CHECK: ret <vscale x 12 x i32> undef
+  return svundef3_s32();
+}
+
+svint64x3_t test_svundef3_s64()
+{
+  // CHECK-LABEL: test_svundef3_s64
+  // CHECK: ret <vscale x 6 x i64> undef
+  return svundef3_s64();
+}
+
+svuint8x3_t test_svundef3_u8()
+{
+  // CHECK-LABEL: test_svundef3_u8
+  // CHECK: ret <vscale x 48 x i8> undef
+  return svundef3_u8();
+}
+
+svuint16x3_t test_svundef3_u16()
+{
+  // CHECK-LABEL: test_svundef3_u16
+  // CHECK: ret <vscale x 24 x i16> undef
+  return svundef3_u16();
+}
+
+svuint32x3_t test_svundef3_u32()
+{
+  // CHECK-LABEL: test_svundef3_u32
+  // CHECK: ret <vscale x 12 x i32> undef
+  return svundef3_u32();
+}
+
+svuint64x3_t test_svundef3_u64()
+{
+  // CHECK-LABEL: test_svundef3_u64
+  // CHECK: ret <vscale x 6 x i64> undef
+  return svundef3_u64();
+}
+
+svfloat16x3_t test_svundef3_f16()
+{
+  // CHECK-LABEL: test_svundef3_f16
+  // CHECK: ret <vscale x 24 x half> undef
+  return svundef3_f16();
+}
+
+svfloat32x3_t test_svundef3_f32()
+{
+  // CHECK-LABEL: test_svundef3_f32
+  // CHECK: ret <vscale x 12 x float> undef
+  return svundef3_f32();
+}
+
+svfloat64x3_t test_svundef3_f64()
+{
+  // CHECK-LABEL: test_svundef3_f64
+  // CHECK: ret <vscale x 6 x double> undef
+  return svundef3_f64();
+}

diff  --git a/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c
new file mode 100644
index 000000000000..7dc854f33159
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-sve-intrinsics/acle_sve_undef4.c
@@ -0,0 +1,80 @@
+// RUN: %clang_cc1 -D__ARM_FEATURE_SVE -triple aarch64-none-linux-gnu -target-feature +sve -fallow-half-arguments-and-returns -S -O2 -Werror -Wall -emit-llvm -o - %s | FileCheck %s
+
+#include <arm_sve.h>
+
+svint8x4_t test_svundef4_s8()
+{
+  // CHECK-LABEL: test_svundef4_s8
+  // CHECK: ret <vscale x 64 x i8> undef
+  return svundef4_s8();
+}
+
+svint16x4_t test_svundef4_s16()
+{
+  // CHECK-LABEL: test_svundef4_s16
+  // CHECK: ret <vscale x 32 x i16> undef
+  return svundef4_s16();
+}
+
+svint32x4_t test_svundef4_s32()
+{
+  // CHECK-LABEL: test_svundef4_s32
+  // CHECK: ret <vscale x 16 x i32> undef
+  return svundef4_s32();
+}
+
+svint64x4_t test_svundef4_s64()
+{
+  // CHECK-LABEL: test_svundef4_s64
+  // CHECK: ret <vscale x 8 x i64> undef
+  return svundef4_s64();
+}
+
+svuint8x4_t test_svundef4_u8()
+{
+  // CHECK-LABEL: test_svundef4_u8
+  // CHECK: ret <vscale x 64 x i8> undef
+  return svundef4_u8();
+}
+
+svuint16x4_t test_svundef4_u16()
+{
+  // CHECK-LABEL: test_svundef4_u16
+  // CHECK: ret <vscale x 32 x i16> undef
+  return svundef4_u16();
+}
+
+svuint32x4_t test_svundef4_u32()
+{
+  // CHECK-LABEL: test_svundef4_u32
+  // CHECK: ret <vscale x 16 x i32> undef
+  return svundef4_u32();
+}
+
+svuint64x4_t test_svundef4_u64()
+{
+  // CHECK-LABEL: test_svundef4_u64
+  // CHECK: ret <vscale x 8 x i64> undef
+  return svundef4_u64();
+}
+
+svfloat16x4_t test_svundef4_f16()
+{
+  // CHECK-LABEL: test_svundef4_f16
+  // CHECK: ret <vscale x 32 x half> undef
+  return svundef4_f16();
+}
+
+svfloat32x4_t test_svundef4_f32()
+{
+  // CHECK-LABEL: test_svundef4_f32
+  // CHECK: ret <vscale x 16 x float> undef
+  return svundef4_f32();
+}
+
+svfloat64x4_t test_svundef4_f64()
+{
+  // CHECK-LABEL: test_svundef4_f64
+  // CHECK: ret <vscale x 8 x double> undef
+  return svundef4_f64();
+}

diff  --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp
index be0e91d8b1d5..c0d203c72f54 100644
--- a/clang/utils/TableGen/SveEmitter.cpp
+++ b/clang/utils/TableGen/SveEmitter.cpp
@@ -490,6 +490,15 @@ void SVEType::applyTypespec() {
 
 void SVEType::applyModifier(char Mod) {
   switch (Mod) {
+  case '2':
+    NumVectors = 2;
+    break;
+  case '3':
+    NumVectors = 3;
+    break;
+  case '4':
+    NumVectors = 4;
+    break;
   case 'v':
     Void = true;
     break;
@@ -801,18 +810,7 @@ Intrinsic::Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy,
 }
 
 std::string Intrinsic::getBuiltinTypeStr() {
-  std::string S;
-
-  SVEType RetT = getReturnType();
-  // Since the return value must be one type, return a vector type of the
-  // appropriate width which we will bitcast.  An exception is made for
-  // returning structs of 2, 3, or 4 vectors which are returned in a sret-like
-  // fashion, storing them to a pointer arg.
-  if (RetT.getNumVectors() > 1) {
-    S += "vv*"; // void result with void* first argument
-  } else
-    S += RetT.builtin_str();
-
+  std::string S = getReturnType().builtin_str();
   for (unsigned I = 0; I < getNumParams(); ++I)
     S += getParamType(I).builtin_str();
 
@@ -1071,6 +1069,39 @@ void SVEEmitter::createHeader(raw_ostream &OS) {
   OS << "typedef __SVFloat16_t svfloat16_t;\n";
   OS << "typedef __SVFloat32_t svfloat32_t;\n";
   OS << "typedef __SVFloat64_t svfloat64_t;\n";
+  OS << "typedef __SVInt8x2_t svint8x2_t;\n";
+  OS << "typedef __SVInt16x2_t svint16x2_t;\n";
+  OS << "typedef __SVInt32x2_t svint32x2_t;\n";
+  OS << "typedef __SVInt64x2_t svint64x2_t;\n";
+  OS << "typedef __SVUint8x2_t svuint8x2_t;\n";
+  OS << "typedef __SVUint16x2_t svuint16x2_t;\n";
+  OS << "typedef __SVUint32x2_t svuint32x2_t;\n";
+  OS << "typedef __SVUint64x2_t svuint64x2_t;\n";
+  OS << "typedef __SVFloat16x2_t svfloat16x2_t;\n";
+  OS << "typedef __SVFloat32x2_t svfloat32x2_t;\n";
+  OS << "typedef __SVFloat64x2_t svfloat64x2_t;\n";
+  OS << "typedef __SVInt8x3_t svint8x3_t;\n";
+  OS << "typedef __SVInt16x3_t svint16x3_t;\n";
+  OS << "typedef __SVInt32x3_t svint32x3_t;\n";
+  OS << "typedef __SVInt64x3_t svint64x3_t;\n";
+  OS << "typedef __SVUint8x3_t svuint8x3_t;\n";
+  OS << "typedef __SVUint16x3_t svuint16x3_t;\n";
+  OS << "typedef __SVUint32x3_t svuint32x3_t;\n";
+  OS << "typedef __SVUint64x3_t svuint64x3_t;\n";
+  OS << "typedef __SVFloat16x3_t svfloat16x3_t;\n";
+  OS << "typedef __SVFloat32x3_t svfloat32x3_t;\n";
+  OS << "typedef __SVFloat64x3_t svfloat64x3_t;\n";
+  OS << "typedef __SVInt8x4_t svint8x4_t;\n";
+  OS << "typedef __SVInt16x4_t svint16x4_t;\n";
+  OS << "typedef __SVInt32x4_t svint32x4_t;\n";
+  OS << "typedef __SVInt64x4_t svint64x4_t;\n";
+  OS << "typedef __SVUint8x4_t svuint8x4_t;\n";
+  OS << "typedef __SVUint16x4_t svuint16x4_t;\n";
+  OS << "typedef __SVUint32x4_t svuint32x4_t;\n";
+  OS << "typedef __SVUint64x4_t svuint64x4_t;\n";
+  OS << "typedef __SVFloat16x4_t svfloat16x4_t;\n";
+  OS << "typedef __SVFloat32x4_t svfloat32x4_t;\n";
+  OS << "typedef __SVFloat64x4_t svfloat64x4_t;\n";
   OS << "typedef __SVBool_t  svbool_t;\n\n";
 
   OS << "typedef enum\n";


        


More information about the cfe-commits mailing list