Home | History | Annotate | Download | only in CodeGen
      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