Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / LowerGlobalDestructors / lower-global-dtors.ll
blob94bbd9e495705b6297b13c9d44bdabea86246761
1 ; RUN: opt -passes=lower-global-dtors -S < %s | FileCheck %s --implicit-check-not=llvm.global_dtors
3 ; Test that @llvm.global_dtors is properly lowered into @llvm.global_ctors,
4 ; grouping dtor calls by priority and associated symbol.
6 declare void @orig_ctor()
7 declare void @orig_dtor0()
8 declare void @orig_dtor1a()
9 declare void @orig_dtor1b()
10 declare void @orig_dtor1c0()
11 declare void @orig_dtor1c1a()
12 declare void @orig_dtor1c1b()
13 declare void @orig_dtor1c2a()
14 declare void @orig_dtor1c2b()
15 declare void @orig_dtor1c3()
16 declare void @orig_dtor1d()
17 declare void @orig_dtor65535()
18 declare void @orig_dtor65535c0()
19 declare void @after_the_null()
21 @associatedc0 = external global i8
22 @associatedc1 = external global i8
23 @associatedc2 = global i8 42
24 @associatedc3 = global i8 84
26 @llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [
27   { i32, ptr, ptr } { i32 200, ptr @orig_ctor, ptr null }
30 @llvm.global_dtors = appending global [14 x { i32, ptr, ptr }] [
31   { i32, ptr, ptr } { i32 0, ptr @orig_dtor0, ptr null },
32   { i32, ptr, ptr } { i32 1, ptr @orig_dtor1a, ptr null },
33   { i32, ptr, ptr } { i32 1, ptr @orig_dtor1b, ptr null },
34   { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c0, ptr @associatedc0 },
35   { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c1a, ptr @associatedc1 },
36   { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c1b, ptr @associatedc1 },
37   { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c2a, ptr @associatedc2 },
38   { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c2b, ptr @associatedc2 },
39   { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c3, ptr @associatedc3 },
40   { i32, ptr, ptr } { i32 1, ptr @orig_dtor1d, ptr null },
41   { i32, ptr, ptr } { i32 65535, ptr @orig_dtor65535c0, ptr @associatedc0 },
42   { i32, ptr, ptr } { i32 65535, ptr @orig_dtor65535, ptr null },
43   { i32, ptr, ptr } { i32 65535, ptr null, ptr null },
44   { i32, ptr, ptr } { i32 65535, ptr @after_the_null, ptr null }
47 ; CHECK: @associatedc0 = external global i8
48 ; CHECK: @associatedc1 = external global i8
49 ; CHECK: @associatedc2 = global i8 42
50 ; CHECK: @associatedc3 = global i8 84
51 ; CHECK: @__dso_handle = extern_weak hidden constant i8
53 ; CHECK-LABEL: @llvm.global_ctors = appending global [10 x { i32, ptr, ptr }] [
54 ; CHECK-SAME:  { i32, ptr, ptr } { i32 200, ptr @orig_ctor, ptr null },
55 ; CHECK-SAME:  { i32, ptr, ptr } { i32 0, ptr @register_call_dtors.0, ptr null },
56 ; CHECK-SAME:  { i32, ptr, ptr } { i32 1, ptr @"register_call_dtors.1$0", ptr null },
57 ; CHECK-SAME:  { i32, ptr, ptr } { i32 1, ptr @"register_call_dtors.1$1.associatedc0", ptr @associatedc0 },
58 ; CHECK-SAME:  { i32, ptr, ptr } { i32 1, ptr @"register_call_dtors.1$2.associatedc1", ptr @associatedc1 },
59 ; CHECK-SAME:  { i32, ptr, ptr } { i32 1, ptr @"register_call_dtors.1$3.associatedc2", ptr @associatedc2 },
60 ; CHECK-SAME:  { i32, ptr, ptr } { i32 1, ptr @"register_call_dtors.1$4.associatedc3", ptr @associatedc3 },
61 ; CHECK-SAME:  { i32, ptr, ptr } { i32 1, ptr @"register_call_dtors.1$5", ptr null },
62 ; CHECK-SAME:  { i32, ptr, ptr } { i32 65535, ptr @"register_call_dtors$0.associatedc0", ptr @associatedc0 },
63 ; CHECK-SAME:  { i32, ptr, ptr } { i32 65535, ptr @"register_call_dtors$1", ptr null }]
65 ; CHECK: declare void @orig_ctor()
66 ; CHECK: declare void @orig_dtor0()
67 ; --- other dtors here ---
68 ; CHECK: declare void @after_the_null()
70 ; CHECK: declare i32 @__cxa_atexit(ptr, ptr, ptr)
72 ; CHECK-LABEL: define private void @call_dtors.0(ptr %0)
73 ; CHECK:       call void @orig_dtor0()
74 ; CHECK-NEXT:  ret void
76 ; CHECK-LABEL: define private void @register_call_dtors.0()
77 ; CHECK:       %call = call i32 @__cxa_atexit(ptr @call_dtors.0, ptr null, ptr @__dso_handle)
78 ; CHECK-NEXT:  %0 = icmp ne i32 %call, 0
79 ; CHECK-NEXT:  br i1 %0, label %fail, label %return
80 ; CHECK-EMPTY:
81 ; CHECK-NEXT:  fail:
82 ; CHECK-NEXT:    call void @llvm.trap()
83 ; CHECK-NEXT:    unreachable
84 ; CHECK-EMPTY:
85 ; CHECK-NEXT:  return:
86 ; CHECK-NEXT:    ret void
88 ; CHECK-LABEL: define private void @"call_dtors.1$0"(ptr %0)
89 ; CHECK:       call void @orig_dtor1b()
90 ; CHECK-NEXT:  call void @orig_dtor1a()
91 ; CHECK-NEXT:  ret void
93 ; CHECK-LABEL: define private void @"register_call_dtors.1$0"()
94 ; CHECK:       %call = call i32 @__cxa_atexit(ptr @"call_dtors.1$0", ptr null, ptr @__dso_handle)
96 ; CHECK-LABEL: define private void @"call_dtors.1$1.associatedc0"(ptr %0)
97 ; CHECK:       call void @orig_dtor1c0()
98 ; CHECK-NEXT:  ret void
100 ; CHECK-LABEL: define private void @"register_call_dtors.1$1.associatedc0"()
101 ; CHECK:       %call = call i32 @__cxa_atexit(ptr @"call_dtors.1$1.associatedc0", ptr null, ptr @__dso_handle)
103 ; CHECK-LABEL: define private void @"call_dtors.1$2.associatedc1"(ptr %0)
104 ; CHECK:       call void @orig_dtor1c1b()
105 ; CHECK-NEXT:  call void @orig_dtor1c1a()
106 ; CHECK-NEXT:  ret void
108 ; CHECK-LABEL: define private void @"register_call_dtors.1$2.associatedc1"()
109 ; CHECK:       %call = call i32 @__cxa_atexit(ptr @"call_dtors.1$2.associatedc1", ptr null, ptr @__dso_handle)
111 ; CHECK-LABEL: define private void @"call_dtors.1$3.associatedc2"(ptr %0)
112 ; CHECK:       call void @orig_dtor1c2b()
113 ; CHECK-NEXT:  call void @orig_dtor1c2a()
114 ; CHECK-NEXT:  ret void
116 ; CHECK-LABEL: define private void @"register_call_dtors.1$3.associatedc2"()
117 ; CHECK:       %call = call i32 @__cxa_atexit(ptr @"call_dtors.1$3.associatedc2", ptr null, ptr @__dso_handle)
119 ; CHECK-LABEL: define private void @"call_dtors.1$4.associatedc3"(ptr %0)
120 ; CHECK:       call void @orig_dtor1c3()
121 ; CHECK-NEXT:  ret void
123 ; CHECK-LABEL: define private void @"register_call_dtors.1$4.associatedc3"()
124 ; CHECK:       %call = call i32 @__cxa_atexit(ptr @"call_dtors.1$4.associatedc3", ptr null, ptr @__dso_handle)
126 ; CHECK-LABEL: define private void @"call_dtors.1$5"(ptr %0)
127 ; CHECK:       call void @orig_dtor1d()
128 ; CHECK-NEXT:  ret void
130 ; CHECK-LABEL: define private void @"register_call_dtors.1$5"()
131 ; CHECK:       %call = call i32 @__cxa_atexit(ptr @"call_dtors.1$5", ptr null, ptr @__dso_handle)
133 ; CHECK-LABEL: define private void @"call_dtors$0.associatedc0"(ptr %0)
134 ; CHECK:       call void @orig_dtor65535c0()
135 ; CHECK-NEXT:  ret void
137 ; CHECK-LABEL: define private void @"register_call_dtors$0.associatedc0"()
138 ; CHECK:       %call = call i32 @__cxa_atexit(ptr @"call_dtors$0.associatedc0", ptr null, ptr @__dso_handle)
140 ; CHECK-LABEL: define private void @"call_dtors$1"(ptr %0)
141 ; CHECK:       call void @orig_dtor65535()
142 ; CHECK-NEXT:  ret void
144 ; CHECK-LABEL: define private void @"register_call_dtors$1"()
145 ; CHECK:       %call = call i32 @__cxa_atexit(ptr @"call_dtors$1", ptr null, ptr @__dso_handle)
148 ; This function is listed after the null terminator, so it should
149 ; be excluded.
151 ; CHECK-NOT: after_the_null