1*207e5cccSFangrui Song // REQUIRES: aarch64-registered-target 2*207e5cccSFangrui Song // RUN: %clang_cc1 -triple aarch64 -target-feature +neon -emit-llvm -O2 -o - %s | FileCheck %s 3*207e5cccSFangrui Song #include <stdarg.h> 4*207e5cccSFangrui Song #include <arm_neon.h> 5*207e5cccSFangrui Song 6*207e5cccSFangrui Song // natural alignment 16, adjusted alignment 16 7*207e5cccSFangrui Song // expected alignment of copy on callee stack: 16 8*207e5cccSFangrui Song struct non_packed_struct { 9*207e5cccSFangrui Song uint16x8_t M0; // member alignment 16 10*207e5cccSFangrui Song }; 11*207e5cccSFangrui Song 12*207e5cccSFangrui Song // natural alignment 1, adjusted alignment 1 13*207e5cccSFangrui Song // expected alignment of copy on callee stack: 8 14*207e5cccSFangrui Song struct __attribute((packed)) packed_struct { 15*207e5cccSFangrui Song uint16x8_t M0; // member alignment 1, because the field is packed when the struct is packed 16*207e5cccSFangrui Song }; 17*207e5cccSFangrui Song 18*207e5cccSFangrui Song // natural alignment 1, adjusted alignment 1 19*207e5cccSFangrui Song // expected alignment of copy on callee stack: 8 20*207e5cccSFangrui Song struct packed_member { 21*207e5cccSFangrui Song uint16x8_t M0 __attribute((packed)); // member alignment 1 22*207e5cccSFangrui Song }; 23*207e5cccSFangrui Song 24*207e5cccSFangrui Song // natural alignment 16, adjusted alignment 16, despite the 8-byte alignment specified by the attribute, because the natural alignment 25*207e5cccSFangrui Song // for the vector type is 16 and the attribute cannot decrease the minimum required alignment to be less. 26*207e5cccSFangrui Song // expected alignment of copy on callee stack: 16 27*207e5cccSFangrui Song struct __attribute((aligned (8))) aligned_struct_8 { 28*207e5cccSFangrui Song uint16x8_t M0; // member alignment 16 29*207e5cccSFangrui Song }; 30*207e5cccSFangrui Song 31*207e5cccSFangrui Song // natural alignment 16, adjusted alignment 16 32*207e5cccSFangrui Song // expected alignment of copy on callee stack: 16 33*207e5cccSFangrui Song struct aligned_member_8 { 34*207e5cccSFangrui Song uint16x8_t M0 __attribute((aligned (8))); // member alignment 16, despite the 8-byte alignment specified by the attribute, 35*207e5cccSFangrui Song // because the natural alignment for the vector type is 16 and the attribute cannot decrease the minimum required alignment to be less. 36*207e5cccSFangrui Song }; 37*207e5cccSFangrui Song 38*207e5cccSFangrui Song // natural alignment 8, adjusted alignment 8 39*207e5cccSFangrui Song // expected alignment of copy on callee stack: 8 40*207e5cccSFangrui Song #pragma pack(8) 41*207e5cccSFangrui Song struct pragma_packed_struct_8 { 42*207e5cccSFangrui Song uint16x8_t M0; // member alignment 8 because the struct is subject to packed(8) 43*207e5cccSFangrui Song }; 44*207e5cccSFangrui Song 45*207e5cccSFangrui Song // natural alignment 4, adjusted alignment 4 46*207e5cccSFangrui Song // expected alignment of copy on callee stack: 8 47*207e5cccSFangrui Song #pragma pack(4) 48*207e5cccSFangrui Song struct pragma_packed_struct_4 { 49*207e5cccSFangrui Song uint16x8_t M0; // member alignment 4 because the struct is subject to packed(4) 50*207e5cccSFangrui Song }; 51*207e5cccSFangrui Song 52*207e5cccSFangrui Song double gd; 53*207e5cccSFangrui Song void init(int, ...); 54*207e5cccSFangrui Song 55*207e5cccSFangrui Song struct non_packed_struct gs_non_packed_struct; 56*207e5cccSFangrui Song 57*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_non_packed_struct 58*207e5cccSFangrui Song // 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>] alignstack(16) [[S_NON_PACKED_STRUCT_COERCE:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { 59*207e5cccSFangrui Song // CHECK-NEXT: entry: 60*207e5cccSFangrui Song // CHECK-NEXT: [[S_NON_PACKED_STRUCT_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_NON_PACKED_STRUCT_COERCE]], 0 61*207e5cccSFangrui Song // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2:![0-9]+]] 62*207e5cccSFangrui Song // CHECK-NEXT: store <8 x i16> [[S_NON_PACKED_STRUCT_COERCE_FCA_0_EXTRACT]], ptr @gs_non_packed_struct, align 16, !tbaa [[TBAA6:![0-9]+]] 63*207e5cccSFangrui Song // CHECK-NEXT: ret void 64*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_non_packed_struct(double d0, double d1, double d2, double d3, 65*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 66*207e5cccSFangrui Song double d8, struct non_packed_struct s_non_packed_struct) { 67*207e5cccSFangrui Song gd = d8; 68*207e5cccSFangrui Song gs_non_packed_struct = s_non_packed_struct; 69*207e5cccSFangrui Song } 70*207e5cccSFangrui Song 71*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_non_packed_struct 72*207e5cccSFangrui Song // 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]+]] { 73*207e5cccSFangrui Song // CHECK-NEXT: entry: 74*207e5cccSFangrui Song // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8 75*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6:[0-9]+]] 76*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]]) 77*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 78*207e5cccSFangrui Song // CHECK-NEXT: ret void 79*207e5cccSFangrui Song void variadic_non_packed_struct(double d0, double d1, double d2, double d3, 80*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 81*207e5cccSFangrui Song double d8, ...) { 82*207e5cccSFangrui Song va_list vl; 83*207e5cccSFangrui Song va_start(vl, d8); 84*207e5cccSFangrui Song struct non_packed_struct on_callee_stack; 85*207e5cccSFangrui Song on_callee_stack = va_arg(vl, struct non_packed_struct); 86*207e5cccSFangrui Song } 87*207e5cccSFangrui Song 88*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_non_packed_struct 89*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4:[0-9]+]] { 90*207e5cccSFangrui Song // CHECK-NEXT: entry: 91*207e5cccSFangrui Song // CHECK-NEXT: [[S_NON_PACKED_STRUCT:%.*]] = alloca [[STRUCT_NON_PACKED_STRUCT:%.*]], align 16 92*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_NON_PACKED_STRUCT]]) #[[ATTR6]] 93*207e5cccSFangrui Song // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_NON_PACKED_STRUCT]]) #[[ATTR6]] 94*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_NON_PACKED_STRUCT]], align 16 95*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0 96*207e5cccSFangrui Song // 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>] alignstack(16) [[DOTFCA_0_INSERT]]) 97*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_NON_PACKED_STRUCT]], align 16 98*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0 99*207e5cccSFangrui Song // 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>] alignstack(16) [[DOTFCA_0_INSERT4]]) 100*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_NON_PACKED_STRUCT]]) #[[ATTR6]] 101*207e5cccSFangrui Song // CHECK-NEXT: ret void 102*207e5cccSFangrui Song void test_non_packed_struct() { 103*207e5cccSFangrui Song struct non_packed_struct s_non_packed_struct; 104*207e5cccSFangrui Song init(1, &s_non_packed_struct); 105*207e5cccSFangrui Song 106*207e5cccSFangrui Song 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); 107*207e5cccSFangrui Song 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); 108*207e5cccSFangrui Song } 109*207e5cccSFangrui Song 110*207e5cccSFangrui Song struct packed_struct gs_packed_struct; 111*207e5cccSFangrui Song 112*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_packed_struct 113*207e5cccSFangrui Song // 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>] alignstack(8) [[S_PACKED_STRUCT_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { 114*207e5cccSFangrui Song // CHECK-NEXT: entry: 115*207e5cccSFangrui Song // CHECK-NEXT: [[S_PACKED_STRUCT_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_PACKED_STRUCT_COERCE]], 0 116*207e5cccSFangrui Song // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]] 117*207e5cccSFangrui Song // CHECK-NEXT: store <8 x i16> [[S_PACKED_STRUCT_COERCE_FCA_0_EXTRACT]], ptr @gs_packed_struct, align 1, !tbaa [[TBAA6]] 118*207e5cccSFangrui Song // CHECK-NEXT: ret void 119*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_packed_struct(double d0, double d1, double d2, double d3, 120*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 121*207e5cccSFangrui Song double d8, struct packed_struct s_packed_struct) { 122*207e5cccSFangrui Song gd = d8; 123*207e5cccSFangrui Song gs_packed_struct = s_packed_struct; 124*207e5cccSFangrui Song } 125*207e5cccSFangrui Song 126*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_packed_struct 127*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] { 128*207e5cccSFangrui Song // CHECK-NEXT: entry: 129*207e5cccSFangrui Song // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8 130*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 131*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]]) 132*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 133*207e5cccSFangrui Song // CHECK-NEXT: ret void 134*207e5cccSFangrui Song void variadic_packed_struct(double d0, double d1, double d2, double d3, 135*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 136*207e5cccSFangrui Song double d8, ...) { 137*207e5cccSFangrui Song va_list vl; 138*207e5cccSFangrui Song va_start(vl, d8); 139*207e5cccSFangrui Song struct packed_struct on_callee_stack; 140*207e5cccSFangrui Song on_callee_stack = va_arg(vl, struct packed_struct); 141*207e5cccSFangrui Song } 142*207e5cccSFangrui Song 143*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_packed_struct 144*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] { 145*207e5cccSFangrui Song // CHECK-NEXT: entry: 146*207e5cccSFangrui Song // CHECK-NEXT: [[S_PACKED_STRUCT:%.*]] = alloca [[STRUCT_PACKED_STRUCT:%.*]], align 16 147*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PACKED_STRUCT]]) #[[ATTR6]] 148*207e5cccSFangrui Song // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PACKED_STRUCT]]) #[[ATTR6]] 149*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PACKED_STRUCT]], align 16 150*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0 151*207e5cccSFangrui Song // 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>] alignstack(8) [[DOTFCA_0_INSERT]]) 152*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PACKED_STRUCT]], align 16 153*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0 154*207e5cccSFangrui Song // 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>] alignstack(8) [[DOTFCA_0_INSERT4]]) 155*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PACKED_STRUCT]]) #[[ATTR6]] 156*207e5cccSFangrui Song // CHECK-NEXT: ret void 157*207e5cccSFangrui Song void test_packed_struct() { 158*207e5cccSFangrui Song struct packed_struct s_packed_struct; 159*207e5cccSFangrui Song init(1, &s_packed_struct); 160*207e5cccSFangrui Song 161*207e5cccSFangrui Song 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); 162*207e5cccSFangrui Song variadic_packed_struct(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_packed_struct); 163*207e5cccSFangrui Song } 164*207e5cccSFangrui Song 165*207e5cccSFangrui Song struct packed_member gs_packed_member; 166*207e5cccSFangrui Song 167*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_packed_member 168*207e5cccSFangrui Song // 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>] alignstack(8) [[S_PACKED_MEMBER_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { 169*207e5cccSFangrui Song // CHECK-NEXT: entry: 170*207e5cccSFangrui Song // CHECK-NEXT: [[S_PACKED_MEMBER_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_PACKED_MEMBER_COERCE]], 0 171*207e5cccSFangrui Song // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]] 172*207e5cccSFangrui Song // CHECK-NEXT: store <8 x i16> [[S_PACKED_MEMBER_COERCE_FCA_0_EXTRACT]], ptr @gs_packed_member, align 1, !tbaa [[TBAA6]] 173*207e5cccSFangrui Song // CHECK-NEXT: ret void 174*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_packed_member(double d0, double d1, double d2, double d3, 175*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 176*207e5cccSFangrui Song double d8, struct packed_member s_packed_member) { 177*207e5cccSFangrui Song gd = d8; 178*207e5cccSFangrui Song gs_packed_member = s_packed_member; 179*207e5cccSFangrui Song } 180*207e5cccSFangrui Song 181*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_packed_member 182*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] { 183*207e5cccSFangrui Song // CHECK-NEXT: entry: 184*207e5cccSFangrui Song // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8 185*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 186*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]]) 187*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 188*207e5cccSFangrui Song // CHECK-NEXT: ret void 189*207e5cccSFangrui Song void variadic_packed_member(double d0, double d1, double d2, double d3, 190*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 191*207e5cccSFangrui Song double d8, ...) { 192*207e5cccSFangrui Song va_list vl; 193*207e5cccSFangrui Song va_start(vl, d8); 194*207e5cccSFangrui Song struct packed_member on_callee_stack; 195*207e5cccSFangrui Song on_callee_stack = va_arg(vl, struct packed_member); 196*207e5cccSFangrui Song } 197*207e5cccSFangrui Song 198*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_packed_member 199*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] { 200*207e5cccSFangrui Song // CHECK-NEXT: entry: 201*207e5cccSFangrui Song // CHECK-NEXT: [[S_PACKED_MEMBER:%.*]] = alloca [[STRUCT_PACKED_MEMBER:%.*]], align 16 202*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PACKED_MEMBER]]) #[[ATTR6]] 203*207e5cccSFangrui Song // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PACKED_MEMBER]]) #[[ATTR6]] 204*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PACKED_MEMBER]], align 16 205*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0 206*207e5cccSFangrui Song // 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>] alignstack(8) [[DOTFCA_0_INSERT]]) 207*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PACKED_MEMBER]], align 16 208*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0 209*207e5cccSFangrui Song // 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>] alignstack(8) [[DOTFCA_0_INSERT4]]) 210*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PACKED_MEMBER]]) #[[ATTR6]] 211*207e5cccSFangrui Song // CHECK-NEXT: ret void 212*207e5cccSFangrui Song void test_packed_member() { 213*207e5cccSFangrui Song struct packed_member s_packed_member; 214*207e5cccSFangrui Song init(1, &s_packed_member); 215*207e5cccSFangrui Song 216*207e5cccSFangrui Song 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); 217*207e5cccSFangrui Song variadic_packed_member(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, s_packed_member); 218*207e5cccSFangrui Song } 219*207e5cccSFangrui Song 220*207e5cccSFangrui Song struct aligned_struct_8 gs_aligned_struct_8; 221*207e5cccSFangrui Song 222*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_aligned_struct_8 223*207e5cccSFangrui Song // 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>] alignstack(16) [[S_ALIGNED_STRUCT_8_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { 224*207e5cccSFangrui Song // CHECK-NEXT: entry: 225*207e5cccSFangrui Song // CHECK-NEXT: [[S_ALIGNED_STRUCT_8_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_ALIGNED_STRUCT_8_COERCE]], 0 226*207e5cccSFangrui Song // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]] 227*207e5cccSFangrui Song // CHECK-NEXT: store <8 x i16> [[S_ALIGNED_STRUCT_8_COERCE_FCA_0_EXTRACT]], ptr @gs_aligned_struct_8, align 16, !tbaa [[TBAA6]] 228*207e5cccSFangrui Song // CHECK-NEXT: ret void 229*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_aligned_struct_8(double d0, double d1, double d2, double d3, 230*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 231*207e5cccSFangrui Song double d8, struct aligned_struct_8 s_aligned_struct_8) { 232*207e5cccSFangrui Song gd = d8; 233*207e5cccSFangrui Song gs_aligned_struct_8 = s_aligned_struct_8; 234*207e5cccSFangrui Song } 235*207e5cccSFangrui Song 236*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_aligned_struct_8 237*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] { 238*207e5cccSFangrui Song // CHECK-NEXT: entry: 239*207e5cccSFangrui Song // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8 240*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 241*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]]) 242*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 243*207e5cccSFangrui Song // CHECK-NEXT: ret void 244*207e5cccSFangrui Song void variadic_aligned_struct_8(double d0, double d1, double d2, double d3, 245*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 246*207e5cccSFangrui Song double d8, ...) { 247*207e5cccSFangrui Song va_list vl; 248*207e5cccSFangrui Song va_start(vl, d8); 249*207e5cccSFangrui Song struct aligned_struct_8 on_callee_stack; 250*207e5cccSFangrui Song on_callee_stack = va_arg(vl, struct aligned_struct_8); 251*207e5cccSFangrui Song } 252*207e5cccSFangrui Song 253*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_aligned_struct_8 254*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] { 255*207e5cccSFangrui Song // CHECK-NEXT: entry: 256*207e5cccSFangrui Song // CHECK-NEXT: [[S_ALIGNED_STRUCT_8:%.*]] = alloca [[STRUCT_ALIGNED_STRUCT_8:%.*]], align 16 257*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_ALIGNED_STRUCT_8]]) #[[ATTR6]] 258*207e5cccSFangrui Song // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_ALIGNED_STRUCT_8]]) #[[ATTR6]] 259*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_STRUCT_8]], align 16 260*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0 261*207e5cccSFangrui Song // 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>] alignstack(16) [[DOTFCA_0_INSERT]]) 262*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_STRUCT_8]], align 16 263*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0 264*207e5cccSFangrui Song // 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>] alignstack(16) [[DOTFCA_0_INSERT4]]) 265*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_ALIGNED_STRUCT_8]]) #[[ATTR6]] 266*207e5cccSFangrui Song // CHECK-NEXT: ret void 267*207e5cccSFangrui Song void test_aligned_struct_8() { 268*207e5cccSFangrui Song struct aligned_struct_8 s_aligned_struct_8; 269*207e5cccSFangrui Song init(1, &s_aligned_struct_8); 270*207e5cccSFangrui Song 271*207e5cccSFangrui Song 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); 272*207e5cccSFangrui Song 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); 273*207e5cccSFangrui Song } 274*207e5cccSFangrui Song 275*207e5cccSFangrui Song struct aligned_member_8 gs_aligned_member_8; 276*207e5cccSFangrui Song 277*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_aligned_member_8 278*207e5cccSFangrui Song // 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>] alignstack(16) [[S_ALIGNED_MEMBER_8_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { 279*207e5cccSFangrui Song // CHECK-NEXT: entry: 280*207e5cccSFangrui Song // CHECK-NEXT: [[S_ALIGNED_MEMBER_8_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_ALIGNED_MEMBER_8_COERCE]], 0 281*207e5cccSFangrui Song // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]] 282*207e5cccSFangrui Song // CHECK-NEXT: store <8 x i16> [[S_ALIGNED_MEMBER_8_COERCE_FCA_0_EXTRACT]], ptr @gs_aligned_member_8, align 16, !tbaa [[TBAA6]] 283*207e5cccSFangrui Song // CHECK-NEXT: ret void 284*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_aligned_member_8(double d0, double d1, double d2, double d3, 285*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 286*207e5cccSFangrui Song double d8, struct aligned_member_8 s_aligned_member_8) { 287*207e5cccSFangrui Song gd = d8; 288*207e5cccSFangrui Song gs_aligned_member_8 = s_aligned_member_8; 289*207e5cccSFangrui Song } 290*207e5cccSFangrui Song 291*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_aligned_member_8 292*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] { 293*207e5cccSFangrui Song // CHECK-NEXT: entry: 294*207e5cccSFangrui Song // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8 295*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 296*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]]) 297*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 298*207e5cccSFangrui Song // CHECK-NEXT: ret void 299*207e5cccSFangrui Song void variadic_aligned_member_8(double d0, double d1, double d2, double d3, 300*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 301*207e5cccSFangrui Song double d8, ...) { 302*207e5cccSFangrui Song va_list vl; 303*207e5cccSFangrui Song va_start(vl, d8); 304*207e5cccSFangrui Song struct aligned_member_8 on_callee_stack; 305*207e5cccSFangrui Song on_callee_stack = va_arg(vl, struct aligned_member_8); 306*207e5cccSFangrui Song } 307*207e5cccSFangrui Song 308*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_aligned_member_8 309*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] { 310*207e5cccSFangrui Song // CHECK-NEXT: entry: 311*207e5cccSFangrui Song // CHECK-NEXT: [[S_ALIGNED_MEMBER_8:%.*]] = alloca [[STRUCT_ALIGNED_MEMBER_8:%.*]], align 16 312*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_ALIGNED_MEMBER_8]]) #[[ATTR6]] 313*207e5cccSFangrui Song // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_ALIGNED_MEMBER_8]]) #[[ATTR6]] 314*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_MEMBER_8]], align 16 315*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0 316*207e5cccSFangrui Song // 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>] alignstack(16) [[DOTFCA_0_INSERT]]) 317*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_ALIGNED_MEMBER_8]], align 16 318*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0 319*207e5cccSFangrui Song // 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>] alignstack(16) [[DOTFCA_0_INSERT4]]) 320*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_ALIGNED_MEMBER_8]]) #[[ATTR6]] 321*207e5cccSFangrui Song // CHECK-NEXT: ret void 322*207e5cccSFangrui Song void test_aligned_member_8() { 323*207e5cccSFangrui Song struct aligned_member_8 s_aligned_member_8; 324*207e5cccSFangrui Song init(1, &s_aligned_member_8); 325*207e5cccSFangrui Song 326*207e5cccSFangrui Song 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); 327*207e5cccSFangrui Song 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); 328*207e5cccSFangrui Song } 329*207e5cccSFangrui Song 330*207e5cccSFangrui Song struct pragma_packed_struct_8 gs_pragma_packed_struct_8; 331*207e5cccSFangrui Song 332*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_pragma_packed_struct_8 333*207e5cccSFangrui Song // 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>] alignstack(8) [[S_PRAGMA_PACKED_STRUCT_8_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { 334*207e5cccSFangrui Song // CHECK-NEXT: entry: 335*207e5cccSFangrui Song // CHECK-NEXT: [[S_PRAGMA_PACKED_STRUCT_8_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_PRAGMA_PACKED_STRUCT_8_COERCE]], 0 336*207e5cccSFangrui Song // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]] 337*207e5cccSFangrui Song // CHECK-NEXT: store <8 x i16> [[S_PRAGMA_PACKED_STRUCT_8_COERCE_FCA_0_EXTRACT]], ptr @gs_pragma_packed_struct_8, align 8, !tbaa [[TBAA6]] 338*207e5cccSFangrui Song // CHECK-NEXT: ret void 339*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_pragma_packed_struct_8(double d0, double d1, double d2, double d3, 340*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 341*207e5cccSFangrui Song double d8, struct pragma_packed_struct_8 s_pragma_packed_struct_8) { 342*207e5cccSFangrui Song gd = d8; 343*207e5cccSFangrui Song gs_pragma_packed_struct_8 = s_pragma_packed_struct_8; 344*207e5cccSFangrui Song } 345*207e5cccSFangrui Song 346*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_pragma_packed_struct_8 347*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] { 348*207e5cccSFangrui Song // CHECK-NEXT: entry: 349*207e5cccSFangrui Song // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8 350*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 351*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]]) 352*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 353*207e5cccSFangrui Song // CHECK-NEXT: ret void 354*207e5cccSFangrui Song void variadic_pragma_packed_struct_8(double d0, double d1, double d2, double d3, 355*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 356*207e5cccSFangrui Song double d8, ...) { 357*207e5cccSFangrui Song va_list vl; 358*207e5cccSFangrui Song va_start(vl, d8); 359*207e5cccSFangrui Song struct pragma_packed_struct_8 on_callee_stack; 360*207e5cccSFangrui Song on_callee_stack = va_arg(vl, struct pragma_packed_struct_8); 361*207e5cccSFangrui Song } 362*207e5cccSFangrui Song 363*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_pragma_packed_struct_8 364*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] { 365*207e5cccSFangrui Song // CHECK-NEXT: entry: 366*207e5cccSFangrui Song // CHECK-NEXT: [[S_PRAGMA_PACKED_STRUCT_8:%.*]] = alloca [[STRUCT_PRAGMA_PACKED_STRUCT_8:%.*]], align 16 367*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]] 368*207e5cccSFangrui Song // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]] 369*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_8]], align 16 370*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0 371*207e5cccSFangrui Song // 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>] alignstack(8) [[DOTFCA_0_INSERT]]) 372*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_8]], align 16 373*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0 374*207e5cccSFangrui Song // 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>] alignstack(8) [[DOTFCA_0_INSERT4]]) 375*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_8]]) #[[ATTR6]] 376*207e5cccSFangrui Song // CHECK-NEXT: ret void 377*207e5cccSFangrui Song void test_pragma_packed_struct_8() { 378*207e5cccSFangrui Song struct pragma_packed_struct_8 s_pragma_packed_struct_8; 379*207e5cccSFangrui Song init(1, &s_pragma_packed_struct_8); 380*207e5cccSFangrui Song 381*207e5cccSFangrui Song 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); 382*207e5cccSFangrui Song 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); 383*207e5cccSFangrui Song } 384*207e5cccSFangrui Song 385*207e5cccSFangrui Song struct pragma_packed_struct_4 gs_pragma_packed_struct_4; 386*207e5cccSFangrui Song 387*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @named_arg_pragma_packed_struct_4 388*207e5cccSFangrui Song // 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>] alignstack(8) [[S_PRAGMA_PACKED_STRUCT_4_COERCE:%.*]]) local_unnamed_addr #[[ATTR0]] { 389*207e5cccSFangrui Song // CHECK-NEXT: entry: 390*207e5cccSFangrui Song // CHECK-NEXT: [[S_PRAGMA_PACKED_STRUCT_4_COERCE_FCA_0_EXTRACT:%.*]] = extractvalue [1 x <8 x i16>] [[S_PRAGMA_PACKED_STRUCT_4_COERCE]], 0 391*207e5cccSFangrui Song // CHECK-NEXT: store double [[D8]], ptr @gd, align 8, !tbaa [[TBAA2]] 392*207e5cccSFangrui Song // CHECK-NEXT: store <8 x i16> [[S_PRAGMA_PACKED_STRUCT_4_COERCE_FCA_0_EXTRACT]], ptr @gs_pragma_packed_struct_4, align 4, !tbaa [[TBAA6]] 393*207e5cccSFangrui Song // CHECK-NEXT: ret void 394*207e5cccSFangrui Song __attribute__((noinline)) void named_arg_pragma_packed_struct_4(double d0, double d1, double d2, double d3, 395*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 396*207e5cccSFangrui Song double d8, struct pragma_packed_struct_4 s_pragma_packed_struct_4) { 397*207e5cccSFangrui Song gd = d8; 398*207e5cccSFangrui Song gs_pragma_packed_struct_4 = s_pragma_packed_struct_4; 399*207e5cccSFangrui Song } 400*207e5cccSFangrui Song 401*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @variadic_pragma_packed_struct_4 402*207e5cccSFangrui Song // CHECK-SAME: (double [[D0:%.*]], double [[D1:%.*]], double [[D2:%.*]], double [[D3:%.*]], double [[D4:%.*]], double [[D5:%.*]], double [[D6:%.*]], double [[D7:%.*]], double [[D8:%.*]], ...) local_unnamed_addr #[[ATTR1]] { 403*207e5cccSFangrui Song // CHECK-NEXT: entry: 404*207e5cccSFangrui Song // CHECK-NEXT: [[VL:%.*]] = alloca [[STRUCT___VA_LIST:%.*]], align 8 405*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 406*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.va_start.p0(ptr nonnull [[VL]]) 407*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[VL]]) #[[ATTR6]] 408*207e5cccSFangrui Song // CHECK-NEXT: ret void 409*207e5cccSFangrui Song void variadic_pragma_packed_struct_4(double d0, double d1, double d2, double d3, 410*207e5cccSFangrui Song double d4, double d5, double d6, double d7, 411*207e5cccSFangrui Song double d8, ...) { 412*207e5cccSFangrui Song va_list vl; 413*207e5cccSFangrui Song va_start(vl, d8); 414*207e5cccSFangrui Song struct pragma_packed_struct_4 on_callee_stack; 415*207e5cccSFangrui Song on_callee_stack = va_arg(vl, struct pragma_packed_struct_4); 416*207e5cccSFangrui Song } 417*207e5cccSFangrui Song 418*207e5cccSFangrui Song // CHECK-LABEL: define dso_local void @test_pragma_packed_struct_4 419*207e5cccSFangrui Song // CHECK-SAME: () local_unnamed_addr #[[ATTR4]] { 420*207e5cccSFangrui Song // CHECK-NEXT: entry: 421*207e5cccSFangrui Song // CHECK-NEXT: [[S_PRAGMA_PACKED_STRUCT_4:%.*]] = alloca [[STRUCT_PRAGMA_PACKED_STRUCT_4:%.*]], align 16 422*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]] 423*207e5cccSFangrui Song // CHECK-NEXT: call void (i32, ...) @init(i32 noundef 1, ptr noundef nonnull [[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]] 424*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_4]], align 16 425*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD]], 0 426*207e5cccSFangrui Song // 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>] alignstack(8) [[DOTFCA_0_INSERT]]) 427*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_LOAD3:%.*]] = load <8 x i16>, ptr [[S_PRAGMA_PACKED_STRUCT_4]], align 16 428*207e5cccSFangrui Song // CHECK-NEXT: [[DOTFCA_0_INSERT4:%.*]] = insertvalue [1 x <8 x i16>] poison, <8 x i16> [[DOTFCA_0_LOAD3]], 0 429*207e5cccSFangrui Song // 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>] alignstack(8) [[DOTFCA_0_INSERT4]]) 430*207e5cccSFangrui Song // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 16, ptr nonnull [[S_PRAGMA_PACKED_STRUCT_4]]) #[[ATTR6]] 431*207e5cccSFangrui Song // CHECK-NEXT: ret void 432*207e5cccSFangrui Song void test_pragma_packed_struct_4() { 433*207e5cccSFangrui Song struct pragma_packed_struct_4 s_pragma_packed_struct_4; 434*207e5cccSFangrui Song init(1, &s_pragma_packed_struct_4); 435*207e5cccSFangrui Song 436*207e5cccSFangrui Song 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); 437*207e5cccSFangrui Song 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); 438*207e5cccSFangrui Song } 439*207e5cccSFangrui Song //. 440*207e5cccSFangrui Song // CHECK: [[TBAA2]] = !{[[META3:![0-9]+]], [[META3]], i64 0} 441*207e5cccSFangrui Song // CHECK: [[META3]] = !{!"double", [[META4:![0-9]+]], i64 0} 442*207e5cccSFangrui Song // CHECK: [[META4]] = !{!"omnipotent char", [[META5:![0-9]+]], i64 0} 443*207e5cccSFangrui Song // CHECK: [[META5]] = !{!"Simple C/C++ TBAA"} 444*207e5cccSFangrui Song // CHECK: [[TBAA6]] = !{[[META4]], [[META4]], i64 0} 445*207e5cccSFangrui Song //. 446