1// RUN: %clang_cc1 -triple x86_64-unk-unk -emit-llvm -Os -o %t %s 2// RUN: FileCheck < %t %s 3 4struct s0 { 5 unsigned int x[2] __attribute__((packed)); 6}; 7 8struct s1 { 9 unsigned int x[2] __attribute__((packed)); 10 unsigned int y; 11 unsigned int z __attribute__((packed)); 12}; 13 14struct s2 { 15 unsigned int x[2] __attribute__((packed)); 16 unsigned int y __attribute__((packed)); 17 unsigned int z __attribute__((packed)); 18}; 19 20struct __attribute__((packed)) s3 { 21 unsigned int x[2]; 22 unsigned int y; 23 unsigned int z; 24}; 25 26// CHECK: @align0 = local_unnamed_addr global i32 1 27int align0 = __alignof(struct s0); 28// CHECK: @align1 = local_unnamed_addr global i32 4 29int align1 = __alignof(struct s1); 30// CHECK: @align2 = local_unnamed_addr global i32 1 31int align2 = __alignof(struct s2); 32// CHECK: @align3 = local_unnamed_addr global i32 1 33int align3 = __alignof(struct s3); 34 35// CHECK: @align0_x = local_unnamed_addr global i32 1 36int align0_x = __alignof(((struct s0*) 0)->x); 37// 38// CHECK: @align1_x = local_unnamed_addr global i32 1 39int align1_x = __alignof(((struct s1*) 0)->x); 40// CHECK: @align2_x = local_unnamed_addr global i32 1 41int align2_x = __alignof(((struct s2*) 0)->x); 42// CHECK: @align3_x = local_unnamed_addr global i32 1 43int align3_x = __alignof(((struct s3*) 0)->x); 44 45// CHECK: @align0_x0 = local_unnamed_addr global i32 4 46int align0_x0 = __alignof(((struct s0*) 0)->x[0]); 47// CHECK: @align1_x0 = local_unnamed_addr global i32 4 48int align1_x0 = __alignof(((struct s1*) 0)->x[0]); 49// CHECK: @align2_x0 = local_unnamed_addr global i32 4 50int align2_x0 = __alignof(((struct s2*) 0)->x[0]); 51// CHECK: @align3_x0 = local_unnamed_addr global i32 4 52int align3_x0 = __alignof(((struct s3*) 0)->x[0]); 53 54// CHECK-LABEL: define i32 @f0_a 55// CHECK: load i32, i32* %{{.*}}, align 1 56// CHECK: } 57// CHECK-LABEL: define i32 @f0_b 58// CHECK: load i32, i32* %{{.*}}, align 4 59// CHECK: } 60int f0_a(struct s0 *a) { 61 return a->x[1]; 62} 63int f0_b(struct s0 *a) { 64 return *(a->x + 1); 65} 66 67// Note that 'y' still causes struct s1 to be four-byte aligned. 68 69// Note that we are incompatible with GCC on this example. 70// 71// CHECK-LABEL: define i32 @f1_a 72// CHECK: load i32, i32* %{{.*}}, align 4 73// CHECK: } 74// CHECK-LABEL: define i32 @f1_b 75// CHECK: load i32, i32* %{{.*}}, align 4 76// CHECK: } 77 78// Note that we are incompatible with GCC on this example. 79// 80// CHECK-LABEL: define i32 @f1_c 81// CHECK: load i32, i32* %{{.*}}, align 4 82// CHECK: } 83// CHECK-LABEL: define i32 @f1_d 84// CHECK: load i32, i32* %{{.*}}, align 4 85// CHECK: } 86int f1_a(struct s1 *a) { 87 return a->x[1]; 88} 89int f1_b(struct s1 *a) { 90 return *(a->x + 1); 91} 92int f1_c(struct s1 *a) { 93 return a->y; 94} 95int f1_d(struct s1 *a) { 96 return a->z; 97} 98 99// CHECK-LABEL: define i32 @f2_a 100// CHECK: load i32, i32* %{{.*}}, align 1 101// CHECK: } 102// CHECK-LABEL: define i32 @f2_b 103// CHECK: load i32, i32* %{{.*}}, align 4 104// CHECK: } 105// CHECK-LABEL: define i32 @f2_c 106// CHECK: load i32, i32* %{{.*}}, align 1 107// CHECK: } 108// CHECK-LABEL: define i32 @f2_d 109// CHECK: load i32, i32* %{{.*}}, align 1 110// CHECK: } 111int f2_a(struct s2 *a) { 112 return a->x[1]; 113} 114int f2_b(struct s2 *a) { 115 return *(a->x + 1); 116} 117int f2_c(struct s2 *a) { 118 return a->y; 119} 120int f2_d(struct s2 *a) { 121 return a->z; 122} 123 124// CHECK-LABEL: define i32 @f3_a 125// CHECK: load i32, i32* %{{.*}}, align 1 126// CHECK: } 127// CHECK-LABEL: define i32 @f3_b 128// CHECK: load i32, i32* %{{.*}}, align 4 129// CHECK: } 130// CHECK-LABEL: define i32 @f3_c 131// CHECK: load i32, i32* %{{.*}}, align 1 132// CHECK: } 133// CHECK-LABEL: define i32 @f3_d 134// CHECK: load i32, i32* %{{.*}}, align 1 135// CHECK: } 136int f3_a(struct s3 *a) { 137 return a->x[1]; 138} 139int f3_b(struct s3 *a) { 140 return *(a->x + 1); 141} 142int f3_c(struct s3 *a) { 143 return a->y; 144} 145int f3_d(struct s3 *a) { 146 return a->z; 147} 148 149// Verify we don't claim things are overaligned. 150// 151// CHECK-LABEL: define double @f4 152// CHECK: load double, double* {{.*}}, align 8 153// CHECK: } 154extern double g4[5] __attribute__((aligned(16))); 155double f4() { 156 return g4[1]; 157} 158