llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Vicky Nguyen (iamvickynguyen)

<details>
<summary>Changes</summary>

Related to https://github.com/llvm/llvm-project/issues/185382

CIR lowering for load intrinsics (`vld[234]_*`/`vld[234]q_*`)
(https://arm-software.github.io/acle/neon_intrinsics/advsimd.html#stride)

Port tests:
- `clang/test/CodeGen/AArch64/neon-intrinsics.c`
- `clang/test/CodeGen/AArch64/neon-ldst-one.c`
- `clang/test/CodeGen/AArch64/poly64.c`

to `clang/test/CodeGen/AArch64/neon/load.c`

---

Patch is 453.37 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/220476.diff


5 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp (+74-17) 
- (modified) clang/test/CodeGen/AArch64/neon-intrinsics.c (-1344) 
- (removed) clang/test/CodeGen/AArch64/neon-ldst-one.c (-2567) 
- (modified) clang/test/CodeGen/AArch64/neon/load.c (+2310) 
- (modified) clang/test/CodeGen/AArch64/poly64.c (-96) 


``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp 
b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
index d681c390fe9de..592496b559efc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAArch64.cpp
@@ -827,26 +827,65 @@ static cir::RecordType getNeonMultiVecTy(CIRGenBuilderTy 
&builder,
                                  cir::RecordType::getAllDataKinds(members));
 }
 
+/// Call the multi-vector NEON load intrinsic `llvmIntrinsic` with `args` of
+/// `argTypes` and store the resulting `numVecs`-vector aggregate to the
+/// destination pointer `dest`. Mirrors the `CreateCall` +
+/// `CreateDefaultAlignedStore` pair used for `vld1_xN` in
+/// `EmitCommonNeonBuiltinExpr` and for `vld[234]{,_dup,_lane}` in
+/// `EmitAArch64BuiltinExpr` (ARM.cpp).
+static mlir::Value
+emitNeonMultiVecLoadCall(CIRGenFunction &cgf, mlir::Value dest,
+                         llvm::SmallVector<mlir::Type> argTypes,
+                         llvm::SmallVectorImpl<mlir::Value> &args,
+                         llvm::Intrinsic::ID llvmIntrinsic, mlir::Type ty,
+                         unsigned numVecs, mlir::Location loc) {
+  CIRGenBuilderTy &builder = cgf.getBuilder();
+  cir::RecordType recTy = getNeonMultiVecTy(builder, ty, numVecs);
+  mlir::Value result =
+      emitNeonCall(cgf.getCIRGenModule(), builder, std::move(argTypes), args,
+                   getLLVMIntrNameNoPrefix(llvmIntrinsic), recTy, loc);
+  Address destAddr(builder.createPtrBitcast(dest, recTy), recTy,
+                   clang::CharUnits::fromQuantity(
+                       cgf.cgm.getDataLayout().getABITypeAlign(recTy)));
+  builder.createStore(loc, result, destAddr);
+  return nullptr;
+}
+
 /// Emit a multi-vector NEON load: call `llvmIntrinsic` on the source pointer
 /// `ops[1]` and store the resulting aggregate to the destination pointer
