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 = global i32 1 27int align0 = __alignof(struct s0); 28// CHECK: @align1 = global i32 4 29int align1 = __alignof(struct s1); 30// CHECK: @align2 = global i32 1 31int align2 = __alignof(struct s2); 32// CHECK: @align3 = global i32 1 33int align3 = __alignof(struct s3); 34 35// CHECK: @align0_x = global i32 1 36int align0_x = __alignof(((struct s0*) 0)->x); 37// 38// CHECK: @align1_x = global i32 1 39int align1_x = __alignof(((struct s1*) 0)->x); 40// CHECK: @align2_x = global i32 1 41int align2_x = __alignof(((struct s2*) 0)->x); 42// CHECK: @align3_x = global i32 1 43int align3_x = __alignof(((struct s3*) 0)->x); 44 45// CHECK: @align0_x0 = global i32 4 46int align0_x0 = __alignof(((struct s0*) 0)->x[0]); 47// CHECK: @align1_x0 = global i32 4 48int align1_x0 = __alignof(((struct s1*) 0)->x[0]); 49// CHECK: @align2_x0 = global i32 4 50int align2_x0 = __alignof(((struct s2*) 0)->x[0]); 51// CHECK: @align3_x0 = 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 we are incompatible with GCC on this example. 68// 69// CHECK-LABEL: define i32 @f1_a 70// CHECK: load i32, i32* %{{.*}}, align 1 71// CHECK: } 72// CHECK-LABEL: define i32 @f1_b 73// CHECK: load i32, i32* %{{.*}}, align 4 74// CHECK: } 75 76// Note that we are incompatible with GCC on this example. 77// 78// CHECK-LABEL: define i32 @f1_c 79// CHECK: load i32, i32* %{{.*}}, align 4 80// CHECK: } 81// CHECK-LABEL: define i32 @f1_d 82// CHECK: load i32, i32* %{{.*}}, align 1 83// CHECK: } 84int f1_a(struct s1 *a) { 85 return a->x[1]; 86} 87int f1_b(struct s1 *a) { 88 return *(a->x + 1); 89} 90int f1_c(struct s1 *a) { 91 return a->y; 92} 93int f1_d(struct s1 *a) { 94 return a->z; 95} 96 97// CHECK-LABEL: define i32 @f2_a 98// CHECK: load i32, i32* %{{.*}}, align 1 99// CHECK: } 100// CHECK-LABEL: define i32 @f2_b 101// CHECK: load i32, i32* %{{.*}}, align 4 102// CHECK: } 103// CHECK-LABEL: define i32 @f2_c 104// CHECK: load i32, i32* %{{.*}}, align 1 105// CHECK: } 106// CHECK-LABEL: define i32 @f2_d 107// CHECK: load i32, i32* %{{.*}}, align 1 108// CHECK: } 109int f2_a(struct s2 *a) { 110 return a->x[1]; 111} 112int f2_b(struct s2 *a) { 113 return *(a->x + 1); 114} 115int f2_c(struct s2 *a) { 116 return a->y; 117} 118int f2_d(struct s2 *a) { 119 return a->z; 120} 121 122// CHECK-LABEL: define i32 @f3_a 123// CHECK: load i32, i32* %{{.*}}, align 1 124// CHECK: } 125// CHECK-LABEL: define i32 @f3_b 126// CHECK: load i32, i32* %{{.*}}, align 4 127// CHECK: } 128// CHECK-LABEL: define i32 @f3_c 129// CHECK: load i32, i32* %{{.*}}, align 1 130// CHECK: } 131// CHECK-LABEL: define i32 @f3_d 132// CHECK: load i32, i32* %{{.*}}, align 1 133// CHECK: } 134int f3_a(struct s3 *a) { 135 return a->x[1]; 136} 137int f3_b(struct s3 *a) { 138 return *(a->x + 1); 139} 140int f3_c(struct s3 *a) { 141 return a->y; 142} 143int f3_d(struct s3 *a) { 144 return a->z; 145} 146 147// Verify we don't claim things are overaligned. 148// 149// CHECK-LABEL: define double @f4 150// CHECK: load double, double* {{.*}}, align 8 151// CHECK: } 152extern double g4[5] __attribute__((aligned(16))); 153double f4() { 154 return g4[1]; 155} 156