198 lines · plain
1; RUN: llc < %s -asm-verbose=false -wasm-keep-registers | FileCheck --check-prefix=CHECK --check-prefix=FINI --check-prefix=NULL %s2 3target triple = "wasm32-unknown-unknown"4 5; Test that @llvm.global_dtors is properly lowered into @llvm.global_ctors,6; grouping dtor calls by priority and associated symbol.7 8declare void @orig_ctor()9declare void @orig_dtor0()10declare void @orig_dtor1a()11declare void @orig_dtor1b()12declare void @orig_dtor1c0()13declare void @orig_dtor1c1a()14declare void @orig_dtor1c1b()15declare void @orig_dtor1c2a()16declare void @orig_dtor1c2b()17declare void @orig_dtor1c3()18declare void @orig_dtor1d()19declare void @orig_dtor65535()20declare void @orig_dtor65535c0()21declare void @after_the_null()22 23@associatedc0 = external global i824@associatedc1 = external global i825@associatedc2 = global i8 4226@associatedc3 = global i8 8427 28@llvm.global_ctors = appending global29[1 x { i32, ptr, ptr }]30[31 { i32, ptr, ptr } { i32 200, ptr @orig_ctor, ptr null }32]33 34@llvm.global_dtors = appending global35[14 x { i32, ptr, ptr }]36[37 { i32, ptr, ptr } { i32 0, ptr @orig_dtor0, ptr null },38 { i32, ptr, ptr } { i32 1, ptr @orig_dtor1a, ptr null },39 { i32, ptr, ptr } { i32 1, ptr @orig_dtor1b, ptr null },40 { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c0, ptr @associatedc0 },41 { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c1a, ptr @associatedc1 },42 { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c1b, ptr @associatedc1 },43 { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c2a, ptr @associatedc2 },44 { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c2b, ptr @associatedc2 },45 { i32, ptr, ptr } { i32 1, ptr @orig_dtor1c3, ptr @associatedc3 },46 { i32, ptr, ptr } { i32 1, ptr @orig_dtor1d, ptr null },47 { i32, ptr, ptr } { i32 65535, ptr @orig_dtor65535c0, ptr @associatedc0 },48 { i32, ptr, ptr } { i32 65535, ptr @orig_dtor65535, ptr null },49 { i32, ptr, ptr } { i32 65535, ptr null, ptr null },50 { i32, ptr, ptr } { i32 65535, ptr @after_the_null, ptr null }51]52 53; CHECK-LABEL: .functype __cxa_atexit (i32, i32, i32) -> (i32){{$}}54 55; CHECK-LABEL: .Lcall_dtors.0:56; CHECK-NEXT: .functype .Lcall_dtors.0 (i32) -> (){{$}}57; CHECK-NEXT: call orig_dtor0{{$}}58 59; CHECK-LABEL: .Lregister_call_dtors.0:60; CHECK: block61; CHECK-NEXT: i32.const $push2=, .Lcall_dtors.0{{$}}62; CHECK-NEXT: i32.const $push1=, 063; CHECK-NEXT: i32.const $push0=, __dso_handle64; CHECK-NEXT: call $push3=, __cxa_atexit, $pop2, $pop1, $pop0{{$}}65; CHECK-NEXT: i32.eqz $push4=, $pop366; CHECK-NEXT: br_if 0, $pop467; CHECK-NEXT: unreachable68; CHECK: end_block69 70; CHECK-LABEL: .Lcall_dtors.1$0:71; CHECK-NEXT: .functype .Lcall_dtors.1$0 (i32) -> (){{$}}72; CHECK-NEXT: call orig_dtor1b{{$}}73; CHECK-NEXT: call orig_dtor1a{{$}}74 75; CHECK-LABEL: .Lregister_call_dtors.1$0:76; CHECK: block77; CHECK-NEXT: i32.const $push2=, .Lcall_dtors.1$0{{$}}78; CHECK-NEXT: i32.const $push1=, 079; CHECK-NEXT: i32.const $push0=, __dso_handle80; CHECK-NEXT: call $push3=, __cxa_atexit, $pop2, $pop1, $pop0{{$}}81; CHECK-NEXT: i32.eqz $push4=, $pop382; CHECK-NEXT: br_if 0, $pop483; CHECK-NEXT: unreachable84; CHECK: end_block85 86; CHECK-LABEL: .Lcall_dtors.1$1.associatedc0:87; CHECK-NEXT: .functype .Lcall_dtors.1$1.associatedc0 (i32) -> (){{$}}88; CHECK-NEXT: call orig_dtor1c0{{$}}89 90; CHECK-LABEL: .Lregister_call_dtors.1$1.associatedc0:91; CHECK: block92; CHECK-NEXT: i32.const $push2=, .Lcall_dtors.1$1.associatedc0{{$}}93; CHECK-NEXT: i32.const $push1=, 094; CHECK-NEXT: i32.const $push0=, __dso_handle95; CHECK-NEXT: call $push3=, __cxa_atexit, $pop2, $pop1, $pop0{{$}}96; CHECK-NEXT: i32.eqz $push4=, $pop397; CHECK-NEXT: br_if 0, $pop498; CHECK-NEXT: unreachable99 100; CHECK-LABEL: .Lcall_dtors.1$2.associatedc1:101; CHECK-NEXT: .functype .Lcall_dtors.1$2.associatedc1 (i32) -> (){{$}}102; CHECK-NEXT: call orig_dtor1c1b{{$}}103; CHECK-NEXT: call orig_dtor1c1a{{$}}104 105; CHECK-LABEL: .Lregister_call_dtors.1$2.associatedc1:106; CHECK: block107; CHECK-NEXT: i32.const $push2=, .Lcall_dtors.1$2.associatedc1{{$}}108; CHECK-NEXT: i32.const $push1=, 0109; CHECK-NEXT: i32.const $push0=, __dso_handle110; CHECK-NEXT: call $push3=, __cxa_atexit, $pop2, $pop1, $pop0{{$}}111; CHECK-NEXT: i32.eqz $push4=, $pop3112; CHECK-NEXT: br_if 0, $pop4113; CHECK-NEXT: unreachable114 115; CHECK-LABEL: .Lcall_dtors.1$3.associatedc2:116; CHECK-NEXT: .functype .Lcall_dtors.1$3.associatedc2 (i32) -> (){{$}}117; CHECK-NEXT: call orig_dtor1c2b{{$}}118; CHECK-NEXT: call orig_dtor1c2a{{$}}119 120; CHECK-LABEL: .Lregister_call_dtors.1$3.associatedc2:121; CHECK: block122; CHECK-NEXT: i32.const $push2=, .Lcall_dtors.1$3.associatedc2{{$}}123; CHECK-NEXT: i32.const $push1=, 0124; CHECK-NEXT: i32.const $push0=, __dso_handle125; CHECK-NEXT: call $push3=, __cxa_atexit, $pop2, $pop1, $pop0{{$}}126; CHECK-NEXT: i32.eqz $push4=, $pop3127; CHECK-NEXT: br_if 0, $pop4128; CHECK-NEXT: unreachable129 130; CHECK-LABEL: .Lcall_dtors.1$4.associatedc3:131; CHECK-NEXT: .functype .Lcall_dtors.1$4.associatedc3 (i32) -> (){{$}}132; CHECK-NEXT: call orig_dtor1c3{{$}}133 134; CHECK-LABEL: .Lregister_call_dtors.1$4.associatedc3:135; CHECK: block136; CHECK-NEXT: i32.const $push2=, .Lcall_dtors.1$4.associatedc3{{$}}137; CHECK-NEXT: i32.const $push1=, 0138; CHECK-NEXT: i32.const $push0=, __dso_handle139; CHECK-NEXT: call $push3=, __cxa_atexit, $pop2, $pop1, $pop0{{$}}140; CHECK-NEXT: i32.eqz $push4=, $pop3141; CHECK-NEXT: br_if 0, $pop4142; CHECK-NEXT: unreachable143 144; CHECK-LABEL: .Lcall_dtors.1$5:145; CHECK-NEXT: .functype .Lcall_dtors.1$5 (i32) -> (){{$}}146; CHECK-NEXT: call orig_dtor1d{{$}}147 148; CHECK-LABEL: .Lregister_call_dtors.1$5:149; CHECK: block150; CHECK-NEXT: i32.const $push2=, .Lcall_dtors.1$5{{$}}151; CHECK-NEXT: i32.const $push1=, 0152; CHECK-NEXT: i32.const $push0=, __dso_handle153; CHECK-NEXT: call $push3=, __cxa_atexit, $pop2, $pop1, $pop0{{$}}154; CHECK-NEXT: i32.eqz $push4=, $pop3155; CHECK-NEXT: br_if 0, $pop4156; CHECK-NEXT: unreachable157 158; CHECK-LABEL: .Lcall_dtors$0.associatedc0:159; CHECK-NEXT: .functype .Lcall_dtors$0.associatedc0 (i32) -> (){{$}}160; CHECK-NEXT: call orig_dtor65535c0161 162; CHECK-LABEL: .Lcall_dtors$1:163; CHECK-NEXT: .functype .Lcall_dtors$1 (i32) -> (){{$}}164; CHECK-NEXT: call orig_dtor65535{{$}}165 166; CHECK-LABEL: .Lregister_call_dtors$1:167; CHECK: block168; CHECK-NEXT: i32.const $push2=, .Lcall_dtors$1{{$}}169; CHECK-NEXT: i32.const $push1=, 0170; CHECK-NEXT: i32.const $push0=, __dso_handle171; CHECK-NEXT: call $push3=, __cxa_atexit, $pop2, $pop1, $pop0{{$}}172; CHECK-NEXT: i32.eqz $push4=, $pop3173; CHECK-NEXT: br_if 0, $pop4174; CHECK-NEXT: unreachable175 176; CHECK-LABEL: .section .init_array.0,"",@177; CHECK: .int32 .Lregister_call_dtors.0{{$}}178; CHECK-LABEL: .section .init_array.1,"",@179; CHECK: .int32 .Lregister_call_dtors.1$0{{$}}180; CHECK-NEXT: .int32 .Lregister_call_dtors.1$3.associatedc2{{$}}181; CHECK-NEXT: .int32 .Lregister_call_dtors.1$4.associatedc3{{$}}182; CHECK-NEXT: .int32 .Lregister_call_dtors.1$5{{$}}183; CHECK-LABEL: .section .init_array.200,"",@184; CHECK: .int32 orig_ctor{{$}}185; CHECK-LABEL: .section .init_array,"",@186; CHECK: .int32 .Lregister_call_dtors$1{{$}}187 188; CHECK-LABEL: .weak __dso_handle189 190; We shouldn't make use of a .fini_array section.191 192; FINI-NOT: fini_array193 194; This function is listed after the null terminator, so it should195; be excluded.196 197; NULL-NOT: after_the_null198