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