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