brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.3 KiB · 06a93d1 Raw
320 lines · cpp
1// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -fstrict-vtable-pointers -o - %s \2// RUN: | FileCheck --check-prefixes=CHECK,CHECK-STRICT %s3// RUN: %clang_cc1 -triple=x86_64-linux-gnu -emit-llvm -o - %s \4// RUN: | FileCheck --check-prefixes=CHECK,CHECK-NONSTRICT %s5 6//===----------------------------------------------------------------------===//7//                            Positive Cases8//===----------------------------------------------------------------------===//9 10struct TestVirtualFn {11  virtual void foo() {}12};13 14// CHECK-LABEL: define{{.*}} void @test_builtin_launder_virtual_fn15extern "C" void test_builtin_launder_virtual_fn(TestVirtualFn *p) {16  // CHECK: store ptr %p, ptr %p.addr17  // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr %p.addr18 19  // CHECK-NONSTRICT-NEXT: store ptr [[TMP0]], ptr %d20 21  // CHECK-STRICT-NEXT: [[TMP2:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[TMP0]])22  // CHECK-STRICT-NEXT: store ptr [[TMP2]], ptr %d23 24  // CHECK-NEXT: ret void25  TestVirtualFn *d = __builtin_launder(p);26}27 28struct TestPolyBase : TestVirtualFn {29};30 31// CHECK-LABEL: define{{.*}} void @test_builtin_launder_poly_base32extern "C" void test_builtin_launder_poly_base(TestPolyBase *p) {33  // CHECK-STRICT-NOT: ret void34  // CHECK-STRICT: @llvm.launder.invariant.group35 36  // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group37 38  // CHECK: ret void39  TestPolyBase *d = __builtin_launder(p);40}41 42struct TestBase {};43struct TestVirtualBase : virtual TestBase {};44 45// CHECK-LABEL: define{{.*}} void @test_builtin_launder_virtual_base46extern "C" void test_builtin_launder_virtual_base(TestVirtualBase *p) {47  // CHECK-STRICT-NOT: ret void48  // CHECK-STRICT: @llvm.launder.invariant.group49 50  // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group51 52  // CHECK: ret void53  TestVirtualBase *d = __builtin_launder(p);54}55 56//===----------------------------------------------------------------------===//57//                            Negative Cases58//===----------------------------------------------------------------------===//59 60// CHECK-LABEL: define{{.*}} void @test_builtin_launder_ommitted_one61extern "C" void test_builtin_launder_ommitted_one(int *p) {62  // CHECK: entry63  // CHECK-NEXT: %p.addr = alloca ptr64  // CHECK-NEXT: %d = alloca ptr65  // CHECK-NEXT: store ptr %p, ptr %p.addr, align 866  // CHECK-NEXT: [[TMP:%.*]] = load ptr, ptr %p.addr67  // CHECK-NEXT: store ptr [[TMP]], ptr %d68  // CHECK-NEXT: ret void69  int *d = __builtin_launder(p);70}71 72struct TestNoInvariant {73  int x;74};75 76// CHECK-LABEL: define{{.*}} void @test_builtin_launder_ommitted_two77extern "C" void test_builtin_launder_ommitted_two(TestNoInvariant *p) {78  // CHECK: entry79  // CHECK-NOT: llvm.launder.invariant.group80  // CHECK-NEXT: %p.addr = alloca ptr, align 881  // CHECK-NEXT: %d = alloca ptr82  // CHECK-NEXT: store ptr %p, ptr %p.addr83  // CHECK-NEXT: [[TMP:%.*]] = load ptr, ptr %p.addr84  // CHECK-NEXT: store ptr [[TMP]], ptr %d85  // CHECK-NEXT: ret void86  TestNoInvariant *d = __builtin_launder(p);87}88 89struct TestVirtualMember {90  TestVirtualFn member;91};92 93// CHECK-LABEL: define{{.*}} void @test_builtin_launder_virtual_member94extern "C" void test_builtin_launder_virtual_member(TestVirtualMember *p) {95  // CHECK: entry96  // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group97  // CHECK-STRICT: @llvm.launder.invariant.group98  // CHECK: ret void99  TestVirtualMember *d = __builtin_launder(p);100}101 102struct TestVirtualMemberDepth2 {103  TestVirtualMember member;104};105 106// CHECK-LABEL: define{{.*}} void @test_builtin_launder_virtual_member_depth_2107extern "C" void test_builtin_launder_virtual_member_depth_2(TestVirtualMemberDepth2 *p) {108  // CHECK: entry109  // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group110  // CHECK-STRICT: @llvm.launder.invariant.group111  // CHECK: ret void112  TestVirtualMemberDepth2 *d = __builtin_launder(p);113}114 115struct TestVirtualReferenceMember {116  TestVirtualFn &member;117};118 119// CHECK-LABEL: define{{.*}} void @test_builtin_launder_virtual_reference_member120extern "C" void test_builtin_launder_virtual_reference_member(TestVirtualReferenceMember *p) {121  // CHECK: entry122  // CHECK-NOT: @llvm.launder.invariant.group123  // CHECK: ret void124  TestVirtualReferenceMember *d = __builtin_launder(p);125}126 127struct TestRecursiveMember {128  TestRecursiveMember() : member(*this) {}129  TestRecursiveMember &member;130};131 132// CHECK-LABEL: define{{.*}} void @test_builtin_launder_recursive_member133extern "C" void test_builtin_launder_recursive_member(TestRecursiveMember *p) {134  // CHECK: entry135  // CHECK-NOT: @llvm.launder.invariant.group136  // CHECK: ret void137  TestRecursiveMember *d = __builtin_launder(p);138}139 140struct TestVirtualRecursiveMember {141  TestVirtualRecursiveMember() : member(*this) {}142  TestVirtualRecursiveMember &member;143  virtual void foo();144};145 146// CHECK-LABEL: define{{.*}} void @test_builtin_launder_virtual_recursive_member147extern "C" void test_builtin_launder_virtual_recursive_member(TestVirtualRecursiveMember *p) {148  // CHECK: entry149  // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group150  // CHECK-STRICT: @llvm.launder.invariant.group151  // CHECK: ret void152  TestVirtualRecursiveMember *d = __builtin_launder(p);153}154 155// CHECK-LABEL: define{{.*}} void @test_builtin_launder_array(156extern "C" void test_builtin_launder_array(TestVirtualFn (&Arr)[5]) {157  // CHECK: entry158  // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group159  // CHECK-STRICT: @llvm.launder.invariant.group160  // CHECK: ret void161  TestVirtualFn *d = __builtin_launder(Arr);162}163 164// CHECK-LABEL: define{{.*}} void @test_builtin_launder_array_nested(165extern "C" void test_builtin_launder_array_nested(TestVirtualFn (&Arr)[5][2]) {166  // CHECK: entry167  // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group168  // CHECK-STRICT: @llvm.launder.invariant.group169  // CHECK: ret void170  using RetTy = TestVirtualFn(*)[2];171  RetTy d = __builtin_launder(Arr);172}173 174// CHECK-LABEL: define{{.*}} void @test_builtin_launder_array_no_invariant(175extern "C" void test_builtin_launder_array_no_invariant(TestNoInvariant (&Arr)[5]) {176  // CHECK: entry177  // CHECK-NOT: @llvm.launder.invariant.group178  // CHECK: ret void179  TestNoInvariant *d = __builtin_launder(Arr);180}181 182// CHECK-LABEL: define{{.*}} void @test_builtin_launder_array_nested_no_invariant(183extern "C" void test_builtin_launder_array_nested_no_invariant(TestNoInvariant (&Arr)[5][2]) {184  // CHECK: entry185  // CHECK-NOT: @llvm.launder.invariant.group186  // CHECK: ret void187  using RetTy = TestNoInvariant(*)[2];188  RetTy d = __builtin_launder(Arr);189}190 191template <class Member>192struct WithMember {193  Member mem;194};195 196template struct WithMember<TestVirtualFn[5]>;197 198// CHECK-LABEL: define{{.*}} void @test_builtin_launder_member_array(199extern "C" void test_builtin_launder_member_array(WithMember<TestVirtualFn[5]> *p) {200  // CHECK: entry201  // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group202  // CHECK-STRICT: @llvm.launder.invariant.group203  // CHECK: ret void204  auto *d = __builtin_launder(p);205}206 207template struct WithMember<TestVirtualFn[5][2]>;208 209// CHECK-LABEL: define{{.*}} void @test_builtin_launder_member_array_nested(210extern "C" void test_builtin_launder_member_array_nested(WithMember<TestVirtualFn[5][2]> *p) {211  // CHECK: entry212  // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group213  // CHECK-STRICT: @llvm.launder.invariant.group214  // CHECK: ret void215  auto *d = __builtin_launder(p);216}217 218template struct WithMember<TestNoInvariant[5]>;219 220// CHECK-LABEL: define{{.*}} void @test_builtin_launder_member_array_no_invariant(221extern "C" void test_builtin_launder_member_array_no_invariant(WithMember<TestNoInvariant[5]> *p) {222  // CHECK: entry223  // CHECK-NOT: @llvm.launder.invariant.group224  // CHECK: ret void225  auto *d = __builtin_launder(p);226}227 228template struct WithMember<TestNoInvariant[5][2]>;229 230// CHECK-LABEL: define{{.*}} void @test_builtin_launder_member_array_nested_no_invariant(231extern "C" void test_builtin_launder_member_array_nested_no_invariant(WithMember<TestNoInvariant[5][2]> *p) {232  // CHECK: entry233  // CHECK-NOT: @llvm.launder.invariant.group234  // CHECK: ret void235  auto *d = __builtin_launder(p);236}237 238template <class T>239struct WithBase : T {};240 241template struct WithBase<TestNoInvariant>;242 243// CHECK-LABEL: define{{.*}} void @test_builtin_launder_base_no_invariant(244extern "C" void test_builtin_launder_base_no_invariant(WithBase<TestNoInvariant> *p) {245  // CHECK: entry246  // CHECK-NOT: @llvm.launder.invariant.group247  // CHECK: ret void248  auto *d = __builtin_launder(p);249}250 251template struct WithBase<TestVirtualFn>;252 253// CHECK-LABEL: define{{.*}} void @test_builtin_launder_base(254extern "C" void test_builtin_launder_base(WithBase<TestVirtualFn> *p) {255  // CHECK: entry256  // CHECK-NONSTRICT-NOT: @llvm.launder.invariant.group257  // CHECK-STRICT: @llvm.launder.invariant.group258  // CHECK: ret void259  auto *d = __builtin_launder(p);260}261 262/// The test cases in this namespace technically need to be laundered according263/// to the language in the standard (ie they have const or reference subobjects)264/// but LLVM doesn't currently optimize on these cases -- so Clang emits265/// __builtin_launder as a nop.266///267/// NOTE: Adding optimizations for these cases later is an LTO ABI break. That's268/// probably OK for now -- but is something to keep in mind.269namespace pessimizing_cases {270 271struct TestConstMember {272  const int x;273};274 275// CHECK-LABEL: define{{.*}} void @test_builtin_launder_const_member276extern "C" void test_builtin_launder_const_member(TestConstMember *p) {277  // CHECK: entry278  // CHECK-NOT: @llvm.launder.invariant.group279  // CHECK: ret void280  TestConstMember *d = __builtin_launder(p);281}282 283struct TestConstSubobject {284  TestConstMember x;285};286 287// CHECK-LABEL: define{{.*}} void @test_builtin_launder_const_subobject288extern "C" void test_builtin_launder_const_subobject(TestConstSubobject *p) {289  // CHECK: entry290  // CHECK-NOT: @llvm.launder.invariant.group291  // CHECK: ret void292  TestConstSubobject *d = __builtin_launder(p);293}294 295struct TestConstObject {296  const struct TestConstMember x;297};298 299// CHECK-LABEL: define{{.*}} void @test_builtin_launder_const_object300extern "C" void test_builtin_launder_const_object(TestConstObject *p) {301  // CHECK: entry302  // CHECK-NOT: @llvm.launder.invariant.group303  // CHECK: ret void304  TestConstObject *d = __builtin_launder(p);305}306 307struct TestReferenceMember {308  int &x;309};310 311// CHECK-LABEL: define{{.*}} void @test_builtin_launder_reference_member312extern "C" void test_builtin_launder_reference_member(TestReferenceMember *p) {313  // CHECK: entry314  // CHECK-NOT: @llvm.launder.invariant.group315  // CHECK: ret void316  TestReferenceMember *d = __builtin_launder(p);317}318 319} // namespace pessimizing_cases320