[clang] 902e845 - [ARM, MVE] Add intrinsics for 'administrative' vector operations.

Simon Tatham via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 15 01:55:04 PST 2019


Author: Simon Tatham
Date: 2019-11-15T09:53:43Z
New Revision: 902e84556a51c70d95088aaa059ab9c494ab3516

URL: https://github.com/llvm/llvm-project/commit/902e84556a51c70d95088aaa059ab9c494ab3516
DIFF: https://github.com/llvm/llvm-project/commit/902e84556a51c70d95088aaa059ab9c494ab3516.diff

LOG: [ARM,MVE] Add intrinsics for 'administrative' vector operations.

This batch of intrinsics includes lots of things that move vector data
around or change its type without really affecting its value very
much. It includes the `vreinterpretq` family (cast one vector type to
another); `vuninitializedq` (create a vector of a given type with
don't-care contents); and `vcreateq` (make a 128-bit vector out of two
`uint64_t` halves).

These are all implemented using completely standard IR that's already
tested in existing LLVM unit tests, so I've just written a clang test
to check the IR is correct, and left it at that.

I've also added some richer infrastructure to the MveEmitter Tablegen
backend, to make it specify the exact integer type of integer
arguments passed to IR construction functions, and wrap those
arguments in a `static_cast` in the autogenerated C++. That was
necessary to prevent an overloading ambiguity when passing the integer
literal `0` to `IRBuilder::CreateInsertElement`, because otherwise, it
could mean either a null pointer `llvm::Value *` or a zero `uint64_t`.

Reviewers: ostannard, MarkMurrayARM, dmgreen

Subscribers: kristof.beyls, cfe-commits

Tags: #clang

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

Added: 
    clang/test/CodeGen/arm-mve-intrinsics/admin.c

Modified: 
    clang/include/clang/Basic/arm_mve.td
    clang/include/clang/Basic/arm_mve_defs.td
    clang/utils/TableGen/MveEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/arm_mve.td b/clang/include/clang/Basic/arm_mve.td
index d2f877dda28e..c8501813d264 100644
--- a/clang/include/clang/Basic/arm_mve.td
+++ b/clang/include/clang/Basic/arm_mve.td
@@ -373,3 +373,44 @@ def vadciq_m: Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b,
          (store (and 1, (lshr (xval $pair, 1), 29)), $carry),
          (xval $pair, 0))>;
 }
+
+foreach desttype = T.All in {
+  // We want a vreinterpretq between every pair of supported vector types
+  // _except_ that there shouldn't be one from a type to itself.
+  //
+  // So this foldl expression implements what you'd write in Python as
+  // [srctype for srctype in T.All if srctype != desttype]
+  let params = !foldl([]<Type>, T.All, tlist, srctype, !listconcat(tlist,
+      !if(!eq(!cast<string>(desttype),!cast<string>(srctype)),[],[srctype])))
+  in {
+    def "vreinterpretq_" # desttype: Intrinsic<
+        VecOf<desttype>, (args Vector:$x), (bitcast $x, VecOf<desttype>)>;
+  }
+}
+
+let params = T.All in {
+  let pnt = PNT_None in {
+    def vcreateq: Intrinsic<Vector, (args u64:$a, u64:$b),
+        (bitcast (ielt_const (ielt_const (undef VecOf<u64>), $a, 0),
+                             $b, 1), Vector)>;
+    def vuninitializedq: Intrinsic<Vector, (args), (undef Vector)>;
+  }
+
+  // This is the polymorphic form of vuninitializedq, which takes no type
+  // suffix, but takes an _unevaluated_ vector parameter and returns an
+  // uninitialized vector of the same vector type.
+  //
+  // This intrinsic has no _non_-polymorphic form exposed to the user. But each
+  // separately typed version of it still has to have its own clang builtin id,
+  // which can't be called vuninitializedq_u32 or similar because that would
+  // collide with the explicit nullary versions above. So I'm calling them
+  // vuninitializedq_polymorphic_u32 (and so on) for builtin id purposes; that
+  // full name never appears in the header file due to the polymorphicOnly
+  // flag, and the _polymorphic suffix is omitted from the shortened name by
+  // the custom PolymorphicNameType here.
+  let polymorphicOnly = 1, nonEvaluating = 1,
+      pnt = PolymorphicNameType<1, "polymorphic"> in {
+    def vuninitializedq_polymorphic: Intrinsic<
+        Vector, (args Vector), (undef Vector)>;
+  }
+}

