1 ; Test the behavior of GlobalDCE in conjunction with comdats. 2 ; 3 ; RUN: opt < %s -globaldce -S | FileCheck %s 4 5 ; First test checks that if one function in a comdat group is used, both other 6 ; functions and other globals even if unused will be preserved. 7 $test1_c = comdat any 8 ; CHECK: $test1_c = comdat any 9 10 ; Second test checks that if one function in a comdat group is used, both other 11 ; functions and other globals even if unused will be preserved. 12 $test2_c = comdat any 13 ; CHECK: $test2_c = comdat any 14 15 ; Third test checks that calling a function in a comdat group with an alias 16 ; preserves the alias. 17 $test3_c = comdat any 18 ; CHECK: $test3_c = comdat any 19 20 ; Fourth test checks that calling an alias in a comdat group with a function 21 ; preserves the function. (This is the trivial case as the alias uses the 22 ; function.) 23 $test4_c = comdat any 24 ; CHECK: $test4_c = comdat any 25 26 ; Fifth test checks that calling a function in a comdat group that is used as 27 ; the resolver of an ifunc doesn't preserve that ifunc. ifunc symbols don't 28 ; participate in the comdat group of their resolver function as they are 29 ; considered separate objects. 30 $test5_c = comdat any 31 ; CHECK: $test5_c = comdat any 32 33 ; Sixth test checks that calling an ifunc whose resolver is in a comdat group 34 ; preserves the resolver. This is the trivial case as the ifunc uses the 35 ; resolver. 36 $test6_c = comdat any 37 ; CHECK: $test6_c = comdat any 38 39 ; Seventh test checks that we can eliminate a comdat when it has only one dead function participant. 40 $test7_c = comdat any 41 ; CHECK-NOT: $test7_c = comdat any 42 43 ; Eighth test checks that we can eliminate a comdat when it has only one dead global participant. 44 $test8_c = comdat any 45 ; CHECK-NOT: $test8_c = comdat any 46 47 ; Ninth test checks that we can eliminate a comdat when there are multiple 48 ; dead participants. 49 $test9_c = comdat any 50 ; CHECK-NOT: $test9_c = comdat any 51 52 ; Tenth test checks that we can eliminate a comdat when it has multiple 53 ; participants that form internal cyclic uses but are never used externally and 54 ; thus the entire ifunc can safely be eliminated. 55 $test10_c = comdat any 56 ; CHECK-NOT: $test10_c = comdat any 57 58 @test1_gv = linkonce_odr unnamed_addr global i32 42, comdat($test1_c) 59 ; CHECK: @test1_gv = linkonce_odr unnamed_addr global 60 61 @test2_used = linkonce_odr unnamed_addr global i32 42, comdat($test2_c) 62 ; CHECK: @test2_used = linkonce_odr unnamed_addr global 63 64 @test2_gv = linkonce_odr unnamed_addr global i32 42, comdat($test2_c) 65 ; CHECK: @test2_gv = linkonce_odr unnamed_addr global 66 67 @test8_gv = linkonce_odr unnamed_addr global i32 42, comdat($test8_c) 68 ; CHECK-NOT: @test8_gv 69 70 @test9_gv = linkonce_odr unnamed_addr global i32 42, comdat($test9_c) 71 ; CHECK-NOT: @test9_gv 72 73 @test10_gv = linkonce_odr unnamed_addr global void ()* @test10_f, comdat($test10_c) 74 ; CHECK-NOT: @test10_gv 75 76 @test3_a = linkonce_odr unnamed_addr alias void (), void ()* @test3_f 77 ; CHECK: @test3_a = linkonce_odr unnamed_addr alias 78 79 @test4_a = linkonce_odr unnamed_addr alias void (), void ()* @test4_f 80 ; CHECK: @test4_a = linkonce_odr unnamed_addr alias 81 82 @test10_a = linkonce_odr unnamed_addr alias void (), void ()* @test10_g 83 ; CHECK-NOT: @test10_a 84 85 @test5_if = linkonce_odr ifunc void (), void ()* ()* @test5_f 86 ; CHECK-NOT: @test5_if 87 88 @test6_if = linkonce_odr ifunc void (), void ()* ()* @test6_f 89 ; CHECK: @test6_if = linkonce_odr ifunc 90 91 ; This function is directly used and so cannot be eliminated. 92 define linkonce_odr void @test1_used() comdat($test1_c) { 93 ; CHECK: define linkonce_odr void @test1_used() 94 entry: 95 ret void 96 } 97 98 define linkonce_odr void @test1_f() comdat($test1_c) { 99 ; CHECK: define linkonce_odr void @test1_f() 100 entry: 101 ret void 102 } 103 104 ; Now test that a function, global variable, alias, and ifunc in the same 105 ; comdat are kept. 106 define linkonce_odr void @test2_f() comdat($test2_c) { 107 ; CHECK: define linkonce_odr void @test2_f() 108 entry: 109 ret void 110 } 111 112 define linkonce_odr void @test3_f() comdat($test3_c) { 113 ; CHECK: define linkonce_odr void @test3_f() 114 entry: 115 ret void 116 } 117 118 define linkonce_odr void @test4_f() comdat($test4_c) { 119 ; CHECK: define linkonce_odr void @test4_f() 120 entry: 121 ret void 122 } 123 124 declare void @test_external() 125 126 define linkonce_odr void ()* @test5_f() comdat($test5_c) { 127 ; CHECK: define linkonce_odr void ()* @test5_f() 128 entry: 129 ret void ()* @test_external 130 } 131 132 define linkonce_odr void ()* @test6_f() comdat($test6_c) { 133 ; CHECK: define linkonce_odr void ()* @test6_f() 134 entry: 135 ret void ()* @test_external 136 } 137 138 define linkonce_odr void @test7_f() comdat($test7_c) { 139 ; CHECK-NOT: @test7_f 140 entry: 141 ret void 142 } 143 144 define linkonce_odr void @test9_f() comdat($test9_c) { 145 ; CHECK-NOT: @test9_f 146 entry: 147 ret void 148 } 149 150 define linkonce_odr void @test10_f() comdat($test10_c) { 151 ; CHECK-NOT: @test10_f 152 entry: 153 %gv = load void ()*, void ()** @test10_gv 154 call void @test10_a() 155 ret void 156 } 157 158 define linkonce_odr void @test10_g() comdat($test10_c) { 159 ; CHECK-NOT: @test10_g 160 entry: 161 call void @test10_f() 162 ret void 163 } 164 165 166 ; An external function to pin as "used" various things above that shouldn't be 167 ; eliminated. 168 define void @external_user() { 169 call void @test1_used() 170 %gv = load i32, i32* @test2_used 171 172 call void @test3_f() 173 call void @test4_a() 174 175 %fptr = call void() *@test5_f() 176 call void @test6_if() 177 ret void 178 } 179