Author: Jirui Wu
Date: 2023-07-26T17:31:59+01:00
New Revision: 16902df6f25aea2bc10de37297691fcf1d0b89cc

URL: 
https://github.com/llvm/llvm-project/commit/16902df6f25aea2bc10de37297691fcf1d0b89cc
DIFF: 
https://github.com/llvm/llvm-project/commit/16902df6f25aea2bc10de37297691fcf1d0b89cc.diff

LOG: [ARM] Adding precommit tests for D146242

Adding precommit tests to better demonstrate the effects of D146242.

Reviewed By: pratlucas

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

Added: 
    clang/test/CodeGen/aarch64-ABI-align-packed-assembly.c
    clang/test/CodeGen/aarch64-ABI-align-packed.c

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/clang/test/CodeGen/aarch64-ABI-align-packed-assembly.c 
b/clang/test/CodeGen/aarch64-ABI-align-packed-assembly.c
new file mode 100644
index 00000000000000..197189a691bd0c
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-ABI-align-packed-assembly.c
@@ -0,0 +1,268 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -fsyntax-only -triple aarch64-none-eabi -target-feature 
+neon -S -O2 -o - %s | FileCheck %s
+#include <stdarg.h>
+#include <arm_neon.h>
+
+// natural alignment 16, adjusted alignment 16
+// expected alignment of copy on callee stack: 16
+struct non_packed_struct {
+  uint16x8_t M0; // member alignment 16
+};
+
+// natural alignment 1, adjusted alignment 1
+// expected alignment of copy on callee stack: 8
+struct __attribute((packed)) packed_struct {
+  uint16x8_t M0; // member alignment 1, because the field is packed when the 
struct is packed
+};
+
+// natural alignment 1, adjusted alignment 1
+// expected alignment of copy on callee stack: 8
+struct packed_member {
+  uint16x8_t M0 __attribute((packed)); // member alignment 1
+};
+
+// natural alignment 16, adjusted alignment 16 since __attribute((aligned 
(n))) sets the minimum alignment
+// expected alignment of copy on callee stack: 16
+struct __attribute((aligned (8))) aligned_struct_8 {
+  uint16x8_t M0; // member alignment 16
+};
+
+// natural alignment 16, adjusted alignment 16
+// expected alignment of copy on callee stack: 16
+struct aligned_member_8 {
+  uint16x8_t M0 __attribute((aligned (8))); // member alignment 16 since 
__attribute((aligned (n))) sets the minimum alignment
+};
+
+// natural alignment 8, adjusted alignment 8
+// expected alignment of copy on callee stack: 8
+#pragma pack(8)
+struct pragma_packed_struct_8 {
+  uint16x8_t M0; // member alignment 8 because the struct is subject to 
packed(8)
+};
+
+// natural alignment 4, adjusted alignment 4
+// expected alignment of copy on callee stack: 8
+#pragma pack(4)
+struct pragma_packed_struct_4 {
+  uint16x8_t M0; // member alignment 4 because the struct is subject to 
packed(4)
+};
+
+double gd;
+void init(int, ...);
+
+struct non_packed_struct gs_non_packed_struct;
+
+__attribute__((noinline)) void named_arg_non_packed_struct(double d0, double 
d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct non_packed_struct 
s_non_packed_struct) {
+// CHECK: ldr q0, [sp, #16]
+    gd = d8;
+    gs_non_packed_struct = s_non_packed_struct;
+}
+
+void variadic_non_packed_struct(double d0, double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct non_packed_struct on_callee_stack;
+  on_callee_stack = va_arg(vl, struct non_packed_struct);
+}
+
+void test_non_packed_struct() {
+    struct non_packed_struct s_non_packed_struct;
+    init(1, &s_non_packed_struct);
+
+// CHECK: mov x8, #4611686018427387904        // =0x4000000000000000
+// CHECK: str q0, [sp, #16]
+// CHECK: str x8, [sp]
+    named_arg_non_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_non_packed_struct);
+// CHECK: str q0, [sp, #16]
+    variadic_non_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_non_packed_struct);
+}
+
+struct packed_struct gs_packed_struct;
+
+__attribute__((noinline)) void named_arg_packed_struct(double d0, double d1, 
double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct packed_struct 
s_packed_struct) {
+// CHECK: ldr q0, [sp, #16]
+    gd = d8;
+    gs_packed_struct = s_packed_struct;
+}
+
+void variadic_packed_struct(double d0, double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct packed_struct on_callee_stack;
+  on_callee_stack = va_arg(vl, struct packed_struct);
+}
+
+void test_packed_struct() {
+    struct packed_struct s_packed_struct;
+    init(1, &s_packed_struct);
+
+// CHECK: mov x8, #4611686018427387904        // =0x4000000000000000
+// CHECK: str q0, [sp, #16]
+// CHECK: str x8, [sp]
+    named_arg_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_packed_struct);
+// CHECK: str q0, [sp, #16]
+    variadic_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_packed_struct);
+}
+
+struct packed_member gs_packed_member;
+
+__attribute__((noinline)) void named_arg_packed_member(double d0, double d1, 
double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct packed_member 
s_packed_member) {
+// CHECK: ldr q0, [sp, #16]
+    gd = d8;
+    gs_packed_member = s_packed_member;
+}
+
+void variadic_packed_member(double d0, double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct packed_member on_callee_stack;
+  on_callee_stack = va_arg(vl, struct packed_member);
+}
+
+void test_packed_member() {
+    struct packed_member s_packed_member;
+    init(1, &s_packed_member);
+
+// CHECK: mov x8, #4611686018427387904        // =0x4000000000000000
+// CHECK: str q0, [sp, #16]
+// CHECK: str x8, [sp]
+    named_arg_packed_member(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_packed_member);
+// CHECK: str q0, [sp, #16]
+    variadic_packed_member(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_packed_member);
+}
+
+struct aligned_struct_8 gs_aligned_struct_8;
+
+__attribute__((noinline)) void named_arg_aligned_struct_8(double d0, double 
d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct aligned_struct_8 
s_aligned_struct_8) {
+// CHECK: ldr q0, [sp, #16]
+    gd = d8;
+    gs_aligned_struct_8 = s_aligned_struct_8;
+}
+
+void variadic_aligned_struct_8(double d0, double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct aligned_struct_8 on_callee_stack;
+  on_callee_stack = va_arg(vl, struct aligned_struct_8);
+}
+
+void test_aligned_struct_8() {
+    struct aligned_struct_8 s_aligned_struct_8;
+    init(1, &s_aligned_struct_8);
+
+// CHECK: mov x8, #4611686018427387904        // =0x4000000000000000
+// CHECK: str q0, [sp, #16]
+// CHECK: str x8, [sp]
+    named_arg_aligned_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_aligned_struct_8);
+// CHECK: str q0, [sp, #16]
+    variadic_aligned_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_aligned_struct_8);
+}
+
+struct aligned_member_8 gs_aligned_member_8;
+
+__attribute__((noinline)) void named_arg_aligned_member_8(double d0, double 
d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct aligned_member_8 
s_aligned_member_8) {
+// CHECK: ldr q0, [sp, #16]
+    gd = d8;
+    gs_aligned_member_8 = s_aligned_member_8;
+}
+
+void variadic_aligned_member_8(double d0, double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct aligned_member_8 on_callee_stack;
+  on_callee_stack = va_arg(vl, struct aligned_member_8);
+}
+
+void test_aligned_member_8() {
+    struct aligned_member_8 s_aligned_member_8;
+    init(1, &s_aligned_member_8);
+
+// CHECK: mov x8, #4611686018427387904        // =0x4000000000000000
+// CHECK: str q0, [sp, #16]
+// CHECK: str x8, [sp]
+    named_arg_aligned_member_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_aligned_member_8);
+// CHECK: str q0, [sp, #16]
+    variadic_aligned_member_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_aligned_member_8);
+}
+
+struct pragma_packed_struct_8 gs_pragma_packed_struct_8;
+
+__attribute__((noinline)) void named_arg_pragma_packed_struct_8(double d0, 
double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct pragma_packed_struct_8 
s_pragma_packed_struct_8) {
+// CHECK: ldr q0, [sp, #16]
+    gd = d8;
+    gs_pragma_packed_struct_8 = s_pragma_packed_struct_8;
+}
+
+void variadic_pragma_packed_struct_8(double d0, double d1, double d2, double 
d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct pragma_packed_struct_8 on_callee_stack;
+  on_callee_stack = va_arg(vl, struct pragma_packed_struct_8);
+}
+
+void test_pragma_packed_struct_8() {
+    struct pragma_packed_struct_8 s_pragma_packed_struct_8;
+    init(1, &s_pragma_packed_struct_8);
+
+// CHECK: mov x8, #4611686018427387904        // =0x4000000000000000
+// CHECK: str q0, [sp, #16]
+// CHECK: str x8, [sp]
+    named_arg_pragma_packed_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
2.0, s_pragma_packed_struct_8);
+// CHECK: str q0, [sp, #16]
+    variadic_pragma_packed_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
2.0, s_pragma_packed_struct_8);
+}
+
+struct pragma_packed_struct_4 gs_pragma_packed_struct_4;
+
+__attribute__((noinline)) void named_arg_pragma_packed_struct_4(double d0, 
double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct pragma_packed_struct_4 
s_pragma_packed_struct_4) {
+// CHECK: ldr q0, [sp, #16]
+    gd = d8;
+    gs_pragma_packed_struct_4 = s_pragma_packed_struct_4;
+}
+
+void variadic_pragma_packed_struct_4(double d0, double d1, double d2, double 
d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct pragma_packed_struct_4 on_callee_stack;
+  on_callee_stack = va_arg(vl, struct pragma_packed_struct_4);
+}
+
+void test_pragma_packed_struct_4() {
+    struct pragma_packed_struct_4 s_pragma_packed_struct_4;
+    init(1, &s_pragma_packed_struct_4);
+
+// CHECK: mov x8, #4611686018427387904        // =0x4000000000000000
+// CHECK: str q0, [sp, #16]
+// CHECK: str x8, [sp]
+    named_arg_pragma_packed_struct_4(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
2.0, s_pragma_packed_struct_4);
+// CHECK: str q0, [sp, #16]
+    variadic_pragma_packed_struct_4(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
2.0, s_pragma_packed_struct_4);
+}

