1; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s 2 3 4declare void @use_obj16(i16 addrspace(1)*) "gc-leaf-function" 5declare void @use_obj32(i32 addrspace(1)*) "gc-leaf-function" 6declare void @use_obj64(i64 addrspace(1)*) "gc-leaf-function" 7 8declare void @do_safepoint() 9 10define void @test_gep_const(i32 addrspace(1)* %base) gc "statepoint-example" { 11; CHECK-LABEL: test_gep_const 12entry: 13 %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15 14; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15 15 call void @do_safepoint() [ "deopt"() ] 16; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7) 17; CHECK: bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)* 18; CHECK: getelementptr i32, i32 addrspace(1)* %base.relocated.casted, i32 15 19 call void @use_obj32(i32 addrspace(1)* %base) 20 call void @use_obj32(i32 addrspace(1)* %ptr) 21 ret void 22} 23 24define void @test_gep_idx(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" { 25; CHECK-LABEL: test_gep_idx 26entry: 27 %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 %idx 28; CHECK: getelementptr 29 call void @do_safepoint() [ "deopt"() ] 30; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7) 31; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)* 32; CHECK: getelementptr i32, i32 addrspace(1)* %base.relocated.casted, i32 %idx 33 call void @use_obj32(i32 addrspace(1)* %base) 34 call void @use_obj32(i32 addrspace(1)* %ptr) 35 ret void 36} 37 38define void @test_bitcast(i32 addrspace(1)* %base) gc "statepoint-example" { 39; CHECK-LABEL: test_bitcast 40entry: 41 %ptr = bitcast i32 addrspace(1)* %base to i64 addrspace(1)* 42; CHECK: bitcast i32 addrspace(1)* %base to i64 addrspace(1)* 43 call void @do_safepoint() [ "deopt"() ] 44; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7) 45; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)* 46; CHECK: bitcast i32 addrspace(1)* %base.relocated.casted to i64 addrspace(1)* 47 call void @use_obj32(i32 addrspace(1)* %base) 48 call void @use_obj64(i64 addrspace(1)* %ptr) 49 ret void 50} 51 52define void @test_bitcast_bitcast(i32 addrspace(1)* %base) gc "statepoint-example" { 53; CHECK-LABEL: test_bitcast_bitcast 54entry: 55 %ptr1 = bitcast i32 addrspace(1)* %base to i64 addrspace(1)* 56 %ptr2 = bitcast i64 addrspace(1)* %ptr1 to i16 addrspace(1)* 57; CHECK: bitcast i32 addrspace(1)* %base to i64 addrspace(1)* 58; CHECK: bitcast i64 addrspace(1)* %ptr1 to i16 addrspace(1)* 59 call void @do_safepoint() [ "deopt"() ] 60 61; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7) 62; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)* 63; CHECK: bitcast i32 addrspace(1)* %base.relocated.casted to i64 addrspace(1)* 64; CHECK: bitcast i64 addrspace(1)* %ptr1.remat to i16 addrspace(1)* 65 call void @use_obj32(i32 addrspace(1)* %base) 66 call void @use_obj16(i16 addrspace(1)* %ptr2) 67 ret void 68} 69 70define void @test_addrspacecast_addrspacecast(i32 addrspace(1)* %base) gc "statepoint-example" { 71; CHECK-LABEL: test_addrspacecast_addrspacecast 72entry: 73 %ptr1 = addrspacecast i32 addrspace(1)* %base to i32* 74 %ptr2 = addrspacecast i32* %ptr1 to i32 addrspace(1)* 75; CHECK: addrspacecast i32 addrspace(1)* %base to i32* 76; CHECK: addrspacecast i32* %ptr1 to i32 addrspace(1)* 77 call void @do_safepoint() [ "deopt"() ] 78 79; CHECK: %ptr2.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 7) 80; CHECK: %ptr2.relocated.casted = bitcast i8 addrspace(1)* %ptr2.relocated to i32 addrspace(1)* 81; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 8, i32 8) 82; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)* 83 call void @use_obj32(i32 addrspace(1)* %base) 84 call void @use_obj32(i32 addrspace(1)* %ptr2) 85 ret void 86} 87 88define void @test_bitcast_gep(i32 addrspace(1)* %base) gc "statepoint-example" { 89; CHECK-LABEL: test_bitcast_gep 90entry: 91 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 92; CHECK: getelementptr 93; CHECK: bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)* 94 %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)* 95 call void @do_safepoint() [ "deopt"() ] 96 97; CHECK: gc.relocate 98; CHECK: bitcast 99; CHECK: getelementptr 100; CHECK: bitcast 101 call void @use_obj32(i32 addrspace(1)* %base) 102 call void @use_obj64(i64 addrspace(1)* %ptr.cast) 103 ret void 104} 105 106define void @test_intersecting_chains(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" { 107; CHECK-LABEL: test_intersecting_chains 108entry: 109 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 110; CHECK: getelementptr 111 %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)* 112; CHECK: bitcast 113 %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)* 114; CHECK: bitcast 115 call void @do_safepoint() [ "deopt"() ] 116 117; CHECK: getelementptr 118; CHECK: bitcast 119; CHECK: getelementptr 120; CHECK: bitcast 121 call void @use_obj64(i64 addrspace(1)* %ptr.cast) 122 call void @use_obj16(i16 addrspace(1)* %ptr.cast2) 123 ret void 124} 125 126define void @test_cost_threshold(i32 addrspace(1)* %base, i32 %idx1, i32 %idx2, i32 %idx3) gc "statepoint-example" { 127; CHECK-LABEL: test_cost_threshold 128entry: 129 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 130; CHECK: getelementptr 131 %ptr.gep2 = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 %idx1 132; CHECK: getelementptr 133 %ptr.gep3 = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 %idx2 134; CHECK: getelementptr 135 %ptr.gep4 = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 %idx3 136; CHECK: getelementptr 137 %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep4 to i64 addrspace(1)* 138 call void @do_safepoint() [ "deopt"() ] 139 140; CHECK: gc.relocate 141; CHECK: bitcast 142; CHECK: gc.relocate 143; CHECK: bitcast 144 call void @use_obj64(i64 addrspace(1)* %ptr.cast) 145 ret void 146} 147 148define void @test_two_derived(i32 addrspace(1)* %base) gc "statepoint-example" { 149; CHECK-LABEL: test_two_derived 150entry: 151 %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15 152 %ptr2 = getelementptr i32, i32 addrspace(1)* %base, i32 12 153; CHECK: getelementptr 154; CHECK: getelementptr 155 call void @do_safepoint() [ "deopt"() ] 156 157; CHECK: gc.relocate 158; CHECK: bitcast 159; CHECK: getelementptr 160; CHECK: getelementptr 161 call void @use_obj32(i32 addrspace(1)* %ptr) 162 call void @use_obj32(i32 addrspace(1)* %ptr2) 163 ret void 164} 165 166define void @test_gep_smallint_array([3 x i32] addrspace(1)* %base) gc "statepoint-example" { 167; CHECK-LABEL: test_gep_smallint_array 168entry: 169 %ptr = getelementptr [3 x i32], [3 x i32] addrspace(1)* %base, i32 0, i32 2 170; CHECK: getelementptr 171 call void @do_safepoint() [ "deopt"() ] 172 173; CHECK: gc.relocate 174; CHECK: bitcast 175; CHECK: getelementptr 176 call void @use_obj32(i32 addrspace(1)* %ptr) 177 ret void 178} 179 180declare i32 @fake_personality_function() 181 182define void @test_invoke(i32 addrspace(1)* %base) gc "statepoint-example" personality i32 ()* @fake_personality_function { 183; CHECK-LABEL: test_invoke 184entry: 185 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 186; CHECK: getelementptr 187 %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)* 188; CHECK: bitcast 189 %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)* 190; CHECK: bitcast 191 invoke void @do_safepoint() [ "deopt"() ] 192 to label %normal unwind label %exception 193 194normal: 195; CHECK: normal: 196; CHECK: gc.relocate 197; CHECK: bitcast 198; CHECK: getelementptr 199; CHECK: bitcast 200; CHECK: getelementptr 201; CHECK: bitcast 202 call void @use_obj64(i64 addrspace(1)* %ptr.cast) 203 call void @use_obj16(i16 addrspace(1)* %ptr.cast2) 204 ret void 205 206exception: 207; CHECK: exception: 208 %landing_pad4 = landingpad token 209 cleanup 210; CHECK: gc.relocate 211; CHECK: bitcast 212; CHECK: getelementptr 213; CHECK: bitcast 214; CHECK: getelementptr 215; CHECK: bitcast 216 call void @use_obj64(i64 addrspace(1)* %ptr.cast) 217 call void @use_obj16(i16 addrspace(1)* %ptr.cast2) 218 ret void 219} 220 221define void @test_loop(i32 addrspace(1)* %base) gc "statepoint-example" { 222; CHECK-LABEL: test_loop 223entry: 224 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 225; CHECK: getelementptr 226 br label %loop 227 228loop: ; preds = %loop, %entry 229; CHECK: phi i32 addrspace(1)* [ %ptr.gep, %entry ], [ %ptr.gep.remat, %loop ] 230; CHECK: phi i32 addrspace(1)* [ %base, %entry ], [ %base.relocated.casted, %loop ] 231 call void @use_obj32(i32 addrspace(1)* %ptr.gep) 232 call void @do_safepoint() [ "deopt"() ] 233; CHECK: gc.relocate 234; CHECK: bitcast 235; CHECK: getelementptr 236 br label %loop 237} 238 239define void @test_too_long(i32 addrspace(1)* %base) gc "statepoint-example" { 240; CHECK-LABEL: test_too_long 241entry: 242 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 243 %ptr.gep1 = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 15 244 %ptr.gep2 = getelementptr i32, i32 addrspace(1)* %ptr.gep1, i32 15 245 %ptr.gep3 = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 15 246 %ptr.gep4 = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 15 247 %ptr.gep5 = getelementptr i32, i32 addrspace(1)* %ptr.gep4, i32 15 248 %ptr.gep6 = getelementptr i32, i32 addrspace(1)* %ptr.gep5, i32 15 249 %ptr.gep7 = getelementptr i32, i32 addrspace(1)* %ptr.gep6, i32 15 250 %ptr.gep8 = getelementptr i32, i32 addrspace(1)* %ptr.gep7, i32 15 251 %ptr.gep9 = getelementptr i32, i32 addrspace(1)* %ptr.gep8, i32 15 252 %ptr.gep10 = getelementptr i32, i32 addrspace(1)* %ptr.gep9, i32 15 253 %ptr.gep11 = getelementptr i32, i32 addrspace(1)* %ptr.gep10, i32 15 254 call void @do_safepoint() [ "deopt"() ] 255; CHECK: gc.relocate 256; CHECK: bitcast 257; CHECK: gc.relocate 258; CHECK: bitcast 259 call void @use_obj32(i32 addrspace(1)* %ptr.gep11) 260 ret void 261} 262 263 264declare i32 addrspace(1)* @new_instance() nounwind "gc-leaf-function" 265 266; remat the gep in presence of base pointer which is a phi node. 267; FIXME: We should remove the extra basephi.base as well. 268define void @contains_basephi(i1 %cond) gc "statepoint-example" { 269; CHECK-LABEL: contains_basephi 270entry: 271 %base1 = call i32 addrspace(1)* @new_instance() 272 %base2 = call i32 addrspace(1)* @new_instance() 273 br i1 %cond, label %here, label %there 274 275here: 276 br label %merge 277 278there: 279 br label %merge 280 281merge: 282 ; CHECK: %basephi.base = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ], !is_base_value !0 283 ; CHECK: %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ] 284 ; CHECK: %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15 285 ; CHECK: %statepoint_token = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint 286 ; CHECK: %basephi.base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %statepoint_token, i32 7, i32 7) ; (%basephi.base, %basephi.base) 287 ; CHECK: %basephi.base.relocated.casted = bitcast i8 addrspace(1)* %basephi.base.relocated to i32 addrspace(1)* 288 ; CHECK: %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15 289 ; CHECK: call void @use_obj32(i32 addrspace(1)* %ptr.gep.remat) 290 291 292 293 %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ] 294 %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15 295 call void @do_safepoint() ["deopt"() ] 296 call void @use_obj32(i32 addrspace(1)* %ptr.gep) 297 ret void 298} 299 300 301define void @test_intersecting_chains_with_phi(i1 %cond) gc "statepoint-example" { 302; CHECK-LABEL: test_intersecting_chains_with_phi 303entry: 304 %base1 = call i32 addrspace(1)* @new_instance() 305 %base2 = call i32 addrspace(1)* @new_instance() 306 br i1 %cond, label %here, label %there 307 308here: 309 br label %merge 310 311there: 312 br label %merge 313 314merge: 315 %basephi = phi i32 addrspace(1)* [ %base1, %here ], [ %base2, %there ] 316 %ptr.gep = getelementptr i32, i32 addrspace(1)* %basephi, i32 15 317 %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)* 318 %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)* 319 call void @do_safepoint() [ "deopt"() ] 320 ; CHECK: statepoint 321 ; CHECK: %ptr.gep.remat1 = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15 322 ; CHECK: %ptr.cast.remat = bitcast i32 addrspace(1)* %ptr.gep.remat1 to i64 addrspace(1)* 323 ; CHECK: %ptr.gep.remat = getelementptr i32, i32 addrspace(1)* %basephi.base.relocated.casted, i32 15 324 ; CHECK: %ptr.cast2.remat = bitcast i32 addrspace(1)* %ptr.gep.remat to i16 addrspace(1)* 325 ; CHECK: call void @use_obj64(i64 addrspace(1)* %ptr.cast.remat) 326 ; CHECK: call void @use_obj16(i16 addrspace(1)* %ptr.cast2.remat) 327 call void @use_obj64(i64 addrspace(1)* %ptr.cast) 328 call void @use_obj16(i16 addrspace(1)* %ptr.cast2) 329 ret void 330} 331