179 lines · plain
1; Test the behavior of GlobalDCE in conjunction with comdats.2;3; RUN: opt < %s -passes=globaldce -S | FileCheck %s4 5; First test checks that if one function in a comdat group is used, both other6; functions and other globals even if unused will be preserved.7$test1_c = comdat any8; CHECK: $test1_c = comdat any9 10; Second test checks that if one function in a comdat group is used, both other11; functions and other globals even if unused will be preserved.12$test2_c = comdat any13; CHECK: $test2_c = comdat any14 15; Third test checks that calling a function in a comdat group with an alias16; preserves the alias.17$test3_c = comdat any18; CHECK: $test3_c = comdat any19 20; Fourth test checks that calling an alias in a comdat group with a function21; preserves the function. (This is the trivial case as the alias uses the22; function.)23$test4_c = comdat any24; CHECK: $test4_c = comdat any25 26; Fifth test checks that calling a function in a comdat group that is used as27; the resolver of an ifunc doesn't preserve that ifunc. ifunc symbols don't28; participate in the comdat group of their resolver function as they are29; considered separate objects.30$test5_c = comdat any31; CHECK: $test5_c = comdat any32 33; Sixth test checks that calling an ifunc whose resolver is in a comdat group34; preserves the resolver. This is the trivial case as the ifunc uses the35; resolver.36$test6_c = comdat any37; CHECK: $test6_c = comdat any38 39; Seventh test checks that we can eliminate a comdat when it has only one dead function participant.40$test7_c = comdat any41; CHECK-NOT: $test7_c = comdat any42 43; Eighth test checks that we can eliminate a comdat when it has only one dead global participant.44$test8_c = comdat any45; CHECK-NOT: $test8_c = comdat any46 47; Ninth test checks that we can eliminate a comdat when there are multiple48; dead participants.49$test9_c = comdat any50; CHECK-NOT: $test9_c = comdat any51 52; Tenth test checks that we can eliminate a comdat when it has multiple53; participants that form internal cyclic uses but are never used externally and54; thus the entire ifunc can safely be eliminated.55$test10_c = comdat any56; CHECK-NOT: $test10_c = comdat any57 58@test1_gv = linkonce_odr unnamed_addr global i32 42, comdat($test1_c)59; CHECK: @test1_gv = linkonce_odr unnamed_addr global60 61@test2_used = linkonce_odr unnamed_addr global i32 42, comdat($test2_c)62; CHECK: @test2_used = linkonce_odr unnamed_addr global63 64@test2_gv = linkonce_odr unnamed_addr global i32 42, comdat($test2_c)65; CHECK: @test2_gv = linkonce_odr unnamed_addr global66 67@test8_gv = linkonce_odr unnamed_addr global i32 42, comdat($test8_c)68; CHECK-NOT: @test8_gv69 70@test9_gv = linkonce_odr unnamed_addr global i32 42, comdat($test9_c)71; CHECK-NOT: @test9_gv72 73@test10_gv = linkonce_odr unnamed_addr global ptr @test10_f, comdat($test10_c)74; CHECK-NOT: @test10_gv75 76@test3_a = linkonce_odr unnamed_addr alias void (), ptr @test3_f77; CHECK: @test3_a = linkonce_odr unnamed_addr alias78 79@test4_a = linkonce_odr unnamed_addr alias void (), ptr @test4_f80; CHECK: @test4_a = linkonce_odr unnamed_addr alias81 82@test10_a = linkonce_odr unnamed_addr alias void (), ptr @test10_g83; CHECK-NOT: @test10_a84 85@test5_if = linkonce_odr ifunc void (), ptr @test5_f86; CHECK-NOT: @test5_if87 88@test6_if = linkonce_odr ifunc void (), ptr @test6_f89; CHECK: @test6_if = linkonce_odr ifunc90 91; This function is directly used and so cannot be eliminated.92define linkonce_odr void @test1_used() comdat($test1_c) {93; CHECK: define linkonce_odr void @test1_used()94entry:95 ret void96}97 98define linkonce_odr void @test1_f() comdat($test1_c) {99; CHECK: define linkonce_odr void @test1_f()100entry:101 ret void102}103 104; Now test that a function, global variable, alias, and ifunc in the same105; comdat are kept.106define linkonce_odr void @test2_f() comdat($test2_c) {107; CHECK: define linkonce_odr void @test2_f()108entry:109 ret void110}111 112define linkonce_odr void @test3_f() comdat($test3_c) {113; CHECK: define linkonce_odr void @test3_f()114entry:115 ret void116}117 118define linkonce_odr void @test4_f() comdat($test4_c) {119; CHECK: define linkonce_odr void @test4_f()120entry:121 ret void122}123 124declare void @test_external()125 126define linkonce_odr ptr @test5_f() comdat($test5_c) {127; CHECK: define linkonce_odr ptr @test5_f()128entry:129 ret ptr @test_external130}131 132define linkonce_odr ptr @test6_f() comdat($test6_c) {133; CHECK: define linkonce_odr ptr @test6_f()134entry:135 ret ptr @test_external136}137 138define linkonce_odr void @test7_f() comdat($test7_c) {139; CHECK-NOT: @test7_f140entry:141 ret void142}143 144define linkonce_odr void @test9_f() comdat($test9_c) {145; CHECK-NOT: @test9_f146entry:147 ret void148}149 150define linkonce_odr void @test10_f() comdat($test10_c) {151; CHECK-NOT: @test10_f152entry:153 %gv = load ptr, ptr @test10_gv154 call void @test10_a()155 ret void156}157 158define linkonce_odr void @test10_g() comdat($test10_c) {159; CHECK-NOT: @test10_g160entry:161 call void @test10_f()162 ret void163}164 165 166; An external function to pin as "used" various things above that shouldn't be167; eliminated.168define void @external_user() {169 call void @test1_used()170 %gv = load i32, ptr @test2_used171 172 call void @test3_f()173 call void @test4_a()174 175 %fptr = call ptr @test5_f()176 call void @test6_if()177 ret void178}179