1 // RUN: %clang_cc1 -triple x86_64-unk-unk -emit-llvm -Os -o %t %s 2 // RUN: FileCheck < %t %s 3 4 struct s0 { 5 unsigned int x[2] __attribute__((packed)); 6 }; 7 8 struct s1 { 9 unsigned int x[2] __attribute__((packed)); 10 unsigned int y; 11 unsigned int z __attribute__((packed)); 12 }; 13 14 struct s2 { 15 unsigned int x[2] __attribute__((packed)); 16 unsigned int y __attribute__((packed)); 17 unsigned int z __attribute__((packed)); 18 }; 19 20 struct __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 27 int align0 = __alignof(struct s0); 28 // CHECK: @align1 = local_unnamed_addr global i32 4 29 int align1 = __alignof(struct s1); 30 // CHECK: @align2 = local_unnamed_addr global i32 1 31 int align2 = __alignof(struct s2); 32 // CHECK: @align3 = local_unnamed_addr global i32 1 33 int align3 = __alignof(struct s3); 34 35 // CHECK: @align0_x = local_unnamed_addr global i32 1 36 int align0_x = __alignof(((struct s0*) 0)->x); 37 // 38 // CHECK: @align1_x = local_unnamed_addr global i32 1 39 int align1_x = __alignof(((struct s1*) 0)->x); 40 // CHECK: @align2_x = local_unnamed_addr global i32 1 41 int align2_x = __alignof(((struct s2*) 0)->x); 42 // CHECK: @align3_x = local_unnamed_addr global i32 1 43 int align3_x = __alignof(((struct s3*) 0)->x); 44 45 // CHECK: @align0_x0 = local_unnamed_addr global i32 4 46 int align0_x0 = __alignof(((struct s0*) 0)->x[0]); 47 // CHECK: @align1_x0 = local_unnamed_addr global i32 4 48 int align1_x0 = __alignof(((struct s1*) 0)->x[0]); 49 // CHECK: @align2_x0 = local_unnamed_addr global i32 4 50 int align2_x0 = __alignof(((struct s2*) 0)->x[0]); 51 // CHECK: @align3_x0 = local_unnamed_addr global i32 4 52 int 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: } 60 int f0_a(struct s0 *a) { 61 return a->x[1]; 62 } 63 int 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: } 86 int f1_a(struct s1 *a) { 87 return a->x[1]; 88 } 89 int f1_b(struct s1 *a) { 90 return *(a->x + 1); 91 } 92 int f1_c(struct s1 *a) { 93 return a->y; 94 } 95 int 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: } 111 int f2_a(struct s2 *a) { 112 return a->x[1]; 113 } 114 int f2_b(struct s2 *a) { 115 return *(a->x + 1); 116 } 117 int f2_c(struct s2 *a) { 118 return a->y; 119 } 120 int 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: } 136 int f3_a(struct s3 *a) { 137 return a->x[1]; 138 } 139 int f3_b(struct s3 *a) { 140 return *(a->x + 1); 141 } 142 int f3_c(struct s3 *a) { 143 return a->y; 144 } 145 int 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: } 154 extern double g4[5] __attribute__((aligned(16))); 155 double f4() { 156 return g4[1]; 157 } 158