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