1*62774658Syabinc // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --version 5 2*62774658Syabinc // RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=gnu11 -verify -emit-llvm %s -o - | FileCheck %s 3*62774658Syabinc // expected-no-diagnostics 4*62774658Syabinc 5*62774658Syabinc union U1 { 6*62774658Syabinc int x; 7*62774658Syabinc char y[5]; 8*62774658Syabinc }; 9*62774658Syabinc 10*62774658Syabinc struct S1 { 11*62774658Syabinc int x; 12*62774658Syabinc long long y; 13*62774658Syabinc }; 14*62774658Syabinc 15*62774658Syabinc struct S2 { 16*62774658Syabinc unsigned char b1 : 3; // 1st 3 bits (in 1st byte) are b1 17*62774658Syabinc unsigned char : 2; // next 2 bits (in 1st byte) are blocked out as unused 18*62774658Syabinc unsigned char b2 : 6; // 6 bits for b2 - doesn't fit into the 1st byte => starts a 2nd 19*62774658Syabinc unsigned char b3 : 2; // 2 bits for b3 - next (and final) bits in the 2nd byte 20*62774658Syabinc int i; 21*62774658Syabinc }; 22*62774658Syabinc 23*62774658Syabinc struct S3 { 24*62774658Syabinc int x; 25*62774658Syabinc } __attribute__((__aligned__(8))); 26*62774658Syabinc 27*62774658Syabinc struct S4 { 28*62774658Syabinc int a; 29*62774658Syabinc union U1 b; 30*62774658Syabinc }; 31*62774658Syabinc 32*62774658Syabinc struct S5 { 33*62774658Syabinc char x; 34*62774658Syabinc unsigned char y : 4; 35*62774658Syabinc unsigned char z : 7; 36*62774658Syabinc } __attribute__((packed)); 37*62774658Syabinc 38*62774658Syabinc // Test non-const initializer for union with padding. 39*62774658Syabinc // CHECK-LABEL: define dso_local void @test1( 40*62774658Syabinc // CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { 41*62774658Syabinc // CHECK-NEXT: [[ENTRY:.*:]] 42*62774658Syabinc // CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 43*62774658Syabinc // CHECK-NEXT: [[A:%.*]] = alloca [[UNION_U1:%.*]], align 4 44*62774658Syabinc // CHECK-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 45*62774658Syabinc // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 46*62774658Syabinc // CHECK-NEXT: store i32 [[TMP0]], ptr [[A]], align 4 47*62774658Syabinc // CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[A]], i64 4 48*62774658Syabinc // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP1]], i8 0, i64 4, i1 false) 49*62774658Syabinc // CHECK-NEXT: ret void 50*62774658Syabinc // 51*62774658Syabinc void test1(int x) { 52*62774658Syabinc union U1 a = {x}; 53*62774658Syabinc } 54*62774658Syabinc 55*62774658Syabinc // Test non-const initializer for struct with padding. 56*62774658Syabinc // CHECK-LABEL: define dso_local void @test2( 57*62774658Syabinc // CHECK-SAME: i64 noundef [[Y:%.*]]) #[[ATTR0]] { 58*62774658Syabinc // CHECK-NEXT: [[ENTRY:.*:]] 59*62774658Syabinc // CHECK-NEXT: [[Y_ADDR:%.*]] = alloca i64, align 8 60*62774658Syabinc // CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S1:%.*]], align 8 61*62774658Syabinc // CHECK-NEXT: store i64 [[Y]], ptr [[Y_ADDR]], align 8 62*62774658Syabinc // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds nuw [[STRUCT_S1]], ptr [[S]], i32 0, i32 0 63*62774658Syabinc // CHECK-NEXT: store i32 0, ptr [[X]], align 8 64*62774658Syabinc // CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, ptr [[S]], i64 4 65*62774658Syabinc // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP0]], i8 0, i64 4, i1 false) 66*62774658Syabinc // CHECK-NEXT: [[Y1:%.*]] = getelementptr inbounds nuw [[STRUCT_S1]], ptr [[S]], i32 0, i32 1 67*62774658Syabinc // CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr [[Y_ADDR]], align 8 68*62774658Syabinc // CHECK-NEXT: store i64 [[TMP1]], ptr [[Y1]], align 8 69*62774658Syabinc // CHECK-NEXT: ret void 70*62774658Syabinc // 71*62774658Syabinc void test2(long long y) { 72*62774658Syabinc struct S1 s = {.y = y}; 73*62774658Syabinc } 74*62774658Syabinc 75*62774658Syabinc // Test non-const initializer for struct with padding and bit fields. 76*62774658Syabinc // CHECK-LABEL: define dso_local void @test3( 77*62774658Syabinc // CHECK-SAME: i8 noundef zeroext [[B:%.*]]) #[[ATTR0]] { 78*62774658Syabinc // CHECK-NEXT: [[ENTRY:.*:]] 79*62774658Syabinc // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i8, align 1 80*62774658Syabinc // CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S2:%.*]], align 4 81*62774658Syabinc // CHECK-NEXT: store i8 [[B]], ptr [[B_ADDR]], align 1 82*62774658Syabinc // CHECK-NEXT: store i16 0, ptr [[S]], align 4 83*62774658Syabinc // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[B_ADDR]], align 1 84*62774658Syabinc // CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[TMP0]] to i16 85*62774658Syabinc // CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[S]], align 4 86*62774658Syabinc // CHECK-NEXT: [[BF_VALUE:%.*]] = and i16 [[TMP1]], 7 87*62774658Syabinc // CHECK-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -8 88*62774658Syabinc // CHECK-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], [[BF_VALUE]] 89*62774658Syabinc // CHECK-NEXT: store i16 [[BF_SET]], ptr [[S]], align 4 90*62774658Syabinc // CHECK-NEXT: [[BF_LOAD1:%.*]] = load i16, ptr [[S]], align 4 91*62774658Syabinc // CHECK-NEXT: [[BF_CLEAR2:%.*]] = and i16 [[BF_LOAD1]], -16129 92*62774658Syabinc // CHECK-NEXT: [[BF_SET3:%.*]] = or i16 [[BF_CLEAR2]], 0 93*62774658Syabinc // CHECK-NEXT: store i16 [[BF_SET3]], ptr [[S]], align 4 94*62774658Syabinc // CHECK-NEXT: [[BF_LOAD4:%.*]] = load i16, ptr [[S]], align 4 95*62774658Syabinc // CHECK-NEXT: [[BF_CLEAR5:%.*]] = and i16 [[BF_LOAD4]], 16383 96*62774658Syabinc // CHECK-NEXT: [[BF_SET6:%.*]] = or i16 [[BF_CLEAR5]], 0 97*62774658Syabinc // CHECK-NEXT: store i16 [[BF_SET6]], ptr [[S]], align 4 98*62774658Syabinc // CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[S]], i64 2 99*62774658Syabinc // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 2 [[TMP2]], i8 0, i64 2, i1 false) 100*62774658Syabinc // CHECK-NEXT: [[I:%.*]] = getelementptr inbounds nuw [[STRUCT_S2]], ptr [[S]], i32 0, i32 1 101*62774658Syabinc // CHECK-NEXT: store i32 0, ptr [[I]], align 4 102*62774658Syabinc // CHECK-NEXT: ret void 103*62774658Syabinc // 104*62774658Syabinc void test3(unsigned char b) { 105*62774658Syabinc struct S2 s = {.b1 = b}; 106*62774658Syabinc } 107*62774658Syabinc 108*62774658Syabinc // Test non-const initializer for struct with padding at the end of the struct. 109*62774658Syabinc // CHECK-LABEL: define dso_local void @test4( 110*62774658Syabinc // CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0]] { 111*62774658Syabinc // CHECK-NEXT: [[ENTRY:.*:]] 112*62774658Syabinc // CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 113*62774658Syabinc // CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S3:%.*]], align 8 114*62774658Syabinc // CHECK-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 115*62774658Syabinc // CHECK-NEXT: [[X1:%.*]] = getelementptr inbounds nuw [[STRUCT_S3]], ptr [[S]], i32 0, i32 0 116*62774658Syabinc // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 117*62774658Syabinc // CHECK-NEXT: store i32 [[TMP0]], ptr [[X1]], align 8 118*62774658Syabinc // CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i64 4 119*62774658Syabinc // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP1]], i8 0, i64 4, i1 false) 120*62774658Syabinc // CHECK-NEXT: ret void 121*62774658Syabinc // 122*62774658Syabinc void test4(int x) { 123*62774658Syabinc struct S3 s = {x}; 124*62774658Syabinc } 125*62774658Syabinc 126*62774658Syabinc // Test non-const initializer for union in struct. 127*62774658Syabinc // CHECK-LABEL: define dso_local void @test5( 128*62774658Syabinc // CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]]) #[[ATTR0]] { 129*62774658Syabinc // CHECK-NEXT: [[ENTRY:.*:]] 130*62774658Syabinc // CHECK-NEXT: [[A_ADDR:%.*]] = alloca i32, align 4 131*62774658Syabinc // CHECK-NEXT: [[B_ADDR:%.*]] = alloca i32, align 4 132*62774658Syabinc // CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S4:%.*]], align 4 133*62774658Syabinc // CHECK-NEXT: store i32 [[A]], ptr [[A_ADDR]], align 4 134*62774658Syabinc // CHECK-NEXT: store i32 [[B]], ptr [[B_ADDR]], align 4 135*62774658Syabinc // CHECK-NEXT: [[A1:%.*]] = getelementptr inbounds nuw [[STRUCT_S4]], ptr [[S]], i32 0, i32 0 136*62774658Syabinc // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A_ADDR]], align 4 137*62774658Syabinc // CHECK-NEXT: store i32 [[TMP0]], ptr [[A1]], align 4 138*62774658Syabinc // CHECK-NEXT: [[B2:%.*]] = getelementptr inbounds nuw [[STRUCT_S4]], ptr [[S]], i32 0, i32 1 139*62774658Syabinc // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[B_ADDR]], align 4 140*62774658Syabinc // CHECK-NEXT: store i32 [[TMP1]], ptr [[B2]], align 4 141*62774658Syabinc // CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[B2]], i64 4 142*62774658Syabinc // CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 4 [[TMP2]], i8 0, i64 4, i1 false) 143*62774658Syabinc // CHECK-NEXT: ret void 144*62774658Syabinc // 145*62774658Syabinc void test5(int a, int b) { 146*62774658Syabinc struct S4 s = {a, {b}}; 147*62774658Syabinc } 148*62774658Syabinc 149*62774658Syabinc // CHECK-LABEL: define dso_local void @test6( 150*62774658Syabinc // CHECK-SAME: i8 noundef signext [[X:%.*]]) #[[ATTR0]] { 151*62774658Syabinc // CHECK-NEXT: [[ENTRY:.*:]] 152*62774658Syabinc // CHECK-NEXT: [[X_ADDR:%.*]] = alloca i8, align 1 153*62774658Syabinc // CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S5:%.*]], align 1 154*62774658Syabinc // CHECK-NEXT: store i8 [[X]], ptr [[X_ADDR]], align 1 155*62774658Syabinc // CHECK-NEXT: [[X1:%.*]] = getelementptr inbounds nuw [[STRUCT_S5]], ptr [[S]], i32 0, i32 0 156*62774658Syabinc // CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[X_ADDR]], align 1 157*62774658Syabinc // CHECK-NEXT: store i8 [[TMP0]], ptr [[X1]], align 1 158*62774658Syabinc // CHECK-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[S]], i64 1 159*62774658Syabinc // CHECK-NEXT: store i16 0, ptr [[TMP1]], align 1 160*62774658Syabinc // CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds nuw [[STRUCT_S5]], ptr [[S]], i32 0, i32 1 161*62774658Syabinc // CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[Y]], align 1 162*62774658Syabinc // CHECK-NEXT: [[BF_CLEAR:%.*]] = and i16 [[BF_LOAD]], -16 163*62774658Syabinc // CHECK-NEXT: [[BF_SET:%.*]] = or i16 [[BF_CLEAR]], 0 164*62774658Syabinc // CHECK-NEXT: store i16 [[BF_SET]], ptr [[Y]], align 1 165*62774658Syabinc // CHECK-NEXT: [[Z:%.*]] = getelementptr inbounds nuw [[STRUCT_S5]], ptr [[S]], i32 0, i32 1 166*62774658Syabinc // CHECK-NEXT: [[BF_LOAD2:%.*]] = load i16, ptr [[Z]], align 1 167*62774658Syabinc // CHECK-NEXT: [[BF_CLEAR3:%.*]] = and i16 [[BF_LOAD2]], -2033 168*62774658Syabinc // CHECK-NEXT: [[BF_SET4:%.*]] = or i16 [[BF_CLEAR3]], 0 169*62774658Syabinc // CHECK-NEXT: store i16 [[BF_SET4]], ptr [[Z]], align 1 170*62774658Syabinc // CHECK-NEXT: ret void 171*62774658Syabinc // 172*62774658Syabinc void test6(char x) { 173*62774658Syabinc struct S5 s = {.x = x}; 174*62774658Syabinc } 175*62774658Syabinc //. 176*62774658Syabinc // CHECK: attributes #[[ATTR0]] = { noinline nounwind optnone "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+cx8,+mmx,+sse,+sse2,+x87" } 177*62774658Syabinc // CHECK: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } 178*62774658Syabinc //. 179*62774658Syabinc // CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4} 180*62774658Syabinc // CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"} 181*62774658Syabinc //. 182