1; RUN: opt %s -rewrite-statepoints-for-gc -S 2>&1 | FileCheck %s 2 3declare void @use_obj16(i16 addrspace(1)*) 4declare void @use_obj32(i32 addrspace(1)*) 5declare void @use_obj64(i64 addrspace(1)*) 6declare void @do_safepoint() 7 8define void @"test_gep_const"(i32 addrspace(1)* %base) gc "statepoint-example" { 9; CHECK-LABEL: test_gep_const 10entry: 11 %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15 12 ; CHECK: getelementptr i32, i32 addrspace(1)* %base, i32 15 13 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 14 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %sp, i32 7, i32 7) 15 ; CHECK: bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)* 16 ; CHECK: getelementptr i32, i32 addrspace(1)* %base.relocated.casted, i32 15 17 call void @use_obj32(i32 addrspace(1)* %base) 18 call void @use_obj32(i32 addrspace(1)* %ptr) 19 ret void 20} 21 22define void @"test_gep_idx"(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" { 23; CHECK-LABEL: test_gep_idx 24entry: 25 %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 %idx 26 ; CHECK: getelementptr 27 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 28 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %sp, i32 7, i32 7) 29 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)* 30 ; CHECK: getelementptr i32, i32 addrspace(1)* %base.relocated.casted, i32 %idx 31 call void @use_obj32(i32 addrspace(1)* %base) 32 call void @use_obj32(i32 addrspace(1)* %ptr) 33 ret void 34} 35 36define void @"test_bitcast"(i32 addrspace(1)* %base) gc "statepoint-example" { 37; CHECK-LABEL: test_bitcast 38entry: 39 %ptr = bitcast i32 addrspace(1)* %base to i64 addrspace(1)* 40 ; CHECK: bitcast i32 addrspace(1)* %base to i64 addrspace(1)* 41 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 42 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %sp, i32 7, i32 7) 43 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)* 44 ; CHECK: bitcast i32 addrspace(1)* %base.relocated.casted to i64 addrspace(1)* 45 call void @use_obj32(i32 addrspace(1)* %base) 46 call void @use_obj64(i64 addrspace(1)* %ptr) 47 ret void 48} 49 50define void @"test_bitcast_bitcast"(i32 addrspace(1)* %base) gc "statepoint-example" { 51; CHECK-LABEL: test_bitcast_bitcast 52entry: 53 %ptr1 = bitcast i32 addrspace(1)* %base to i64 addrspace(1)* 54 %ptr2 = bitcast i64 addrspace(1)* %ptr1 to i16 addrspace(1)* 55 ; CHECK: bitcast i32 addrspace(1)* %base to i64 addrspace(1)* 56 ; CHECK: bitcast i64 addrspace(1)* %ptr1 to i16 addrspace(1)* 57 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 58 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %sp, i32 7, i32 7) 59 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)* 60 ; CHECK: bitcast i32 addrspace(1)* %base.relocated.casted to i64 addrspace(1)* 61 ; CHECK: bitcast i64 addrspace(1)* %ptr1.remat to i16 addrspace(1)* 62 call void @use_obj32(i32 addrspace(1)* %base) 63 call void @use_obj16(i16 addrspace(1)* %ptr2) 64 ret void 65} 66 67define void @"test_addrspacecast_addrspacecast"(i32 addrspace(1)* %base) gc "statepoint-example" { 68; CHECK-LABEL: test_addrspacecast_addrspacecast 69entry: 70 %ptr1 = addrspacecast i32 addrspace(1)* %base to i32* 71 %ptr2 = addrspacecast i32* %ptr1 to i32 addrspace(1)* 72 ; CHECK: addrspacecast i32 addrspace(1)* %base to i32* 73 ; CHECK: addrspacecast i32* %ptr1 to i32 addrspace(1)* 74 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 75 ; CHECK: %base.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %sp, i32 7, i32 7) 76 ; CHECK: %base.relocated.casted = bitcast i8 addrspace(1)* %base.relocated to i32 addrspace(1)* 77 ; CHECK: %ptr2.relocated = call coldcc i8 addrspace(1)* @llvm.experimental.gc.relocate.p1i8(token %sp, i32 7, i32 8) 78 ; CHECK: %ptr2.relocated.casted = bitcast i8 addrspace(1)* %ptr2.relocated to i32 addrspace(1)* 79 call void @use_obj32(i32 addrspace(1)* %base) 80 call void @use_obj32(i32 addrspace(1)* %ptr2) 81 ret void 82} 83 84define void @"test_bitcast_gep"(i32 addrspace(1)* %base) gc "statepoint-example" { 85; CHECK-LABEL: test_bitcast_gep 86entry: 87 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 88 ; CHECK: getelementptr 89 %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)* 90 ; CHECK: bitcast 91 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 92 ; CHECK: gc.relocate 93 ; CHECK: bitcast 94 ; CHECK: getelementptr 95 ; CHECK: bitcast 96 call void @use_obj32(i32 addrspace(1)* %base) 97 call void @use_obj64(i64 addrspace(1)* %ptr.cast) 98 ret void 99} 100 101define void @"test_intersecting_chains"(i32 addrspace(1)* %base, i32 %idx) gc "statepoint-example" { 102; CHECK-LABEL: test_intersecting_chains 103entry: 104 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 105 ; CHECK: getelementptr 106 %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)* 107 ; CHECK: bitcast 108 %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)* 109 ; CHECK: bitcast 110 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 111 ; CHECK: getelementptr 112 ; CHECK: bitcast 113 ; CHECK: getelementptr 114 ; CHECK: bitcast 115 call void @use_obj64(i64 addrspace(1)* %ptr.cast) 116 call void @use_obj16(i16 addrspace(1)* %ptr.cast2) 117 ret void 118} 119 120define void @"test_cost_threshold"(i32 addrspace(1)* %base, i32 %idx1, i32 %idx2, i32 %idx3) gc "statepoint-example" { 121; CHECK-LABEL: test_cost_threshold 122entry: 123 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 124 ; CHECK: getelementptr 125 %ptr.gep2 = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 %idx1 126 ; CHECK: getelementptr 127 %ptr.gep3 = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 %idx2 128 ; CHECK: getelementptr 129 %ptr.gep4 = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 %idx3 130 ; CHECK: getelementptr 131 %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep4 to i64 addrspace(1)* 132 ; CHECK: bitcast 133 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 134 ; CHECK: gc.relocate 135 ; CHECK: bitcast 136 ; CHECK: gc.relocate 137 ; CHECK: bitcast 138 call void @use_obj64(i64 addrspace(1)* %ptr.cast) 139 ret void 140} 141 142define void @"test_two_derived"(i32 addrspace(1)* %base) gc "statepoint-example" { 143; CHECK-LABEL: test_two_derived 144entry: 145 %ptr = getelementptr i32, i32 addrspace(1)* %base, i32 15 146 %ptr2 = getelementptr i32, i32 addrspace(1)* %base, i32 12 147 ; CHECK: getelementptr 148 ; CHECK: getelementptr 149 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 150 ; CHECK: gc.relocate 151 ; CHECK: bitcast 152 ; CHECK: getelementptr 153 ; CHECK: getelementptr 154 call void @use_obj32(i32 addrspace(1)* %ptr) 155 call void @use_obj32(i32 addrspace(1)* %ptr2) 156 ret void 157} 158 159define void @"test_gep_smallint_array"([3 x i32] addrspace(1)* %base) gc "statepoint-example" { 160; CHECK-LABEL: test_gep_smallint_array 161entry: 162 %ptr = getelementptr [3 x i32], [3 x i32] addrspace(1)* %base, i32 0, i32 2 163 ; CHECK: getelementptr 164 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 165 ; CHECK: gc.relocate 166 ; CHECK: bitcast 167 ; CHECK: getelementptr 168 call void @use_obj32(i32 addrspace(1)* %ptr) 169 ret void 170} 171 172declare i32 @fake_personality_function() 173 174define void @"test_invoke"(i32 addrspace(1)* %base) gc "statepoint-example" personality i32 ()* @fake_personality_function { 175; CHECK-LABEL: test_invoke 176entry: 177 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 178 ; CHECK: getelementptr 179 %ptr.cast = bitcast i32 addrspace(1)* %ptr.gep to i64 addrspace(1)* 180 ; CHECK: bitcast 181 %ptr.cast2 = bitcast i32 addrspace(1)* %ptr.gep to i16 addrspace(1)* 182 ; CHECK: bitcast 183 %sp = invoke token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 184 to label %normal unwind label %exception 185 186normal: 187 ; CHECK-LABEL: normal: 188 ; CHECK: gc.relocate 189 ; CHECK: bitcast 190 ; CHECK: getelementptr 191 ; CHECK: bitcast 192 ; CHECK: getelementptr 193 ; CHECK: bitcast 194 call void @use_obj64(i64 addrspace(1)* %ptr.cast) 195 call void @use_obj16(i16 addrspace(1)* %ptr.cast2) 196 ret void 197 198exception: 199 ; CHECK-LABEL: exception: 200 %landing_pad4 = landingpad token 201 cleanup 202 ; CHECK: gc.relocate 203 ; CHECK: bitcast 204 ; CHECK: getelementptr 205 ; CHECK: bitcast 206 ; CHECK: getelementptr 207 ; CHECK: bitcast 208 call void @use_obj64(i64 addrspace(1)* %ptr.cast) 209 call void @use_obj16(i16 addrspace(1)* %ptr.cast2) 210 ret void 211} 212 213define void @"test_loop"(i32 addrspace(1)* %base) gc "statepoint-example" { 214; CHECK-LABEL: test_loop 215entry: 216 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 217 ; CHECK: getelementptr 218 br label %loop 219 220loop: 221 ; CHECK: phi i32 addrspace(1)* [ %ptr.gep, %entry ], [ %ptr.gep.remat, %loop ] 222 ; CHECK: phi i32 addrspace(1)* [ %base, %entry ], [ %base.relocated.casted, %loop ] 223 call void @use_obj32(i32 addrspace(1)* %ptr.gep) 224 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 225 ; CHECK: gc.relocate 226 ; CHECK: bitcast 227 ; CHECK: getelementptr 228 br label %loop 229} 230 231define void @"test_too_long"(i32 addrspace(1)* %base) gc "statepoint-example" { 232; CHECK-LABEL: test_too_long 233entry: 234 %ptr.gep = getelementptr i32, i32 addrspace(1)* %base, i32 15 235 %ptr.gep1 = getelementptr i32, i32 addrspace(1)* %ptr.gep, i32 15 236 %ptr.gep2 = getelementptr i32, i32 addrspace(1)* %ptr.gep1, i32 15 237 %ptr.gep3 = getelementptr i32, i32 addrspace(1)* %ptr.gep2, i32 15 238 %ptr.gep4 = getelementptr i32, i32 addrspace(1)* %ptr.gep3, i32 15 239 %ptr.gep5 = getelementptr i32, i32 addrspace(1)* %ptr.gep4, i32 15 240 %ptr.gep6 = getelementptr i32, i32 addrspace(1)* %ptr.gep5, i32 15 241 %ptr.gep7 = getelementptr i32, i32 addrspace(1)* %ptr.gep6, i32 15 242 %ptr.gep8 = getelementptr i32, i32 addrspace(1)* %ptr.gep7, i32 15 243 %ptr.gep9 = getelementptr i32, i32 addrspace(1)* %ptr.gep8, i32 15 244 %ptr.gep10 = getelementptr i32, i32 addrspace(1)* %ptr.gep9, i32 15 245 %ptr.gep11 = getelementptr i32, i32 addrspace(1)* %ptr.gep10, i32 15 246 %sp = call token (i64, i32, void ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_isVoidf(i64 0, i32 0, void ()* @do_safepoint, i32 0, i32 0, i32 0, i32 0) 247 ; CHECK: gc.relocate 248 ; CHECK: bitcast 249 ; CHECK: gc.relocate 250 ; CHECK: bitcast 251 call void @use_obj32(i32 addrspace(1)* %ptr.gep11) 252 ret void 253} 254 255 256declare token @llvm.experimental.gc.statepoint.p0f_isVoidf(i64, i32, void ()*, i32, i32, ...) 257