diff  --git a/clang/test/CodeGen/aarch64-ABI-align-packed.c 
b/clang/test/CodeGen/aarch64-ABI-align-packed.c
new file mode 100644
index 00000000000000..a1c7d8b2cc6a9b
--- /dev/null
+++ b/clang/test/CodeGen/aarch64-ABI-align-packed.c
@@ -0,0 +1,436 @@
+// REQUIRES: aarch64-registered-target
+// RUN: %clang_cc1 -fsyntax-only -triple aarch64-none-eabi -target-feature 
+neon -emit-llvm -O2 -o - %s | FileCheck %s
+#include <stdarg.h>
+#include <arm_neon.h>
+
+// natural alignment 16, adjusted alignment 16
+// expected alignment of copy on callee stack: 16
+struct non_packed_struct {
+  uint16x8_t M0; // member alignment 16
+};
+
+// natural alignment 1, adjusted alignment 1
+// expected alignment of copy on callee stack: 8
+struct __attribute((packed)) packed_struct {
+  uint16x8_t M0; // member alignment 1, because the field is packed when the 
struct is packed
+};
+
+// natural alignment 1, adjusted alignment 1
+// expected alignment of copy on callee stack: 8
+struct packed_member {
+  uint16x8_t M0 __attribute((packed)); // member alignment 1
+};
+
+// natural alignment 16, adjusted alignment 16 since __attribute((aligned 
(n))) sets the minimum alignment
+// expected alignment of copy on callee stack: 16
+struct __attribute((aligned (8))) aligned_struct_8 {
+  uint16x8_t M0; // member alignment 16
+};
+
+// natural alignment 16, adjusted alignment 16
+// expected alignment of copy on callee stack: 16
+struct aligned_member_8 {
+  uint16x8_t M0 __attribute((aligned (8))); // member alignment 16 since 
__attribute((aligned (n))) sets the minimum alignment
+};
+
+// natural alignment 8, adjusted alignment 8
+// expected alignment of copy on callee stack: 8
+#pragma pack(8)
+struct pragma_packed_struct_8 {
+  uint16x8_t M0; // member alignment 8 because the struct is subject to 
packed(8)
+};
+
+// natural alignment 4, adjusted alignment 4
+// expected alignment of copy on callee stack: 8
+#pragma pack(4)
+struct pragma_packed_struct_4 {
+  uint16x8_t M0; // member alignment 4 because the struct is subject to 
packed(4)
+};
+
+double gd;
+void init(int, ...);
+
+struct non_packed_struct gs_non_packed_struct;
+
+// CHECK-LABEL: define dso_local void @named_arg_non_packed_struct
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] 
[[S_NON_PACKED_STRUCT_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_NON_PACKED_STRUCT_COERCE_FCA_0_EXTRACT:%.*]] = 
extractvalue [1 x <8 x i16>] [[S_NON_PACKED_STRUCT_COERCE]], 0
+// CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa 
[[TBAA2:![0-9]+]]
+// CHECK-NEXT:    store <8 x i16> 
[[S_NON_PACKED_STRUCT_COERCE_FCA_0_EXTRACT]], ptr @gs_non_packed_struct, align 
16, !tbaa.struct [[TBAA_STRUCT6:![0-9]+]]
+// CHECK-NEXT:    ret void
+__attribute__((noinline)) void named_arg_non_packed_struct(double d0, double 
d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct non_packed_struct 
s_non_packed_struct) {
+    gd = d8;
+    gs_non_packed_struct = s_non_packed_struct;
+}
+
+// CHECK-LABEL: define dso_local void @variadic_non_packed_struct
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1:[0-9]+]] 
{
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull 
[[VL]]) #[[ATTR6:[0-9]+]]
+// CHECK-NEXT:    call void @llvm.va_start(ptr nonnull [[VL]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) 
#[[ATTR6]]
+// CHECK-NEXT:    ret void
+void variadic_non_packed_struct(double d0, double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct non_packed_struct on_callee_stack;
+  on_callee_stack = va_arg(vl, struct non_packed_struct);
+}
+
+// CHECK-LABEL: define dso_local void @test_non_packed_struct
+// CHECK-SAME: () local_unnamed_addr #[[ATTR4:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_NON_PACKED_STRUCT:%.*]] = alloca 
[[STRUCT_NON_PACKED_STRUCT:%.*]], align 16
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull 
[[S_NON_PACKED_STRUCT]]) #[[ATTR6]]
+// CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef 
nonnull [[S_NON_PACKED_STRUCT]]) #[[ATTR6]]
+// CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr 
[[S_NON_PACKED_STRUCT]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
+// CHECK-NEXT:    call void @named_arg_non_packed_struct(double poison, double 
poison, double poison, double poison, double poison, double poison, double 
poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] 
[[DOTFCA_0_INSERT]])
+// CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr 
[[S_NON_PACKED_STRUCT]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
+// CHECK-NEXT:    call void (double, double, double, double, double, double, 
double, double, double, ...) @variadic_non_packed_struct(double poison, double 
poison, double poison, double poison, double poison, double poison, double 
poison, double poison, double poison, [1 x <8 x i16>] [[DOTFCA_0_INSERT4]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull 
[[S_NON_PACKED_STRUCT]]) #[[ATTR6]]
+// CHECK-NEXT:    ret void
+void test_non_packed_struct() {
+    struct non_packed_struct s_non_packed_struct;
+    init(1, &s_non_packed_struct);
+
+    named_arg_non_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_non_packed_struct);
+    variadic_non_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_non_packed_struct);
+}
+
+struct packed_struct gs_packed_struct;
+
+// CHECK-LABEL: define dso_local void @named_arg_packed_struct
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] 
[[S_PACKED_STRUCT_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_PACKED_STRUCT_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue 
[1 x <8 x i16>] [[S_PACKED_STRUCT_COERCE]], 0
+// CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:    store <8 x i16> [[S_PACKED_STRUCT_COERCE_FCA_0_EXTRACT]], 
ptr @gs_packed_struct, align 1, !tbaa.struct [[TBAA_STRUCT6]]
+// CHECK-NEXT:    ret void
+__attribute__((noinline)) void named_arg_packed_struct(double d0, double d1, 
double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct packed_struct 
s_packed_struct) {
+    gd = d8;
+    gs_packed_struct = s_packed_struct;
+}
+
+// CHECK-LABEL: define dso_local void @variadic_packed_struct
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull 
[[VL]]) #[[ATTR6]]
+// CHECK-NEXT:    call void @llvm.va_start(ptr nonnull [[VL]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) 
#[[ATTR6]]
+// CHECK-NEXT:    ret void
+void variadic_packed_struct(double d0, double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct packed_struct on_callee_stack;
+  on_callee_stack = va_arg(vl, struct packed_struct);
+}
+
+// CHECK-LABEL: define dso_local void @test_packed_struct
+// CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_PACKED_STRUCT:%.*]] = alloca 
[[STRUCT_PACKED_STRUCT:%.*]], align 16
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull 
[[S_PACKED_STRUCT]]) #[[ATTR6]]
+// CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef 
nonnull [[S_PACKED_STRUCT]]) #[[ATTR6]]
+// CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr 
[[S_PACKED_STRUCT]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
+// CHECK-NEXT:    call void @named_arg_packed_struct(double poison, double 
poison, double poison, double poison, double poison, double poison, double 
poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] 
[[DOTFCA_0_INSERT]])
+// CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr 
[[S_PACKED_STRUCT]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
+// CHECK-NEXT:    call void (double, double, double, double, double, double, 
double, double, double, ...) @variadic_packed_struct(double poison, double 
poison, double poison, double poison, double poison, double poison, double 
poison, double poison, double poison, [1 x <8 x i16>] [[DOTFCA_0_INSERT4]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull 
[[S_PACKED_STRUCT]]) #[[ATTR6]]
+// CHECK-NEXT:    ret void
+void test_packed_struct() {
+    struct packed_struct s_packed_struct;
+    init(1, &s_packed_struct);
+
+    named_arg_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_packed_struct);
+    variadic_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_packed_struct);
+}
+
+struct packed_member gs_packed_member;
+
+// CHECK-LABEL: define dso_local void @named_arg_packed_member
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] 
[[S_PACKED_MEMBER_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_PACKED_MEMBER_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue 
[1 x <8 x i16>] [[S_PACKED_MEMBER_COERCE]], 0
+// CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:    store <8 x i16> [[S_PACKED_MEMBER_COERCE_FCA_0_EXTRACT]], 
ptr @gs_packed_member, align 1, !tbaa.struct [[TBAA_STRUCT6]]
+// CHECK-NEXT:    ret void
+__attribute__((noinline)) void named_arg_packed_member(double d0, double d1, 
double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct packed_member 
s_packed_member) {
+    gd = d8;
+    gs_packed_member = s_packed_member;
+}
+
+// CHECK-LABEL: define dso_local void @variadic_packed_member
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull 
[[VL]]) #[[ATTR6]]
+// CHECK-NEXT:    call void @llvm.va_start(ptr nonnull [[VL]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) 
#[[ATTR6]]
+// CHECK-NEXT:    ret void
+void variadic_packed_member(double d0, double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct packed_member on_callee_stack;
+  on_callee_stack = va_arg(vl, struct packed_member);
+}
+
+// CHECK-LABEL: define dso_local void @test_packed_member
+// CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_PACKED_MEMBER:%.*]] = alloca 
[[STRUCT_PACKED_MEMBER:%.*]], align 16
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull 
[[S_PACKED_MEMBER]]) #[[ATTR6]]
+// CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef 
nonnull [[S_PACKED_MEMBER]]) #[[ATTR6]]
+// CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr 
[[S_PACKED_MEMBER]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
+// CHECK-NEXT:    call void @named_arg_packed_member(double poison, double 
poison, double poison, double poison, double poison, double poison, double 
poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] 
[[DOTFCA_0_INSERT]])
+// CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr 
[[S_PACKED_MEMBER]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
+// CHECK-NEXT:    call void (double, double, double, double, double, double, 
double, double, double, ...) @variadic_packed_member(double poison, double 
poison, double poison, double poison, double poison, double poison, double 
poison, double poison, double poison, [1 x <8 x i16>] [[DOTFCA_0_INSERT4]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull 
[[S_PACKED_MEMBER]]) #[[ATTR6]]
+// CHECK-NEXT:    ret void
+void test_packed_member() {
+    struct packed_member s_packed_member;
+    init(1, &s_packed_member);
+
+    named_arg_packed_member(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_packed_member);
+    variadic_packed_member(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_packed_member);
+}
+
+struct aligned_struct_8 gs_aligned_struct_8;
+
+// CHECK-LABEL: define dso_local void @named_arg_aligned_struct_8
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] 
[[S_ALIGNED_STRUCT_8_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_ALIGNED_STRUCT_8_COERCE_FCA_0_EXTRACT:%.*]] = 
extractvalue [1 x <8 x i16>] [[S_ALIGNED_STRUCT_8_COERCE]], 0
+// CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:    store <8 x i16> [[S_ALIGNED_STRUCT_8_COERCE_FCA_0_EXTRACT]], 
ptr @gs_aligned_struct_8, align 16, !tbaa.struct [[TBAA_STRUCT6]]
+// CHECK-NEXT:    ret void
+__attribute__((noinline)) void named_arg_aligned_struct_8(double d0, double 
d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct aligned_struct_8 
s_aligned_struct_8) {
+    gd = d8;
+    gs_aligned_struct_8 = s_aligned_struct_8;
+}
+
+// CHECK-LABEL: define dso_local void @variadic_aligned_struct_8
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull 
[[VL]]) #[[ATTR6]]
+// CHECK-NEXT:    call void @llvm.va_start(ptr nonnull [[VL]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) 
#[[ATTR6]]
+// CHECK-NEXT:    ret void
+void variadic_aligned_struct_8(double d0, double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct aligned_struct_8 on_callee_stack;
+  on_callee_stack = va_arg(vl, struct aligned_struct_8);
+}
+
+// CHECK-LABEL: define dso_local void @test_aligned_struct_8
+// CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_ALIGNED_STRUCT_8:%.*]] = alloca 
[[STRUCT_ALIGNED_STRUCT_8:%.*]], align 16
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull 
[[S_ALIGNED_STRUCT_8]]) #[[ATTR6]]
+// CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef 
nonnull [[S_ALIGNED_STRUCT_8]]) #[[ATTR6]]
+// CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr 
[[S_ALIGNED_STRUCT_8]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
+// CHECK-NEXT:    call void @named_arg_aligned_struct_8(double poison, double 
poison, double poison, double poison, double poison, double poison, double 
poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] 
[[DOTFCA_0_INSERT]])
+// CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr 
[[S_ALIGNED_STRUCT_8]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
+// CHECK-NEXT:    call void (double, double, double, double, double, double, 
double, double, double, ...) @variadic_aligned_struct_8(double poison, double 
poison, double poison, double poison, double poison, double poison, double 
poison, double poison, double poison, [1 x <8 x i16>] [[DOTFCA_0_INSERT4]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull 
[[S_ALIGNED_STRUCT_8]]) #[[ATTR6]]
+// CHECK-NEXT:    ret void
+void test_aligned_struct_8() {
+    struct aligned_struct_8 s_aligned_struct_8;
+    init(1, &s_aligned_struct_8);
+
+    named_arg_aligned_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_aligned_struct_8);
+    variadic_aligned_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_aligned_struct_8);
+}
+
+struct aligned_member_8 gs_aligned_member_8;
+
+// CHECK-LABEL: define dso_local void @named_arg_aligned_member_8
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] 
[[S_ALIGNED_MEMBER_8_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_ALIGNED_MEMBER_8_COERCE_FCA_0_EXTRACT:%.*]] = 
extractvalue [1 x <8 x i16>] [[S_ALIGNED_MEMBER_8_COERCE]], 0
+// CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:    store <8 x i16> [[S_ALIGNED_MEMBER_8_COERCE_FCA_0_EXTRACT]], 
ptr @gs_aligned_member_8, align 16, !tbaa.struct [[TBAA_STRUCT6]]
+// CHECK-NEXT:    ret void
+__attribute__((noinline)) void named_arg_aligned_member_8(double d0, double 
d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct aligned_member_8 
s_aligned_member_8) {
+    gd = d8;
+    gs_aligned_member_8 = s_aligned_member_8;
+}
+
+// CHECK-LABEL: define dso_local void @variadic_aligned_member_8
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull 
[[VL]]) #[[ATTR6]]
+// CHECK-NEXT:    call void @llvm.va_start(ptr nonnull [[VL]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) 
#[[ATTR6]]
+// CHECK-NEXT:    ret void
+void variadic_aligned_member_8(double d0, double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct aligned_member_8 on_callee_stack;
+  on_callee_stack = va_arg(vl, struct aligned_member_8);
+}
+
+// CHECK-LABEL: define dso_local void @test_aligned_member_8
+// CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_ALIGNED_MEMBER_8:%.*]] = alloca 
[[STRUCT_ALIGNED_MEMBER_8:%.*]], align 16
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull 
[[S_ALIGNED_MEMBER_8]]) #[[ATTR6]]
+// CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef 
nonnull [[S_ALIGNED_MEMBER_8]]) #[[ATTR6]]
+// CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr 
[[S_ALIGNED_MEMBER_8]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
+// CHECK-NEXT:    call void @named_arg_aligned_member_8(double poison, double 
poison, double poison, double poison, double poison, double poison, double 
poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] 
[[DOTFCA_0_INSERT]])
+// CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr 
[[S_ALIGNED_MEMBER_8]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
+// CHECK-NEXT:    call void (double, double, double, double, double, double, 
double, double, double, ...) @variadic_aligned_member_8(double poison, double 
poison, double poison, double poison, double poison, double poison, double 
poison, double poison, double poison, [1 x <8 x i16>] [[DOTFCA_0_INSERT4]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull 
[[S_ALIGNED_MEMBER_8]]) #[[ATTR6]]
+// CHECK-NEXT:    ret void
+void test_aligned_member_8() {
+    struct aligned_member_8 s_aligned_member_8;
+    init(1, &s_aligned_member_8);
+
+    named_arg_aligned_member_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_aligned_member_8);
+    variadic_aligned_member_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 
s_aligned_member_8);
+}
+
+struct pragma_packed_struct_8 gs_pragma_packed_struct_8;
+
+// CHECK-LABEL: define dso_local void @named_arg_pragma_packed_struct_8
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] 
[[S_PRAGMA_PACKED_STRUCT_8_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_PRAGMA_PACKED_STRUCT_8_COERCE_FCA_0_EXTRACT:%.*]] = 
extractvalue [1 x <8 x i16>] [[S_PRAGMA_PACKED_STRUCT_8_COERCE]], 0
+// CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:    store <8 x i16> 
[[S_PRAGMA_PACKED_STRUCT_8_COERCE_FCA_0_EXTRACT]], ptr 
@gs_pragma_packed_struct_8, align 8, !tbaa.struct [[TBAA_STRUCT6]]
+// CHECK-NEXT:    ret void
+__attribute__((noinline)) void named_arg_pragma_packed_struct_8(double d0, 
double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct pragma_packed_struct_8 
s_pragma_packed_struct_8) {
+    gd = d8;
+    gs_pragma_packed_struct_8 = s_pragma_packed_struct_8;
+}
+
+// CHECK-LABEL: define dso_local void @variadic_pragma_packed_struct_8
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull 
[[VL]]) #[[ATTR6]]
+// CHECK-NEXT:    call void @llvm.va_start(ptr nonnull [[VL]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) 
#[[ATTR6]]
+// CHECK-NEXT:    ret void
+void variadic_pragma_packed_struct_8(double d0, double d1, double d2, double 
d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct pragma_packed_struct_8 on_callee_stack;
+  on_callee_stack = va_arg(vl, struct pragma_packed_struct_8);
+}
+
+// CHECK-LABEL: define dso_local void @test_pragma_packed_struct_8
+// CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_PRAGMA_PACKED_STRUCT_8:%.*]] = alloca 
[[STRUCT_PRAGMA_PACKED_STRUCT_8:%.*]], align 16
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull 
[[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]]
+// CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef 
nonnull [[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]]
+// CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr 
[[S_PRAGMA_PACKED_STRUCT_8]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
+// CHECK-NEXT:    call void @named_arg_pragma_packed_struct_8(double poison, 
double poison, double poison, double poison, double poison, double poison, 
double poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] 
[[DOTFCA_0_INSERT]])
+// CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr 
[[S_PRAGMA_PACKED_STRUCT_8]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
+// CHECK-NEXT:    call void (double, double, double, double, double, double, 
double, double, double, ...) @variadic_pragma_packed_struct_8(double poison, 
double poison, double poison, double poison, double poison, double poison, 
double poison, double poison, double poison, [1 x <8 x i16>] 
[[DOTFCA_0_INSERT4]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull 
[[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]]
+// CHECK-NEXT:    ret void
+void test_pragma_packed_struct_8() {
+    struct pragma_packed_struct_8 s_pragma_packed_struct_8;
+    init(1, &s_pragma_packed_struct_8);
+
+    named_arg_pragma_packed_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
2.0, s_pragma_packed_struct_8);
+    variadic_pragma_packed_struct_8(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
2.0, s_pragma_packed_struct_8);
+}
+
+struct pragma_packed_struct_4 gs_pragma_packed_struct_4;
+
+// CHECK-LABEL: define dso_local void @named_arg_pragma_packed_struct_4
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double noundef [[D8:%.*]], [1 x <8 x i16>] 
[[S_PRAGMA_PACKED_STRUCT_4_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_PRAGMA_PACKED_STRUCT_4_COERCE_FCA_0_EXTRACT:%.*]] = 
extractvalue [1 x <8 x i16>] [[S_PRAGMA_PACKED_STRUCT_4_COERCE]], 0
+// CHECK-NEXT:    store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]]
+// CHECK-NEXT:    store <8 x i16> 
[[S_PRAGMA_PACKED_STRUCT_4_COERCE_FCA_0_EXTRACT]], ptr 
@gs_pragma_packed_struct_4, align 4, !tbaa.struct [[TBAA_STRUCT6]]
+// CHECK-NEXT:    ret void
+__attribute__((noinline)) void named_arg_pragma_packed_struct_4(double d0, 
double d1, double d2, double d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, struct pragma_packed_struct_4 
s_pragma_packed_struct_4) {
+    gd = d8;
+    gs_pragma_packed_struct_4 = s_pragma_packed_struct_4;
+}
+
+// CHECK-LABEL: define dso_local void @variadic_pragma_packed_struct_4
+// CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], 
double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], 
double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 32, ptr nonnull 
[[VL]]) #[[ATTR6]]
+// CHECK-NEXT:    call void @llvm.va_start(ptr nonnull [[VL]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) 
#[[ATTR6]]
+// CHECK-NEXT:    ret void
+void variadic_pragma_packed_struct_4(double d0, double d1, double d2, double 
d3,
+                                 double d4, double d5, double d6, double d7,
+                                 double d8, ...) {
+  va_list vl;
+  va_start(vl, d8);
+  struct pragma_packed_struct_4 on_callee_stack;
+  on_callee_stack = va_arg(vl, struct pragma_packed_struct_4);
+}
+
+// CHECK-LABEL: define dso_local void @test_pragma_packed_struct_4
+// CHECK-SAME: () local_unnamed_addr #[[ATTR4]] {
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    [[S_PRAGMA_PACKED_STRUCT_4:%.*]] = alloca 
[[STRUCT_PRAGMA_PACKED_STRUCT_4:%.*]], align 16
+// CHECK-NEXT:    call void @llvm.lifetime.start.p0(i64 16, ptr nonnull 
[[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]]
+// CHECK-NEXT:    call void (i32, ...) @init(i32 noundef 1, ptr noundef 
nonnull [[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]]
+// CHECK-NEXT:    [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr 
[[S_PRAGMA_PACKED_STRUCT_4]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD]], 0
+// CHECK-NEXT:    call void @named_arg_pragma_packed_struct_4(double poison, 
double poison, double poison, double poison, double poison, double poison, 
double poison, double poison, double noundef 2.000000e+00, [1 x <8 x i16>] 
[[DOTFCA_0_INSERT]])
+// CHECK-NEXT:    [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr 
[[S_PRAGMA_PACKED_STRUCT_4]], align 16
+// CHECK-NEXT:    [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] 
poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0
+// CHECK-NEXT:    call void (double, double, double, double, double, double, 
double, double, double, ...) @variadic_pragma_packed_struct_4(double poison, 
double poison, double poison, double poison, double poison, double poison, 
double poison, double poison, double poison, [1 x <8 x i16>] 
[[DOTFCA_0_INSERT4]])
+// CHECK-NEXT:    call void @llvm.lifetime.end.p0(i64 16, ptr nonnull 
[[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]]
+// CHECK-NEXT:    ret void
+void test_pragma_packed_struct_4() {
+    struct pragma_packed_struct_4 s_pragma_packed_struct_4;
+    init(1, &s_pragma_packed_struct_4);
+
+    named_arg_pragma_packed_struct_4(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
2.0, s_pragma_packed_struct_4);
+    variadic_pragma_packed_struct_4(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 
2.0, s_pragma_packed_struct_4);
+}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to