1 ; RUN: opt < %s -rewrite-statepoints-for-gc -S | FileCheck %s 2 3 4 declare void @use_obj16(i16 addrspace(1)*) "gc-leaf-function" 5 declare void @use_obj32(i32 addrspace(1)*) "gc-leaf-function" 6 declare void @use_obj64(i64 addrspace(1)*) "gc-leaf-function" 7 8 declare void @do_safepoint() 9 10 define void @test_gep_const(i32 addrspace(1)* %base) gc "statepoint-example" { 11 ; CHECK-LABEL: test_gep_const 12 entry: 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 24 define void @test_gep_idx(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" { 25 ; CHECK-LABEL: test_gep_idx 26 entry: 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 38 define void @test_bitcast(i32 addrspace(1)* %base) gc "statepoint-example" { 39 ; CHECK-LABEL: test_bitcast 40 entry: 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 52 define void @test_bitcast_bitcast(i32 addrspace(1)* %base) gc "statepoint-example" { 53 ; CHECK-LABEL: test_bitcast_bitcast 54 entry: 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 70 define void @test_addrspacecast_addrspacecast(i32 addrspace(1)* %base) gc "statepoint-example" { 71 ; CHECK-LABEL: test_addrspacecast_addrspacecast 72 entry: 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 88 define void @test_bitcast_gep(i32 addrspace(1)* %base) gc "statepoint-example" { 89 ; CHECK-LABEL: test_bitcast_gep 90 entry: 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 106 define void @test_intersecting_chains(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" { 107 ; CHECK-LABEL: test_intersecting_chains 108 entry: 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 126 define void @test_cost_threshold(i32 addrspace(1)* %base, i32 %idx1, i32 %idx2, i32 %idx3) gc "statepoint-example" { 127 ; CHECK-LABEL: test_cost_threshold 128 entry: 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 148 define void @test_two_derived(i32 addrspace(1)* %base) gc "statepoint-example" { 149 ; CHECK-LABEL: test_two_derived 150 entry: 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 166 define void @test_gep_smallint_array([3 x i32] addrspace(1)* %base) gc "statepoint-example" { 167 ; CHECK-LABEL: test_gep_smallint_array 168 entry: 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 180 declare i32 @fake_personality_function() 181 182 define void @test_invoke(i32 addrspace(1)* %base) gc "statepoint-example" personality i32 ()* @fake_personality_function { 183 ; CHECK-LABEL: test_invoke 184 entry: 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 194 normal: 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 206 exception: 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 221 define void @test_loop(i32 addrspace(1)* %base) gc "statepoint-example" { 222 ; CHECK-LABEL: test_loop 223 entry: 224 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 225 ; CHECK: getelementptr 226 br label %loop 227 228 loop: ; 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 239 define void @test_too_long(i32 addrspace(1)* %base) gc "statepoint-example" { 240 ; CHECK-LABEL: test_too_long 241 entry: 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