-/// `ops[0]`. Mirrors the `CreateCall` + `CreateDefaultAlignedStore` pair in
-/// `EmitCommonNeonBuiltinExpr` (ARM.cpp).
+/// `ops[0]`.
 static mlir::Value emitNeonMultiVecLoad(CIRGenFunction &cgf,
                                         llvm::ArrayRef<mlir::Value> ops,
                                         unsigned llvmIntrinsic, mlir::Type ty,
                                         unsigned numVecs, mlir::Location loc) {
-  CIRGenBuilderTy &builder = cgf.getBuilder();
-  cir::RecordType recTy = getNeonMultiVecTy(builder, ty, numVecs);
   llvm::SmallVector<mlir::Value> srcOp = {ops[1]};
-  mlir::Value result = emitNeonCall(
-      cgf.getCIRGenModule(), builder, {builder.getVoidPtrTy()}, srcOp,
-      getLLVMIntrNameNoPrefix(static_cast<llvm::Intrinsic::ID>(llvmIntrinsic)),
-      recTy, loc);
-  Address dest(builder.createPtrBitcast(ops[0], recTy), recTy,
-               clang::CharUnits::fromQuantity(
-                   cgf.cgm.getDataLayout().getABITypeAlign(recTy)));
-  builder.createStore(loc, result, dest);
-  return nullptr;
+  return emitNeonMultiVecLoadCall(
+      cgf, ops[0], {cgf.getBuilder().getVoidPtrTy()}, srcOp,
+      static_cast<llvm::Intrinsic::ID>(llvmIntrinsic), ty, numVecs, loc);
+}
+
+/// Emit a multi-vector NEON load-lane: call `llvmIntrinsic` on the `numVecs`
+/// vector operands, the lane index, and the source pointer `ops[1]`, then
+/// store the resulting aggregate to the destination pointer `ops[0]`.
+/// `ops` on entry is `[dest, addr, vec0, ..., vec(numVecs-1), lane]`.
+static mlir::Value emitNeonMultiVecLoadLane(CIRGenFunction &cgf,
+                                            llvm::ArrayRef<mlir::Value> ops,
+                                            llvm::Intrinsic::ID llvmIntrinsic,
+                                            mlir::Type ty, unsigned numVecs,
+                                            mlir::Location loc) {
+  assert(ops.size() == numVecs + 3 && "expected [dest, addr, vecs..., lane]");
+  CIRGenBuilderTy &builder = cgf.getBuilder();
+  // Reorder to [vec0, ..., vec(numVecs-1), lane, addr] for the intrinsic call.
+  llvm::SmallVector<mlir::Value> callOps(ops.begin() + 2, ops.end());
+  callOps.push_back(ops[1]);
+  // The lane is a Sema-range-checked non-negative constant, so this
+  // sign-extending cast is equivalent to classic CodeGen's CreateZExt.
+  callOps[numVecs] = builder.createIntCast(callOps[numVecs], cgf.sInt64Ty);
+  llvm::SmallVector<mlir::Type> argTypes(numVecs, ty);
+  argTypes.push_back(cgf.sInt64Ty);
+  argTypes.push_back(builder.getVoidPtrTy());
+  return emitNeonMultiVecLoadCall(cgf, ops[0], std::move(argTypes), callOps,
+                                  llvmIntrinsic, ty, numVecs, loc);
 }
 
 static mlir::Value emitCommonNeonBuiltinExpr(
@@ -3708,28 +3747,46 @@ CIRGenFunction::emitAArch64BuiltinExpr(unsigned 
builtinID, const CallExpr *expr,
   }
   case NEON::BI__builtin_neon_vstl1_lane_s64:
   case NEON::BI__builtin_neon_vstl1q_lane_s64:
+    cgm.errorNYI(expr->getSourceRange(),
+                 std::string("unimplemented AArch64 builtin call: ") +
+                     getContext().BuiltinInfo.getName(builtinID));
+    return mlir::Value{};
   case NEON::BI__builtin_neon_vld2_v:
   case NEON::BI__builtin_neon_vld2q_v:
+    return emitNeonMultiVecLoad(*this, ops, llvm::Intrinsic::aarch64_neon_ld2,
+                                ty, 2, loc);
   case NEON::BI__builtin_neon_vld3_v:
   case NEON::BI__builtin_neon_vld3q_v:
+    return emitNeonMultiVecLoad(*this, ops, llvm::Intrinsic::aarch64_neon_ld3,
+                                ty, 3, loc);
   case NEON::BI__builtin_neon_vld4_v:
   case NEON::BI__builtin_neon_vld4q_v:
+    return emitNeonMultiVecLoad(*this, ops, llvm::Intrinsic::aarch64_neon_ld4,
+                                ty, 4, loc);
   case NEON::BI__builtin_neon_vld2_dup_v:
   case NEON::BI__builtin_neon_vld2q_dup_v:
+    return emitNeonMultiVecLoad(*this, ops, llvm::Intrinsic::aarch64_neon_ld2r,
+                                ty, 2, loc);
   case NEON::BI__builtin_neon_vld3_dup_v:
   case NEON::BI__builtin_neon_vld3q_dup_v:
+    return emitNeonMultiVecLoad(*this, ops, llvm::Intrinsic::aarch64_neon_ld3r,
+                                ty, 3, loc);
   case NEON::BI__builtin_neon_vld4_dup_v:
   case NEON::BI__builtin_neon_vld4q_dup_v:
+    return emitNeonMultiVecLoad(*this, ops, llvm::Intrinsic::aarch64_neon_ld4r,
+                                ty, 4, loc);
   case NEON::BI__builtin_neon_vld2_lane_v:
   case NEON::BI__builtin_neon_vld2q_lane_v:
+    return emitNeonMultiVecLoadLane(
+        *this, ops, llvm::Intrinsic::aarch64_neon_ld2lane, ty, 2, loc);
   case NEON::BI__builtin_neon_vld3_lane_v:
   case NEON::BI__builtin_neon_vld3q_lane_v:
+    return emitNeonMultiVecLoadLane(
+        *this, ops, llvm::Intrinsic::aarch64_neon_ld3lane, ty, 3, loc);
   case NEON::BI__builtin_neon_vld4_lane_v:
   case NEON::BI__builtin_neon_vld4q_lane_v:
-    cgm.errorNYI(expr->getSourceRange(),
-                 std::string("unimplemented AArch64 builtin call: ") +
-                     getContext().BuiltinInfo.getName(builtinID));
-    return mlir::Value{};
+    return emitNeonMultiVecLoadLane(
+        *this, ops, llvm::Intrinsic::aarch64_neon_ld4lane, ty, 4, loc);
   case NEON::BI__builtin_neon_vst2_v:
   case NEON::BI__builtin_neon_vst2q_v: {
     // The builtin call has the pointer first, but the AArch64 st2 intrinsic
diff --git a/clang/test/CodeGen/AArch64/neon-intrinsics.c 
b/clang/test/CodeGen/AArch64/neon-intrinsics.c
index 2098abb097889..ece835a96d294 100644
--- a/clang/test/CodeGen/AArch64/neon-intrinsics.c
+++ b/clang/test/CodeGen/AArch64/neon-intrinsics.c
@@ -4868,1350 +4868,6 @@ float64_t test_vrsqrted_f64(float64_t a) {
   return vrsqrted_f64(a);
 }
 
-// CHECK-LABEL: define dso_local %struct.uint8x16x2_t @test_vld2q_u8(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <16 x i8>, <16 x i8> } 
@llvm.aarch64.neon.ld2.v16i8.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <16 x i8>, <16 x 
i8> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <16 x i8>, <16 x 
i8> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_UINT8X16X2_T:%.*]] poison, <16 x i8> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_UINT8X16X2_T]] [[DOTFCA_0_0_INSERT]], <16 x i8> 
[[VLD2_FCA_1_EXTRACT]], 0, 1
-// CHECK-NEXT:    ret [[STRUCT_UINT8X16X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-uint8x16x2_t test_vld2q_u8(uint8_t const *a) {
-  return vld2q_u8(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.uint16x8x2_t @test_vld2q_u16(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <8 x i16>, <8 x i16> } 
@llvm.aarch64.neon.ld2.v8i16.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <8 x i16>, <8 x 
i16> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <8 x i16>, <8 x 
i16> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_UINT16X8X2_T:%.*]] poison, <8 x i16> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_UINT16X8X2_T]] [[DOTFCA_0_0_INSERT]], <8 x i16> 
[[VLD2_FCA_1_EXTRACT]], 0, 1
-// CHECK-NEXT:    ret [[STRUCT_UINT16X8X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-uint16x8x2_t test_vld2q_u16(uint16_t const *a) {
-  return vld2q_u16(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.uint32x4x2_t @test_vld2q_u32(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <4 x i32>, <4 x i32> } 
@llvm.aarch64.neon.ld2.v4i32.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <4 x i32>, <4 x 
i32> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <4 x i32>, <4 x 
i32> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_UINT32X4X2_T:%.*]] poison, <4 x i32> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_UINT32X4X2_T]] [[DOTFCA_0_0_INSERT]], <4 x i32> 
[[VLD2_FCA_1_EXTRACT]], 0, 1
-// CHECK-NEXT:    ret [[STRUCT_UINT32X4X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-uint32x4x2_t test_vld2q_u32(uint32_t const *a) {
-  return vld2q_u32(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.uint64x2x2_t @test_vld2q_u64(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <2 x i64>, <2 x i64> } 
@llvm.aarch64.neon.ld2.v2i64.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <2 x i64>, <2 x 
i64> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <2 x i64>, <2 x 
i64> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_UINT64X2X2_T:%.*]] poison, <2 x i64> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_UINT64X2X2_T]] [[DOTFCA_0_0_INSERT]], <2 x i64> 
[[VLD2_FCA_1_EXTRACT]], 0, 1
-// CHECK-NEXT:    ret [[STRUCT_UINT64X2X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-uint64x2x2_t test_vld2q_u64(uint64_t const *a) {
-  return vld2q_u64(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.int8x16x2_t @test_vld2q_s8(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <16 x i8>, <16 x i8> } 
@llvm.aarch64.neon.ld2.v16i8.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <16 x i8>, <16 x 
i8> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <16 x i8>, <16 x 
i8> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_INT8X16X2_T:%.*]] poison, <16 x i8> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_INT8X16X2_T]] [[DOTFCA_0_0_INSERT]], <16 x i8> [[VLD2_FCA_1_EXTRACT]], 
0, 1
-// CHECK-NEXT:    ret [[STRUCT_INT8X16X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-int8x16x2_t test_vld2q_s8(int8_t const *a) {
-  return vld2q_s8(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.int16x8x2_t @test_vld2q_s16(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <8 x i16>, <8 x i16> } 
@llvm.aarch64.neon.ld2.v8i16.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <8 x i16>, <8 x 
i16> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <8 x i16>, <8 x 
i16> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_INT16X8X2_T:%.*]] poison, <8 x i16> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_INT16X8X2_T]] [[DOTFCA_0_0_INSERT]], <8 x i16> [[VLD2_FCA_1_EXTRACT]], 
0, 1
-// CHECK-NEXT:    ret [[STRUCT_INT16X8X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-int16x8x2_t test_vld2q_s16(int16_t const *a) {
-  return vld2q_s16(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.int32x4x2_t @test_vld2q_s32(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <4 x i32>, <4 x i32> } 
@llvm.aarch64.neon.ld2.v4i32.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <4 x i32>, <4 x 
i32> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <4 x i32>, <4 x 
i32> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_INT32X4X2_T:%.*]] poison, <4 x i32> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_INT32X4X2_T]] [[DOTFCA_0_0_INSERT]], <4 x i32> [[VLD2_FCA_1_EXTRACT]], 
0, 1
-// CHECK-NEXT:    ret [[STRUCT_INT32X4X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-int32x4x2_t test_vld2q_s32(int32_t const *a) {
-  return vld2q_s32(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.int64x2x2_t @test_vld2q_s64(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <2 x i64>, <2 x i64> } 
@llvm.aarch64.neon.ld2.v2i64.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <2 x i64>, <2 x 
i64> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <2 x i64>, <2 x 
i64> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_INT64X2X2_T:%.*]] poison, <2 x i64> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_INT64X2X2_T]] [[DOTFCA_0_0_INSERT]], <2 x i64> [[VLD2_FCA_1_EXTRACT]], 
0, 1
-// CHECK-NEXT:    ret [[STRUCT_INT64X2X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-int64x2x2_t test_vld2q_s64(int64_t const *a) {
-  return vld2q_s64(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.float16x8x2_t @test_vld2q_f16(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <8 x half>, <8 x half> } 
@llvm.aarch64.neon.ld2.v8f16.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <8 x half>, <8 x 
half> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <8 x half>, <8 x 
half> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_FLOAT16X8X2_T:%.*]] poison, <8 x half> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_FLOAT16X8X2_T]] [[DOTFCA_0_0_INSERT]], <8 x half> 
[[VLD2_FCA_1_EXTRACT]], 0, 1
-// CHECK-NEXT:    ret [[STRUCT_FLOAT16X8X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-float16x8x2_t test_vld2q_f16(float16_t const *a) {
-  return vld2q_f16(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.float32x4x2_t @test_vld2q_f32(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <4 x float>, <4 x float> } 
@llvm.aarch64.neon.ld2.v4f32.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <4 x float>, <4 
x float> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <4 x float>, <4 
x float> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_FLOAT32X4X2_T:%.*]] poison, <4 x float> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_FLOAT32X4X2_T]] [[DOTFCA_0_0_INSERT]], <4 x float> 
[[VLD2_FCA_1_EXTRACT]], 0, 1
-// CHECK-NEXT:    ret [[STRUCT_FLOAT32X4X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-float32x4x2_t test_vld2q_f32(float32_t const *a) {
-  return vld2q_f32(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.float64x2x2_t @test_vld2q_f64(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <2 x double>, <2 x double> } 
@llvm.aarch64.neon.ld2.v2f64.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <2 x double>, <2 
x double> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <2 x double>, <2 
x double> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_FLOAT64X2X2_T:%.*]] poison, <2 x double> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_FLOAT64X2X2_T]] [[DOTFCA_0_0_INSERT]], <2 x double> 
[[VLD2_FCA_1_EXTRACT]], 0, 1
-// CHECK-NEXT:    ret [[STRUCT_FLOAT64X2X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-float64x2x2_t test_vld2q_f64(float64_t const *a) {
-  return vld2q_f64(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.mfloat8x16x2_t @test_vld2q_mf8(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <16 x i8>, <16 x i8> } 
@llvm.aarch64.neon.ld2.v16i8.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <16 x i8>, <16 x 
i8> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <16 x i8>, <16 x 
i8> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_MFLOAT8X16X2_T:%.*]] poison, <16 x i8> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_MFLOAT8X16X2_T]] [[DOTFCA_0_0_INSERT]], <16 x i8> 
[[VLD2_FCA_1_EXTRACT]], 0, 1
-// CHECK-NEXT:    ret [[STRUCT_MFLOAT8X16X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-mfloat8x16x2_t test_vld2q_mf8(mfloat8_t const *a) {
-  return vld2q_mf8(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.poly8x16x2_t @test_vld2q_p8(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <16 x i8>, <16 x i8> } 
@llvm.aarch64.neon.ld2.v16i8.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <16 x i8>, <16 x 
i8> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <16 x i8>, <16 x 
i8> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_POLY8X16X2_T:%.*]] poison, <16 x i8> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_POLY8X16X2_T]] [[DOTFCA_0_0_INSERT]], <16 x i8> 
[[VLD2_FCA_1_EXTRACT]], 0, 1
-// CHECK-NEXT:    ret [[STRUCT_POLY8X16X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-poly8x16x2_t test_vld2q_p8(poly8_t const *a) {
-  return vld2q_p8(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.poly16x8x2_t @test_vld2q_p16(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <8 x i16>, <8 x i16> } 
@llvm.aarch64.neon.ld2.v8i16.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <8 x i16>, <8 x 
i16> } [[VLD2]], 0
-// CHECK-NEXT:    [[VLD2_FCA_1_EXTRACT:%.*]] = extractvalue { <8 x i16>, <8 x 
i16> } [[VLD2]], 1
-// CHECK-NEXT:    [[DOTFCA_0_0_INSERT:%.*]] = insertvalue 
[[STRUCT_POLY16X8X2_T:%.*]] poison, <8 x i16> [[VLD2_FCA_0_EXTRACT]], 0, 0
-// CHECK-NEXT:    [[DOTFCA_0_1_INSERT:%.*]] = insertvalue 
[[STRUCT_POLY16X8X2_T]] [[DOTFCA_0_0_INSERT]], <8 x i16> 
[[VLD2_FCA_1_EXTRACT]], 0, 1
-// CHECK-NEXT:    ret [[STRUCT_POLY16X8X2_T]] [[DOTFCA_0_1_INSERT]]
-//
-poly16x8x2_t test_vld2q_p16(poly16_t const *a) {
-  return vld2q_p16(a);
-}
-
-// CHECK-LABEL: define dso_local %struct.uint8x8x2_t @test_vld2_u8(
-// CHECK-SAME: ptr noundef [[A:%.*]]) #[[ATTR0]] {
-// CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[VLD2:%.*]] = call { <8 x i8>, <8 x i8> } 
@llvm.aarch64.neon.ld2.v8i8.p0(ptr [[A]])
-// CHECK-NEXT:    [[VLD2_FCA_0_EXTRACT:%.*]] = extractvalue { <8 x i8>, <8 x 
i8> } [[VLD2]], 0
-...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/220476
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to