diff  --git a/clang/include/clang/Basic/arm_mve_defs.td b/clang/include/clang/Basic/arm_mve_defs.td
index da6928fc137a..911c2c129db9 100644
--- a/clang/include/clang/Basic/arm_mve_defs.td
+++ b/clang/include/clang/Basic/arm_mve_defs.td
@@ -29,6 +29,11 @@ def args;
 // -----------------------------------------------------------------------------
 // Family of nodes for use in the codegen dag for an intrinsic, corresponding
 // to function calls that return LLVM IR nodes.
+class IRBuilderParam<int index_> { int index = index_; }
+class IRBuilderAddrParam<int index_> : IRBuilderParam<index_>;
+class IRBuilderIntParam<int index_, string type_> : IRBuilderParam<index_> {
+  string type = type_;
+}
 class IRBuilderBase {
   // The prefix of the function call, including an open parenthesis.
   string prefix;
@@ -36,8 +41,7 @@ class IRBuilderBase {
   // Any parameters that have types that have to be treated specially by the
   // Tablegen back end. Generally these will be types other than llvm::Value *,
   // although not all other types need special treatment (e.g. llvm::Type *).
-  list<int> address_params = []; // indices of parameters with type Address
-  list<int> int_constant_params = []; // indices of plain integer parameters
+  list<IRBuilderParam> special_params = [];
 }
 class IRBuilder<string func> : IRBuilderBase {
   // The usual case: a method called on the code gen function's instance of
@@ -61,12 +65,25 @@ def shl: IRBuilder<"CreateShl">;
 def lshr: IRBuilder<"CreateLShr">;
 def fadd: IRBuilder<"CreateFAdd">;
 def fsub: IRBuilder<"CreateFSub">;
-def load: IRBuilder<"CreateLoad"> { let address_params = [0]; }
-def store: IRBuilder<"CreateStore"> { let address_params = [1]; }
-def xval: IRBuilder<"CreateExtractValue"> { let int_constant_params = [1]; }
+def load: IRBuilder<"CreateLoad"> {
+  let special_params = [IRBuilderAddrParam<0>];
+}
+def store: IRBuilder<"CreateStore"> {
+  let special_params = [IRBuilderAddrParam<1>];
+}
+def xval: IRBuilder<"CreateExtractValue"> {
+  let special_params = [IRBuilderIntParam<1, "unsigned">];
+}
+def ielt_const: IRBuilder<"CreateInsertElement"> {
+  let special_params = [IRBuilderIntParam<2, "uint64_t">];
+}
 def trunc: IRBuilder<"CreateTrunc">;
-def extend: CGHelperFn<"SignOrZeroExtend"> { let int_constant_params = [2]; }
+def bitcast: IRBuilder<"CreateBitCast">;
+def extend: CGHelperFn<"SignOrZeroExtend"> {
+  let special_params = [IRBuilderIntParam<2, "bool">];
+}
 def zeroinit: IRFunction<"llvm::Constant::getNullValue">;
+def undef: IRFunction<"UndefValue::get">;
 
 // A node that makes an Address out of a pointer-typed Value, by
 // providing an alignment as the second argument.
@@ -350,6 +367,12 @@ class Intrinsic<Type ret_, dag args_, dag codegen_> {
 
   // Default to PNT_Type, which is by far the most common case.
   PolymorphicNameType pnt = PNT_Type;
+
+  // A very few intrinsics _only_ have a polymorphic name.
+  bit polymorphicOnly = 0;
+
+  // True if the builtin has to avoid evaluating its arguments.
+  bit nonEvaluating = 0;
 }
 
 // Sometimes you have to use two separate Intrinsic declarations to

diff  --git a/clang/test/CodeGen/arm-mve-intrinsics/admin.c b/clang/test/CodeGen/arm-mve-intrinsics/admin.c
new file mode 100644
index 000000000000..56740cbc5ad9
--- /dev/null
+++ b/clang/test/CodeGen/arm-mve-intrinsics/admin.c
@@ -0,0 +1,1556 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
+// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s
+// RUN: %clang_cc1 -triple thumbv8.1m.main-arm-none-eabi -target-feature +mve.fp -mfloat-abi hard -fallow-half-arguments-and-returns -O0 -disable-O0-optnone -DPOLYMORPHIC -S -emit-llvm -o - %s | opt -S -mem2reg -sroa -early-cse | FileCheck %s
+
+#include <arm_mve.h>
+
+// CHECK-LABEL: @test_vcreateq_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0
+// CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i64> [[TMP0]], i64 [[B:%.*]], i64 1
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to <8 x half>
+// CHECK-NEXT:    ret <8 x half> [[TMP2]]
+//
+float16x8_t test_vcreateq_f16(uint64_t a, uint64_t b)
+{
+    return vcreateq_f16(a, b);
+}
+
+// CHECK-LABEL: @test_vcreateq_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0
+// CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i64> [[TMP0]], i64 [[B:%.*]], i64 1
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to <4 x float>
+// CHECK-NEXT:    ret <4 x float> [[TMP2]]
+//
+float32x4_t test_vcreateq_f32(uint64_t a, uint64_t b)
+{
+    return vcreateq_f32(a, b);
+}
+
+// CHECK-LABEL: @test_vcreateq_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0
+// CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i64> [[TMP0]], i64 [[B:%.*]], i64 1
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP2]]
+//
+int16x8_t test_vcreateq_s16(uint64_t a, uint64_t b)
+{
+    return vcreateq_s16(a, b);
+}
+
+// CHECK-LABEL: @test_vcreateq_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0
+// CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i64> [[TMP0]], i64 [[B:%.*]], i64 1
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP2]]
+//
+int32x4_t test_vcreateq_s32(uint64_t a, uint64_t b)
+{
+    return vcreateq_s32(a, b);
+}
+
+// CHECK-LABEL: @test_vcreateq_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0
+// CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i64> [[TMP0]], i64 [[B:%.*]], i64 1
+// CHECK-NEXT:    ret <2 x i64> [[TMP1]]
+//
+int64x2_t test_vcreateq_s64(uint64_t a, uint64_t b)
+{
+    return vcreateq_s64(a, b);
+}
+
+// CHECK-LABEL: @test_vcreateq_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0
+// CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i64> [[TMP0]], i64 [[B:%.*]], i64 1
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+int8x16_t test_vcreateq_s8(uint64_t a, uint64_t b)
+{
+    return vcreateq_s8(a, b);
+}
+
+// CHECK-LABEL: @test_vcreateq_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0
+// CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i64> [[TMP0]], i64 [[B:%.*]], i64 1
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP2]]
+//
+uint16x8_t test_vcreateq_u16(uint64_t a, uint64_t b)
+{
+    return vcreateq_u16(a, b);
+}
+
+// CHECK-LABEL: @test_vcreateq_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0
+// CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i64> [[TMP0]], i64 [[B:%.*]], i64 1
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP2]]
+//
+uint32x4_t test_vcreateq_u32(uint64_t a, uint64_t b)
+{
+    return vcreateq_u32(a, b);
+}
+
+// CHECK-LABEL: @test_vcreateq_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0
+// CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i64> [[TMP0]], i64 [[B:%.*]], i64 1
+// CHECK-NEXT:    ret <2 x i64> [[TMP1]]
+//
+uint64x2_t test_vcreateq_u64(uint64_t a, uint64_t b)
+{
+    return vcreateq_u64(a, b);
+}
+
+// CHECK-LABEL: @test_vcreateq_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i64> undef, i64 [[A:%.*]], i64 0
+// CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i64> [[TMP0]], i64 [[B:%.*]], i64 1
+// CHECK-NEXT:    [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP2]]
+//
+uint8x16_t test_vcreateq_u8(uint64_t a, uint64_t b)
+{
+    return vcreateq_u8(a, b);
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f16_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <8 x half>
+// CHECK-NEXT:    ret <8 x half> [[TMP0]]
+//
+float16x8_t test_vreinterpretq_f16_f32(float32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f16_f32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f16_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <8 x half>
+// CHECK-NEXT:    ret <8 x half> [[TMP0]]
+//
+float16x8_t test_vreinterpretq_f16_s16(int16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f16_s16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f16_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x half>
+// CHECK-NEXT:    ret <8 x half> [[TMP0]]
+//
+float16x8_t test_vreinterpretq_f16_s32(int32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f16_s32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f16_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <8 x half>
+// CHECK-NEXT:    ret <8 x half> [[TMP0]]
+//
+float16x8_t test_vreinterpretq_f16_s64(int64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f16_s64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f16_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <8 x half>
+// CHECK-NEXT:    ret <8 x half> [[TMP0]]
+//
+float16x8_t test_vreinterpretq_f16_s8(int8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f16_s8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f16_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <8 x half>
+// CHECK-NEXT:    ret <8 x half> [[TMP0]]
+//
+float16x8_t test_vreinterpretq_f16_u16(uint16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f16_u16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f16_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x half>
+// CHECK-NEXT:    ret <8 x half> [[TMP0]]
+//
+float16x8_t test_vreinterpretq_f16_u32(uint32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f16_u32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f16_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <8 x half>
+// CHECK-NEXT:    ret <8 x half> [[TMP0]]
+//
+float16x8_t test_vreinterpretq_f16_u64(uint64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f16_u64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f16_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <8 x half>
+// CHECK-NEXT:    ret <8 x half> [[TMP0]]
+//
+float16x8_t test_vreinterpretq_f16_u8(uint8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f16_u8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f32_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x half> [[A:%.*]] to <4 x float>
+// CHECK-NEXT:    ret <4 x float> [[TMP0]]
+//
+float32x4_t test_vreinterpretq_f32_f16(float16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f32_f16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f32_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <4 x float>
+// CHECK-NEXT:    ret <4 x float> [[TMP0]]
+//
+float32x4_t test_vreinterpretq_f32_s16(int16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f32_s16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f32_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <4 x float>
+// CHECK-NEXT:    ret <4 x float> [[TMP0]]
+//
+float32x4_t test_vreinterpretq_f32_s32(int32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f32_s32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f32_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x float>
+// CHECK-NEXT:    ret <4 x float> [[TMP0]]
+//
+float32x4_t test_vreinterpretq_f32_s64(int64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f32_s64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f32_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <4 x float>
+// CHECK-NEXT:    ret <4 x float> [[TMP0]]
+//
+float32x4_t test_vreinterpretq_f32_s8(int8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f32_s8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f32_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <4 x float>
+// CHECK-NEXT:    ret <4 x float> [[TMP0]]
+//
+float32x4_t test_vreinterpretq_f32_u16(uint16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f32_u16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f32_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <4 x float>
+// CHECK-NEXT:    ret <4 x float> [[TMP0]]
+//
+float32x4_t test_vreinterpretq_f32_u32(uint32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f32_u32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f32_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x float>
+// CHECK-NEXT:    ret <4 x float> [[TMP0]]
+//
+float32x4_t test_vreinterpretq_f32_u64(uint64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f32_u64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_f32_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <4 x float>
+// CHECK-NEXT:    ret <4 x float> [[TMP0]]
+//
+float32x4_t test_vreinterpretq_f32_u8(uint8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_f32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_f32_u8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s16_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x half> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+int16x8_t test_vreinterpretq_s16_f16(float16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s16_f16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s16_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+int16x8_t test_vreinterpretq_s16_f32(float32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s16_f32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s16_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+int16x8_t test_vreinterpretq_s16_s32(int32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s16_s32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s16_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+int16x8_t test_vreinterpretq_s16_s64(int64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s16_s64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s16_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+int16x8_t test_vreinterpretq_s16_s8(int8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s16_s8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s16_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <8 x i16> [[A:%.*]]
+//
+int16x8_t test_vreinterpretq_s16_u16(uint16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s16_u16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s16_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+int16x8_t test_vreinterpretq_s16_u32(uint32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s16_u32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s16_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+int16x8_t test_vreinterpretq_s16_u64(uint64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s16_u64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s16_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+int16x8_t test_vreinterpretq_s16_u8(uint8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s16_u8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s32_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x half> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+int32x4_t test_vreinterpretq_s32_f16(float16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s32_f16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s32_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+int32x4_t test_vreinterpretq_s32_f32(float32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s32_f32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s32_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+int32x4_t test_vreinterpretq_s32_s16(int16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s32_s16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s32_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+int32x4_t test_vreinterpretq_s32_s64(int64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s32_s64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s32_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+int32x4_t test_vreinterpretq_s32_s8(int8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s32_s8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s32_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+int32x4_t test_vreinterpretq_s32_u16(uint16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s32_u16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s32_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> [[A:%.*]]
+//
+int32x4_t test_vreinterpretq_s32_u32(uint32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s32_u32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s32_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+int32x4_t test_vreinterpretq_s32_u64(uint64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s32_u64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s32_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+int32x4_t test_vreinterpretq_s32_u8(uint8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s32_u8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s64_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x half> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+int64x2_t test_vreinterpretq_s64_f16(float16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s64_f16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s64_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+int64x2_t test_vreinterpretq_s64_f32(float32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s64_f32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s64_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+int64x2_t test_vreinterpretq_s64_s16(int16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s64_s16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s64_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+int64x2_t test_vreinterpretq_s64_s32(int32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s64_s32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s64_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+int64x2_t test_vreinterpretq_s64_s8(int8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s64_s8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s64_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+int64x2_t test_vreinterpretq_s64_u16(uint16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s64_u16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s64_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+int64x2_t test_vreinterpretq_s64_u32(uint32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s64_u32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s64_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <2 x i64> [[A:%.*]]
+//
+int64x2_t test_vreinterpretq_s64_u64(uint64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s64_u64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s64_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+int64x2_t test_vreinterpretq_s64_u8(uint8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s64_u8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s8_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x half> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+int8x16_t test_vreinterpretq_s8_f16(float16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s8_f16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s8_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+int8x16_t test_vreinterpretq_s8_f32(float32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s8_f32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s8_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+int8x16_t test_vreinterpretq_s8_s16(int16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s8_s16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s8_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+int8x16_t test_vreinterpretq_s8_s32(int32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s8_s32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s8_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+int8x16_t test_vreinterpretq_s8_s64(int64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s8_s64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s8_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+int8x16_t test_vreinterpretq_s8_u16(uint16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s8_u16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s8_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+int8x16_t test_vreinterpretq_s8_u32(uint32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s8_u32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s8_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+int8x16_t test_vreinterpretq_s8_u64(uint64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s8_u64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_s8_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <16 x i8> [[A:%.*]]
+//
+int8x16_t test_vreinterpretq_s8_u8(uint8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_s8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_s8_u8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u16_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x half> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+uint16x8_t test_vreinterpretq_u16_f16(float16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u16_f16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u16_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+uint16x8_t test_vreinterpretq_u16_f32(float32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u16_f32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u16_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <8 x i16> [[A:%.*]]
+//
+uint16x8_t test_vreinterpretq_u16_s16(int16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u16_s16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u16_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+uint16x8_t test_vreinterpretq_u16_s32(int32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u16_s32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u16_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+uint16x8_t test_vreinterpretq_u16_s64(int64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u16_s64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u16_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+uint16x8_t test_vreinterpretq_u16_s8(int8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u16_s8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u16_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+uint16x8_t test_vreinterpretq_u16_u32(uint32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u16_u32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u16_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+uint16x8_t test_vreinterpretq_u16_u64(uint64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u16_u64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u16_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <8 x i16>
+// CHECK-NEXT:    ret <8 x i16> [[TMP0]]
+//
+uint16x8_t test_vreinterpretq_u16_u8(uint8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u16(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u16_u8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u32_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x half> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+uint32x4_t test_vreinterpretq_u32_f16(float16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u32_f16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u32_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+uint32x4_t test_vreinterpretq_u32_f32(float32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u32_f32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u32_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+uint32x4_t test_vreinterpretq_u32_s16(int16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u32_s16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u32_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> [[A:%.*]]
+//
+uint32x4_t test_vreinterpretq_u32_s32(int32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u32_s32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u32_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+uint32x4_t test_vreinterpretq_u32_s64(int64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u32_s64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u32_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+uint32x4_t test_vreinterpretq_u32_s8(int8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u32_s8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u32_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+uint32x4_t test_vreinterpretq_u32_u16(uint16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u32_u16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u32_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+uint32x4_t test_vreinterpretq_u32_u64(uint64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u32_u64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u32_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <4 x i32>
+// CHECK-NEXT:    ret <4 x i32> [[TMP0]]
+//
+uint32x4_t test_vreinterpretq_u32_u8(uint8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u32(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u32_u8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u64_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x half> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+uint64x2_t test_vreinterpretq_u64_f16(float16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u64_f16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u64_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+uint64x2_t test_vreinterpretq_u64_f32(float32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u64_f32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u64_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+uint64x2_t test_vreinterpretq_u64_s16(int16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u64_s16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u64_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+uint64x2_t test_vreinterpretq_u64_s32(int32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u64_s32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u64_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <2 x i64> [[A:%.*]]
+//
+uint64x2_t test_vreinterpretq_u64_s64(int64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u64_s64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u64_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+uint64x2_t test_vreinterpretq_u64_s8(int8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u64_s8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u64_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+uint64x2_t test_vreinterpretq_u64_u16(uint16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u64_u16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u64_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+uint64x2_t test_vreinterpretq_u64_u32(uint32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u64_u32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u64_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <16 x i8> [[A:%.*]] to <2 x i64>
+// CHECK-NEXT:    ret <2 x i64> [[TMP0]]
+//
+uint64x2_t test_vreinterpretq_u64_u8(uint8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u64(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u64_u8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u8_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x half> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+uint8x16_t test_vreinterpretq_u8_f16(float16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u8_f16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u8_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x float> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+uint8x16_t test_vreinterpretq_u8_f32(float32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u8_f32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u8_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+uint8x16_t test_vreinterpretq_u8_s16(int16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u8_s16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u8_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+uint8x16_t test_vreinterpretq_u8_s32(int32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u8_s32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u8_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+uint8x16_t test_vreinterpretq_u8_s64(int64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u8_s64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u8_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <16 x i8> [[A:%.*]]
+//
+uint8x16_t test_vreinterpretq_u8_s8(int8x16_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u8_s8(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u8_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <8 x i16> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+uint8x16_t test_vreinterpretq_u8_u16(uint16x8_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u8_u16(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u8_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <4 x i32> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+uint8x16_t test_vreinterpretq_u8_u32(uint32x4_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u8_u32(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vreinterpretq_u8_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[TMP0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <16 x i8>
+// CHECK-NEXT:    ret <16 x i8> [[TMP0]]
+//
+uint8x16_t test_vreinterpretq_u8_u64(uint64x2_t a)
+{
+#ifdef POLYMORPHIC
+    return vreinterpretq_u8(a);
+#else /* POLYMORPHIC */
+    return vreinterpretq_u8_u64(a);
+#endif /* POLYMORPHIC */
+}
+
+// CHECK-LABEL: @test_vuninitializedq_polymorphic_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <8 x half> undef
+//
+float16x8_t test_vuninitializedq_polymorphic_f16(float16x8_t (*funcptr)(void))
+{
+    return vuninitializedq(funcptr());
+}
+
+// CHECK-LABEL: @test_vuninitializedq_polymorphic_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x float> undef
+//
+float32x4_t test_vuninitializedq_polymorphic_f32(float32x4_t (*funcptr)(void))
+{
+    return vuninitializedq(funcptr());
+}
+
+// CHECK-LABEL: @test_vuninitializedq_polymorphic_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <16 x i8> undef
+//
+int8x16_t test_vuninitializedq_polymorphic_s8(int8x16_t (*funcptr)(void))
+{
+    return vuninitializedq(funcptr());
+}
+
+// CHECK-LABEL: @test_vuninitializedq_polymorphic_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <8 x i16> undef
+//
+int16x8_t test_vuninitializedq_polymorphic_s16(int16x8_t (*funcptr)(void))
+{
+    return vuninitializedq(funcptr());
+}
+
+// CHECK-LABEL: @test_vuninitializedq_polymorphic_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> undef
+//
+int32x4_t test_vuninitializedq_polymorphic_s32(int32x4_t (*funcptr)(void))
+{
+    return vuninitializedq(funcptr());
+}
+
+// CHECK-LABEL: @test_vuninitializedq_polymorphic_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <2 x i64> undef
+//
+int64x2_t test_vuninitializedq_polymorphic_s64(int64x2_t (*funcptr)(void))
+{
+    return vuninitializedq(funcptr());
+}
+
+// CHECK-LABEL: @test_vuninitializedq_polymorphic_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <16 x i8> undef
+//
+uint8x16_t test_vuninitializedq_polymorphic_u8(uint8x16_t (*funcptr)(void))
+{
+    return vuninitializedq(funcptr());
+}
+
+// CHECK-LABEL: @test_vuninitializedq_polymorphic_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <8 x i16> undef
+//
+uint16x8_t test_vuninitializedq_polymorphic_u16(uint16x8_t (*funcptr)(void))
+{
+    return vuninitializedq(funcptr());
+}
+
+// CHECK-LABEL: @test_vuninitializedq_polymorphic_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> undef
+//
+uint32x4_t test_vuninitializedq_polymorphic_u32(uint32x4_t (*funcptr)(void))
+{
+    return vuninitializedq(funcptr());
+}
+
+// CHECK-LABEL: @test_vuninitializedq_polymorphic_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <2 x i64> undef
+//
+uint64x2_t test_vuninitializedq_polymorphic_u64(uint64x2_t (*funcptr)(void))
+{
+    return vuninitializedq(funcptr());
+}
+
+// CHECK-LABEL: @test_vuninitializedq_f16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <8 x half> undef
+//
+float16x8_t test_vuninitializedq_f16(void)
+{
+    return vuninitializedq_f16();
+}
+
+// CHECK-LABEL: @test_vuninitializedq_f32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x float> undef
+//
+float32x4_t test_vuninitializedq_f32(void)
+{
+    return vuninitializedq_f32();
+}
+
+// CHECK-LABEL: @test_vuninitializedq_s16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <8 x i16> undef
+//
+int16x8_t test_vuninitializedq_s16(void)
+{
+    return vuninitializedq_s16();
+}
+
+// CHECK-LABEL: @test_vuninitializedq_s32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> undef
+//
+int32x4_t test_vuninitializedq_s32(void)
+{
+    return vuninitializedq_s32();
+}
+
+// CHECK-LABEL: @test_vuninitializedq_s64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <2 x i64> undef
+//
+int64x2_t test_vuninitializedq_s64(void)
+{
+    return vuninitializedq_s64();
+}
+
+// CHECK-LABEL: @test_vuninitializedq_s8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <16 x i8> undef
+//
+int8x16_t test_vuninitializedq_s8(void)
+{
+    return vuninitializedq_s8();
+}
+
+// CHECK-LABEL: @test_vuninitializedq_u16(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <8 x i16> undef
+//
+uint16x8_t test_vuninitializedq_u16(void)
+{
+    return vuninitializedq_u16();
+}
+
+// CHECK-LABEL: @test_vuninitializedq_u32(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> undef
+//
+uint32x4_t test_vuninitializedq_u32(void)
+{
+    return vuninitializedq_u32();
+}
+
+// CHECK-LABEL: @test_vuninitializedq_u64(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <2 x i64> undef
+//
+uint64x2_t test_vuninitializedq_u64(void)
+{
+    return vuninitializedq_u64();
+}
+
+// CHECK-LABEL: @test_vuninitializedq_u8(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <16 x i8> undef
+//
+uint8x16_t test_vuninitializedq_u8(void)
+{
+    return vuninitializedq_u8();
+}
+

diff  --git a/clang/utils/TableGen/MveEmitter.cpp b/clang/utils/TableGen/MveEmitter.cpp
index 2941cb6ec088..4258dd0a1f41 100644
--- a/clang/utils/TableGen/MveEmitter.cpp
+++ b/clang/utils/TableGen/MveEmitter.cpp
@@ -632,10 +632,10 @@ class IRBuilderResult : public Result {
   StringRef CallPrefix;
   std::vector<Ptr> Args;
   std::set<unsigned> AddressArgs;
-  std::set<unsigned> IntConstantArgs;
+  std::map<unsigned, std::string> IntConstantArgs;
   IRBuilderResult(StringRef CallPrefix, std::vector<Ptr> Args,
                   std::set<unsigned> AddressArgs,
-                  std::set<unsigned> IntConstantArgs)
+                  std::map<unsigned, std::string> IntConstantArgs)
     : CallPrefix(CallPrefix), Args(Args), AddressArgs(AddressArgs),
         IntConstantArgs(IntConstantArgs) {}
   void genCode(raw_ostream &OS,
@@ -644,11 +644,13 @@ class IRBuilderResult : public Result {
     const char *Sep = "";
     for (unsigned i = 0, e = Args.size(); i < e; ++i) {
       Ptr Arg = Args[i];
-      if (IntConstantArgs.find(i) != IntConstantArgs.end()) {
+      auto it = IntConstantArgs.find(i);
+      if (it != IntConstantArgs.end()) {
         assert(Arg->hasIntegerConstantValue());
-        OS << Sep
+        OS << Sep << "static_cast<" << it->second << ">("
            << ParamAlloc.allocParam("unsigned",
-                                    utostr(Arg->integerConstantValue()));
+                                    utostr(Arg->integerConstantValue()))
+           << ")";
       } else {
         OS << Sep << Arg->varname();
       }
@@ -763,6 +765,14 @@ class ACLEIntrinsic {
   // shares with at least one other intrinsic.
   std::string ShortName, FullName;
 
+  // A very small number of intrinsics _only_ have a polymorphic
+  // variant (vuninitializedq taking an unevaluated argument).
+  bool PolymorphicOnly;
+
+  // Another rarely-used flag indicating that the builtin doesn't
+  // evaluate its argument(s) at all.
+  bool NonEvaluating;
+
   const Type *ReturnType;
   std::vector<const Type *> ArgTypes;
   std::map<unsigned, ImmediateArg> ImmediateArgs;
@@ -796,6 +806,8 @@ class ACLEIntrinsic {
     return false;
   }
   bool polymorphic() const { return ShortName != FullName; }
+  bool polymorphicOnly() const { return PolymorphicOnly; }
+  bool nonEvaluating() const { return NonEvaluating; }
 
   // External entry point for code generation, called from MveEmitter.
   void genCode(raw_ostream &OS, CodeGenParamAllocator &ParamAlloc,
@@ -1126,11 +1138,15 @@ Result::Ptr MveEmitter::getCodeForDag(DagInit *D, const Result::Scope &Scope,
       Args.push_back(getCodeForDagArg(D, i, Scope, Param));
     if (Op->isSubClassOf("IRBuilderBase")) {
       std::set<unsigned> AddressArgs;
-      for (unsigned i : Op->getValueAsListOfInts("address_params"))
-        AddressArgs.insert(i);
-      std::set<unsigned> IntConstantArgs;
-      for (unsigned i : Op->getValueAsListOfInts("int_constant_params"))
-        IntConstantArgs.insert(i);
+      std::map<unsigned, std::string> IntConstantArgs;
+      for (Record *sp : Op->getValueAsListOfDefs("special_params")) {
+        unsigned Index = sp->getValueAsInt("index");
+        if (sp->isSubClassOf("IRBuilderAddrParam")) {
+          AddressArgs.insert(Index);
+        } else if (sp->isSubClassOf("IRBuilderIntParam")) {
+          IntConstantArgs[Index] = sp->getValueAsString("type");
+        }
+      }
       return std::make_shared<IRBuilderResult>(
           Op->getValueAsString("prefix"), Args, AddressArgs, IntConstantArgs);
     } else if (Op->isSubClassOf("IRIntBase")) {
@@ -1235,6 +1251,9 @@ ACLEIntrinsic::ACLEIntrinsic(MveEmitter &ME, Record *R, const Type *Param)
   }
   ShortName = join(std::begin(NameParts), std::end(NameParts), "_");
 
+  PolymorphicOnly = R->getValueAsBit("polymorphicOnly");
+  NonEvaluating = R->getValueAsBit("nonEvaluating");
+
   // Process the intrinsic's argument list.
   DagInit *ArgsDag = R->getValueAsDag("args");
   Result::Scope Scope;
@@ -1404,6 +1423,8 @@ void MveEmitter::EmitHeader(raw_ostream &OS) {
     for (bool Polymorphic : {false, true}) {
       if (Polymorphic && !Int.polymorphic())
         continue;
+      if (!Polymorphic && Int.polymorphicOnly())
+        continue;
 
       // We also generate each intrinsic under a name like __arm_vfooq
       // (which is in C language implementation namespace, so it's
@@ -1557,7 +1578,10 @@ void MveEmitter::EmitBuiltinDef(raw_ostream &OS) {
     if (Int.polymorphic()) {
       StringRef Name = Int.shortName();
       if (ShortNamesSeen.find(Name) == ShortNamesSeen.end()) {
-        OS << "BUILTIN(__builtin_arm_mve_" << Name << ", \"vi.\", \"nt\")\n";
+        OS << "BUILTIN(__builtin_arm_mve_" << Name << ", \"vi.\", \"nt";
+        if (Int.nonEvaluating())
+          OS << "u"; // indicate that this builtin doesn't evaluate its args
+        OS << "\")\n";
         ShortNamesSeen.insert(Name);
       }
     }


        


More information about the cfe-commits mailing list