1 // RUN: %clang_cc1 -no-opaque-pointers -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm \ 2 // RUN: -fno-use-cxa-atexit < %s | \ 3 // RUN: FileCheck --check-prefix=NO-REGISTER %s 4 // RUN: %clang_cc1 -no-opaque-pointers -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm \ 5 // RUN: -fno-use-cxa-atexit < %s | \ 6 // RUN: FileCheck --check-prefix=NO-REGISTER %s 7 8 // RUN: %clang_cc1 -no-opaque-pointers -triple powerpc-ibm-aix-xcoff -x c++ -emit-llvm \ 9 // RUN: -fno-use-cxa-atexit -fregister-global-dtors-with-atexit < %s | \ 10 // RUN: FileCheck --check-prefix=REGISTER %s 11 // RUN: %clang_cc1 -no-opaque-pointers -triple powerpc64-ibm-aix-xcoff -x c++ -emit-llvm \ 12 // RUN: -fno-use-cxa-atexit -fregister-global-dtors-with-atexit < %s | \ 13 // RUN: FileCheck --check-prefix=REGISTER %s 14 15 struct test { 16 test(); 17 ~test(); 18 } t; 19 20 int bar() __attribute__((destructor(100))); 21 int bar2() __attribute__((destructor(65535))); 22 int bar3(int) __attribute__((destructor(65535))); 23 24 int bar() { 25 return 1; 26 } 27 28 int bar2() { 29 return 2; 30 } 31 32 int bar3(int a) { 33 return a; 34 } 35 36 // NO-REGISTER: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I__, i8* null }] 37 // NO-REGISTER: @llvm.global_dtors = appending global [4 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 100, void ()* bitcast (i32 ()* @_Z3barv to void ()*), i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* bitcast (i32 ()* @_Z4bar2v to void ()*), i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* bitcast (i32 (i32)* @_Z4bar3i to void ()*), i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__D_a, i8* null }] 38 39 // REGISTER: @llvm.global_ctors = appending global [3 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I__, i8* null }, { i32, void ()*, i8* } { i32 100, void ()* @__GLOBAL_init_100, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__GLOBAL_init_65535, i8* null }] 40 // REGISTER: @llvm.global_dtors = appending global [3 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__D_a, i8* null }, { i32, void ()*, i8* } { i32 100, void ()* @__GLOBAL_cleanup_100, i8* null }, { i32, void ()*, i8* } { i32 65535, void ()* @__GLOBAL_cleanup_65535, i8* null }] 41 42 // REGISTER: define internal void @__GLOBAL_init_100() [[ATTR:#[0-9]+]] { 43 // REGISTER: entry: 44 // REGISTER: %0 = call i32 @atexit(void ()* bitcast (i32 ()* @_Z3barv to void ()*)) 45 // REGISTER: ret void 46 // REGISTER: } 47 48 // REGISTER: define internal void @__GLOBAL_init_65535() [[ATTR:#[0-9]+]] { 49 // REGISTER: entry: 50 // REGISTER: %0 = call i32 @atexit(void ()* bitcast (i32 ()* @_Z4bar2v to void ()*)) 51 // REGISTER: %1 = call i32 @atexit(void ()* bitcast (i32 (i32)* @_Z4bar3i to void ()*)) 52 // REGISTER: ret void 53 // REGISTER: } 54 55 // REGISTER: define internal void @__GLOBAL_cleanup_100() [[ATTR:#[0-9]+]] { 56 // REGISTER: entry: 57 // REGISTER: %0 = call i32 @unatexit(void ()* bitcast (i32 ()* @_Z3barv to void ()*)) 58 // REGISTER: %needs_destruct = icmp eq i32 %0, 0 59 // REGISTER: br i1 %needs_destruct, label %destruct.call, label %destruct.end 60 61 // REGISTER: destruct.call: 62 // REGISTER: call void bitcast (i32 ()* @_Z3barv to void ()*)() 63 // REGISTER: br label %destruct.end 64 65 // REGISTER: destruct.end: 66 // REGISTER: ret void 67 // REGISTER: } 68 69 // REGISTER: define internal void @__GLOBAL_cleanup_65535() [[ATTR:#[0-9]+]] { 70 // REGISTER: entry: 71 // REGISTER: %0 = call i32 @unatexit(void ()* bitcast (i32 (i32)* @_Z4bar3i to void ()*)) 72 // REGISTER: %needs_destruct = icmp eq i32 %0, 0 73 // REGISTER: br i1 %needs_destruct, label %destruct.call, label %unatexit.call 74 75 // REGISTER: destruct.call: 76 // REGISTER: call void bitcast (i32 (i32)* @_Z4bar3i to void ()*)() 77 // REGISTER: br label %unatexit.call 78 79 // REGISTER: unatexit.call: 80 // REGISTER: %1 = call i32 @unatexit(void ()* bitcast (i32 ()* @_Z4bar2v to void ()*)) 81 // REGISTER: %needs_destruct1 = icmp eq i32 %1, 0 82 // REGISTER: br i1 %needs_destruct1, label %destruct.call2, label %destruct.end 83 84 // REGISTER: destruct.call2: 85 // REGISTER: call void bitcast (i32 ()* @_Z4bar2v to void ()*)() 86 // REGISTER: br label %destruct.end 87 88 // REGISTER: destruct.end: 89 // REGISTER: ret void 90 // REGISTER: } 91