brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.6 KiB · 364a4dd Raw
277 lines · cpp
1// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOCOMPAT2// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin10 -fclang-abi-compat=6.0 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V6COMPAT3// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-scei-ps4 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V6COMPAT4// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-sie-ps5  | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-V6COMPAT5 6extern int int_source();7extern void int_sink(int x);8 9namespace test0 {10  struct A {11    int aField;12    int bField;13  };14 15  struct B {16    int onebit : 2;17    int twobit : 6;18    int intField;19  };20 21  struct __attribute__((packed, aligned(2))) C : A, B {22  };23 24  // These accesses should have alignment 4 because they're at offset 025  // in a reference with an assumed alignment of 4.26  // CHECK-LABEL: @_ZN5test01aERNS_1BE27  void a(B &b) {28    // CHECK: [[CALL:%.*]] = call noundef i32 @_Z10int_sourcev()29    // CHECK: [[B_P:%.*]] = load ptr, ptr30    // CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i831    // CHECK: [[OLD_VALUE:%.*]] = load i8, ptr [[B_P]], align 432    // CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 333    // CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -434    // CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]35    // CHECK: store i8 [[T2]], ptr [[B_P]], align 436    b.onebit = int_source();37 38    // CHECK: [[B_P:%.*]] = load ptr, ptr39    // CHECK: [[VALUE:%.*]] = load i8, ptr [[B_P]], align 440    // CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 641    // CHECK: [[T1:%.*]] = ashr i8 [[T0]], 642    // CHECK: [[T2:%.*]] = sext i8 [[T1]] to i3243    // CHECK: call void @_Z8int_sinki(i32 noundef [[T2]])44    int_sink(b.onebit);45  }46 47  // These accesses should have alignment 2 because they're at offset 848  // in a reference/pointer with an assumed alignment of 2.49  // CHECK-LABEL: @_ZN5test01bERNS_1CE50  void b(C &c) {51    // CHECK: [[CALL:%.*]] = call noundef i32 @_Z10int_sourcev()52    // CHECK: [[C_P:%.*]] = load ptr, ptr53    // CHECK: [[FIELD_P:%.*]] = getelementptr inbounds i8, ptr [[C_P]], i64 854    // CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i855    // CHECK-V6COMPAT: [[OLD_VALUE:%.*]] = load i8, ptr [[FIELD_P]], align 256    // CHECK-NOCOMPAT: [[OLD_VALUE:%.*]] = load i8, ptr [[FIELD_P]], align 457    // CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 358    // CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -459    // CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]60    // CHECK-V6COMPAT: store i8 [[T2]], ptr [[FIELD_P]], align 261    // CHECK-NOCOMPAT: store i8 [[T2]], ptr [[FIELD_P]], align 462    c.onebit = int_source();63 64    // CHECK: [[C_P:%.*]] = load ptr, ptr65    // CHECK: [[FIELD_P:%.*]] = getelementptr inbounds i8, ptr [[C_P]], i64 866    // CHECK-V6COMPAT: [[VALUE:%.*]] = load i8, ptr [[FIELD_P]], align 267    // CHECK-NOCOMPAT: [[VALUE:%.*]] = load i8, ptr [[FIELD_P]], align 468    // CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 669    // CHECK: [[T1:%.*]] = ashr i8 [[T0]], 670    // CHECK: [[T2:%.*]] = sext i8 [[T1]] to i3271    // CHECK: call void @_Z8int_sinki(i32 noundef [[T2]])72    int_sink(c.onebit);73  }74 75  // CHECK-LABEL: @_ZN5test01cEPNS_1CE76  void c(C *c) {77    // CHECK: [[CALL:%.*]] = call noundef i32 @_Z10int_sourcev()78    // CHECK: [[C_P:%.*]] = load ptr, ptr79    // CHECK: [[FIELD_P:%.*]] = getelementptr inbounds i8, ptr [[C_P]], i64 880    // CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i881    // CHECK-V6COMPAT: [[OLD_VALUE:%.*]] = load i8, ptr [[FIELD_P]], align 282    // CHECK-NOCOMPAT: [[OLD_VALUE:%.*]] = load i8, ptr [[FIELD_P]], align 483    // CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 384    // CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -485    // CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]86    // CHECK-V6COMPAT: store i8 [[T2]], ptr [[FIELD_P]], align 287    // CHECK-NOCOMPAT: store i8 [[T2]], ptr [[FIELD_P]], align 488    c->onebit = int_source();89 90    // CHECK: [[C_P:%.*]] = load ptr, ptr91    // CHECK: [[P:%.*]] = getelementptr inbounds i8, ptr [[C_P]], i64 892    // CHECK-V6COMPAT: [[VALUE:%.*]] = load i8, ptr [[P]], align 293    // CHECK-NOCOMPAT: [[VALUE:%.*]] = load i8, ptr [[P]], align 494    // CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 695    // CHECK: [[T1:%.*]] = ashr i8 [[T0]], 696    // CHECK: [[T2:%.*]] = sext i8 [[T1]] to i3297    // CHECK: call void @_Z8int_sinki(i32 noundef [[T2]])98    int_sink(c->onebit);99  }100 101  // These accesses should have alignment 2 because they're at offset 8102  // in an alignment-2 variable.103  // CHECK-LABEL: @_ZN5test01dEv104  void d() {105    // CHECK-V6COMPAT: [[C_P:%.*]] = alloca [[C:%.*]], align 2106    // CHECK-NOCOMPAT: [[C_P:%.*]] = alloca [[C:%.*]], align 4107    C c;108 109    // CHECK: [[CALL:%.*]] = call noundef i32 @_Z10int_sourcev()110    // CHECK: [[FIELD_P:%.*]] = getelementptr inbounds i8, ptr [[C_P]], i64 8111    // CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i8112    // CHECK-V6COMPAT: [[OLD_VALUE:%.*]] = load i8, ptr [[FIELD_P]], align 2113    // CHECK-NOCOMPAT: [[OLD_VALUE:%.*]] = load i8, ptr [[FIELD_P]], align 4114    // CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 3115    // CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -4116    // CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]117    // CHECK-V6COMPAT: store i8 [[T2]], ptr [[FIELD_P]], align 2118    // CHECK-NOCOMPAT: store i8 [[T2]], ptr [[FIELD_P]], align 4119    c.onebit = int_source();120 121    // CHECK: [[T1:%.*]] = getelementptr inbounds i8, ptr [[C_P]], i64 8122    // CHECK-V6COMPAT: [[VALUE:%.*]] = load i8, ptr [[T1]], align 2123    // CHECK-NOCOMPAT: [[VALUE:%.*]] = load i8, ptr [[T1]], align 4124    // CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 6125    // CHECK: [[T1:%.*]] = ashr i8 [[T0]], 6126    // CHECK: [[T2:%.*]] = sext i8 [[T1]] to i32127    // CHECK: call void @_Z8int_sinki(i32 noundef [[T2]])128    int_sink(c.onebit);129  }130 131  // These accesses should have alignment 8 because they're at offset 8132  // in an alignment-16 variable.133  // CHECK-LABEL: @_ZN5test01eEv134  void e() {135    // CHECK: [[C_P:%.*]] = alloca [[C:%.*]], align 16136    __attribute__((aligned(16))) C c;137 138    // CHECK: [[CALL:%.*]] = call noundef i32 @_Z10int_sourcev()139    // CHECK: [[FIELD_P:%.*]] = getelementptr inbounds i8, ptr [[C_P]], i64 8140    // CHECK: [[TRUNC:%.*]] = trunc i32 [[CALL]] to i8141    // CHECK: [[OLD_VALUE:%.*]] = load i8, ptr [[FIELD_P]], align 8142    // CHECK: [[T0:%.*]] = and i8 [[TRUNC]], 3143    // CHECK: [[T1:%.*]] = and i8 [[OLD_VALUE]], -4144    // CHECK: [[T2:%.*]] = or i8 [[T1]], [[T0]]145    // CHECK: store i8 [[T2]], ptr [[FIELD_P]], align 8146    c.onebit = int_source();147 148    // CHECK: [[T1:%.*]] = getelementptr inbounds i8, ptr [[C_P]], i64 8149    // CHECK: [[VALUE:%.*]] = load i8, ptr [[T1]], align 8150    // CHECK: [[T0:%.*]] = shl i8 [[VALUE]], 6151    // CHECK: [[T1:%.*]] = ashr i8 [[T0]], 6152    // CHECK: [[T2:%.*]] = sext i8 [[T1]] to i32153    // CHECK: call void @_Z8int_sinki(i32 noundef [[T2]])154    int_sink(c.onebit);155  }156}157 158namespace test1 {159  struct Array {160    int elts[4];161  };162 163  struct A {164    __attribute__((aligned(16))) Array aArray;165  };166 167  struct B : virtual A {168    void *bPointer; // puts bArray at offset 16169    Array bArray;170  };171 172  struct C : virtual A { // must be viable as primary base173    // Non-empty, nv-size not a multiple of 16.174    void *cPointer1;175    void *cPointer2;176  };177 178  // Proof of concept that the non-virtual components of B do not have179  // to be 16-byte-aligned.180  struct D : C, B {};181 182  // For the following tests, we want to assign into a variable whose183  // alignment is high enough that it will absolutely not be the184  // constraint on the memcpy alignment.185  typedef __attribute__((aligned(64))) Array AlignedArray;186 187  // CHECK-LABEL: @_ZN5test11aERNS_1AE188  void a(A &a) {189    // CHECK: [[RESULT:%.*]] = alloca [[ARRAY:%.*]], align 64190    // CHECK: [[A_P:%.*]] = load ptr, ptr191    // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds nuw [[A:%.*]], ptr [[A_P]], i32 0, i32 0192    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 64 [[RESULT]], ptr align 16 [[ARRAY_P]], i64 16, i1 false)193    AlignedArray result = a.aArray;194  }195 196  // CHECK-LABEL: @_ZN5test11bERNS_1BE197  void b(B &b) {198    // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64199    // CHECK: [[B_P:%.*]] = load ptr, ptr200    // CHECK: [[VPTR:%.*]] = load ptr, ptr [[B_P]], align 8201    // CHECK: [[T0:%.*]] = getelementptr i8, ptr [[VPTR]], i64 -24202    // CHECK: [[OFFSET:%.*]] = load i64, ptr [[T0]], align 8203    // CHECK: [[T1:%.*]] = getelementptr inbounds i8, ptr [[B_P]], i64 [[OFFSET]]204    // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds nuw [[A]], ptr [[T1]], i32 0, i32 0205    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 64 [[RESULT]], ptr align 16 [[ARRAY_P]], i64 16, i1 false)206    AlignedArray result = b.aArray;207  }208 209  // CHECK-LABEL: @_ZN5test11cERNS_1BE210  void c(B &b) {211    // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64212    // CHECK: [[B_P:%.*]] = load ptr, ptr213    // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds nuw [[B:%.*]], ptr [[B_P]], i32 0, i32 2214    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 64 [[RESULT]], ptr align 8 [[ARRAY_P]], i64 16, i1 false)215    AlignedArray result = b.bArray;216  }217 218  // CHECK-LABEL: @_ZN5test11dEPNS_1BE219  void d(B *b) {220    // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64221    // CHECK: [[B_P:%.*]] = load ptr, ptr222    // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds nuw [[B:%.*]], ptr [[B_P]], i32 0, i32 2223    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 64 [[RESULT]], ptr align 8 [[ARRAY_P]], i64 16, i1 false)224    AlignedArray result = b->bArray;225  }226 227  // CHECK-LABEL: @_ZN5test11eEv228  void e() {229    // CHECK: [[B_P:%.*]] = alloca [[B:%.*]], align 16230    // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64231    // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds nuw [[B:%.*]], ptr [[B_P]], i32 0, i32 2232    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 64 [[RESULT]], ptr align 16 [[ARRAY_P]], i64 16, i1 false)233    B b;234    AlignedArray result = b.bArray;235  }236 237  // CHECK-LABEL: @_ZN5test11fEv238  void f() {239    // TODO: we should devirtualize this derived-to-base conversion.240    // CHECK: [[D_P:%.*]] = alloca [[D:%.*]], align 16241    // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64242    // CHECK: [[VPTR:%.*]] = load ptr, ptr [[D_P]], align 16243    // CHECK: [[T0:%.*]] = getelementptr i8, ptr [[VPTR]], i64 -24244    // CHECK: [[OFFSET:%.*]] = load i64, ptr [[T0]], align 8245    // CHECK: [[T1:%.*]] = getelementptr inbounds i8, ptr [[D_P]], i64 [[OFFSET]]246    // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds nuw [[A]], ptr [[T1]], i32 0, i32 0247    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 64 [[RESULT]], ptr align 16 [[ARRAY_P]], i64 16, i1 false)248    D d;249    AlignedArray result = d.aArray;250  }251 252  // CHECK-LABEL: @_ZN5test11gEv253  void g() {254    // CHECK: [[D_P:%.*]] = alloca [[D]], align 16255    // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64256    // CHECK: [[T1:%.*]] = getelementptr inbounds i8, ptr [[D_P]], i64 24257    // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds nuw [[B:%.*]], ptr [[T1]], i32 0, i32 2258    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 64 [[RESULT]], ptr align 8 [[ARRAY_P]], i64 16, i1 false)259    D d;260    AlignedArray result = d.bArray;261  }262 263  // CHECK-LABEL: @_ZN5test11hEPA_NS_1BE264  void h(B (*b)[]) {265    // CHECK: [[RESULT:%.*]] = alloca [[ARRAY]], align 64266    // CHECK: [[B_P:%.*]] = load ptr, ptr267    // CHECK: [[ELEMENT_P:%.*]] = getelementptr inbounds [0 x [[B]]], ptr [[B_P]], i64 0268    // CHECK: [[ARRAY_P:%.*]] = getelementptr inbounds nuw [[B]], ptr [[ELEMENT_P]], i32 0, i32 2269    // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 64 [[RESULT]], ptr align 16 [[ARRAY_P]], i64 16, i1 false)270    AlignedArray result = (*b)->bArray;271  }272}273 274// CHECK-LABEL: @_Z22incomplete_array_derefPA_i275// CHECK: load i32, ptr {{%.*}}, align 4276int incomplete_array_deref(int (*p)[]) { return (*p)[2]; }277