OLD | NEW |
(Empty) | |
| 1 ; RUN: opt %s -replace-ptrs-with-ints -S | FileCheck %s |
| 2 |
| 3 target datalayout = "p:32:32:32" |
| 4 |
| 5 |
| 6 %struct = type { i32, i32 } |
| 7 |
| 8 declare %struct* @addr_taken_func(%struct*) |
| 9 |
| 10 @addr_of_func = global %struct* (%struct*)* @addr_taken_func |
| 11 ; CHECK: @addr_of_func = global %struct* (%struct*)* bitcast (i32 (i32)* @addr_t
aken_func to %struct* (%struct*)*) |
| 12 |
| 13 @blockaddr = global i8* blockaddress(@indirectbr, %l1) |
| 14 ; CHECK: @blockaddr = global i8* blockaddress(@indirectbr, %l1) |
| 15 |
| 16 |
| 17 define i8* @pointer_arg(i8* %ptr, i64 %non_ptr) { |
| 18 ret i8* %ptr |
| 19 } |
| 20 ; CHECK: define i32 @pointer_arg(i32 %ptr, i64 %non_ptr) { |
| 21 ; CHECK-NEXT: ret i32 %ptr |
| 22 ; CHECK-NEXT: } |
| 23 |
| 24 |
| 25 declare i8* @declared_func(i8*, i64) |
| 26 ; CHECK: declare i32 @declared_func(i32, i64) |
| 27 |
| 28 |
| 29 define void @self_reference_phi(i8* %ptr) { |
| 30 entry: |
| 31 br label %loop |
| 32 loop: |
| 33 %x = phi i8* [ %x, %loop ], [ %ptr, %entry ] |
| 34 br label %loop |
| 35 } |
| 36 ; CHECK: define void @self_reference_phi(i32 %ptr) { |
| 37 ; CHECK: %x = phi i32 [ %x, %loop ], [ %ptr, %entry ] |
| 38 |
| 39 ; Self-referencing bitcasts are possible in unreachable basic blocks. |
| 40 ; It is not very likely that we will encounter this, but we handle it |
| 41 ; for completeness. |
| 42 define void @self_reference_bitcast(i8** %dest) { |
| 43 ret void |
| 44 unreachable_loop: |
| 45 store i8* %self_ref, i8** %dest |
| 46 %self_ref = bitcast i8* %self_ref to i8* |
| 47 store i8* %self_ref, i8** %dest |
| 48 br label %unreachable_loop |
| 49 } |
| 50 ; CHECK: define void @self_reference_bitcast(i32 %dest) { |
| 51 ; CHECK: store i32 undef, i32* %dest.asptr |
| 52 ; CHECK: store i32 undef, i32* %dest.asptr |
| 53 |
| 54 define void @circular_reference_bitcasts(i8** %dest) { |
| 55 ret void |
| 56 unreachable_loop: |
| 57 store i8* %cycle1, i8** %dest |
| 58 %cycle1 = bitcast i8* %cycle2 to i8* |
| 59 %cycle2 = bitcast i8* %cycle1 to i8* |
| 60 br label %unreachable_loop |
| 61 } |
| 62 ; CHECK: define void @circular_reference_bitcasts(i32 %dest) { |
| 63 ; CHECK: store i32 undef, i32* %dest.asptr |
| 64 |
| 65 define void @circular_reference_inttoptr(i8** %dest) { |
| 66 ret void |
| 67 unreachable_loop: |
| 68 %ptr = inttoptr i32 %int to i8* |
| 69 %int = ptrtoint i8* %ptr to i32 |
| 70 store i8* %ptr, i8** %dest |
| 71 br label %unreachable_loop |
| 72 } |
| 73 ; CHECK: define void @circular_reference_inttoptr(i32 %dest) { |
| 74 ; CHECK: store i32 undef, i32* %dest.asptr |
| 75 |
| 76 define i8* @forwards_reference(%struct** %ptr) { |
| 77 br label %block1 |
| 78 block2: |
| 79 ; Forwards reference to %val. |
| 80 %cast = bitcast %struct* %val to i8* |
| 81 br label %block3 |
| 82 block1: |
| 83 %val = load %struct** %ptr |
| 84 br label %block2 |
| 85 block3: |
| 86 ; Backwards reference to a forwards reference that has already been |
| 87 ; resolved. |
| 88 ret i8* %cast |
| 89 } |
| 90 ; CHECK: define i32 @forwards_reference(i32 %ptr) { |
| 91 ; CHECK-NEXT: br label %block1 |
| 92 ; CHECK: block2: |
| 93 ; CHECK-NEXT: br label %block3 |
| 94 ; CHECK: block1: |
| 95 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i32* |
| 96 ; CHECK-NEXT: %val = load i32* %ptr.asptr |
| 97 ; CHECK-NEXT: br label %block2 |
| 98 ; CHECK: block3: |
| 99 ; CHECK-NEXT: ret i32 %val |
| 100 |
| 101 |
| 102 define i8* @phi_multiple_entry(i1 %arg, i8* %ptr) { |
| 103 entry: |
| 104 br i1 %arg, label %done, label %done |
| 105 done: |
| 106 %result = phi i8* [ %ptr, %entry ], [ %ptr, %entry ] |
| 107 ret i8* %result |
| 108 } |
| 109 ; CHECK: define i32 @phi_multiple_entry(i1 %arg, i32 %ptr) { |
| 110 ; CHECK: %result = phi i32 [ %ptr, %entry ], [ %ptr, %entry ] |
| 111 |
| 112 |
| 113 define i8* @select(i1 %cond, i8* %val1, i8* %val2) { |
| 114 %r = select i1 %cond, i8* %val1, i8* %val2 |
| 115 ret i8* %r |
| 116 } |
| 117 ; CHECK: define i32 @select(i1 %cond, i32 %val1, i32 %val2) { |
| 118 ; CHECK-NEXT: %r = select i1 %cond, i32 %val1, i32 %val2 |
| 119 |
| 120 |
| 121 define i32* @ptrtoint_same_size(i32* %ptr) { |
| 122 %a = ptrtoint i32* %ptr to i32 |
| 123 %b = add i32 %a, 4 |
| 124 %c = inttoptr i32 %b to i32* |
| 125 ret i32* %c |
| 126 } |
| 127 ; CHECK: define i32 @ptrtoint_same_size(i32 %ptr) { |
| 128 ; CHECK-NEXT: %b = add i32 %ptr, 4 |
| 129 ; CHECK-NEXT: ret i32 %b |
| 130 |
| 131 |
| 132 define i32* @ptrtoint_different_size(i32* %ptr) { |
| 133 %a = ptrtoint i32* %ptr to i64 |
| 134 %b = add i64 %a, 4 |
| 135 %c = inttoptr i64 %b to i32* |
| 136 ret i32* %c |
| 137 } |
| 138 ; CHECK: define i32 @ptrtoint_different_size(i32 %ptr) { |
| 139 ; CHECK-NEXT: %a = zext i32 %ptr to i64 |
| 140 ; CHECK-NEXT: %b = add i64 %a, 4 |
| 141 ; CHECK-NEXT: %c = trunc i64 %b to i32 |
| 142 ; CHECK-NEXT: ret i32 %c |
| 143 |
| 144 define i8 @ptrtoint_truncates_var(i32* %ptr) { |
| 145 %a = ptrtoint i32* %ptr to i8 |
| 146 ret i8 %a |
| 147 } |
| 148 ; CHECK: define i8 @ptrtoint_truncates_var(i32 %ptr) { |
| 149 ; CHECK-NEXT: %a = trunc i32 %ptr to i8 |
| 150 |
| 151 define i8 @ptrtoint_truncates_global() { |
| 152 %a = ptrtoint i32* @var to i8 |
| 153 ret i8 %a |
| 154 } |
| 155 ; CHECK: define i8 @ptrtoint_truncates_global() { |
| 156 ; CHECK-NEXT: %expanded = ptrtoint i32* @var to i32 |
| 157 ; CHECK-NEXT: %a = trunc i32 %expanded to i8 |
| 158 |
| 159 |
| 160 define i32* @pointer_bitcast(i64* %ptr) { |
| 161 %cast = bitcast i64* %ptr to i32* |
| 162 ret i32* %cast |
| 163 } |
| 164 ; CHECK: define i32 @pointer_bitcast(i32 %ptr) { |
| 165 ; CHECK-NEXT: ret i32 %ptr |
| 166 |
| 167 ; Same-type non-pointer bitcasts happen to be left alone by this pass. |
| 168 define i32 @no_op_bitcast(i32 %val) { |
| 169 %val2 = bitcast i32 %val to i32 |
| 170 ret i32 %val2 |
| 171 } |
| 172 ; CHECK: define i32 @no_op_bitcast(i32 %val) { |
| 173 ; CHECK-NEXT: %val2 = bitcast i32 %val to i32 |
| 174 |
| 175 define i64 @kept_bitcast(double %d) { |
| 176 %i = bitcast double %d to i64 |
| 177 ret i64 %i |
| 178 } |
| 179 ; CHECK: define i64 @kept_bitcast(double %d) { |
| 180 ; CHECK-NEXT: %i = bitcast double %d to i64 |
| 181 |
| 182 |
| 183 define i32 @constant_pointer_null() { |
| 184 %val = ptrtoint i32* null to i32 |
| 185 ret i32 %val |
| 186 } |
| 187 ; CHECK: define i32 @constant_pointer_null() { |
| 188 ; CHECK-NEXT: ret i32 0 |
| 189 |
| 190 define i32 @constant_pointer_undef() { |
| 191 %val = ptrtoint i32* undef to i32 |
| 192 ret i32 %val |
| 193 } |
| 194 ; CHECK: define i32 @constant_pointer_undef() { |
| 195 ; CHECK-NEXT: ret i32 undef |
| 196 |
| 197 define i16* @constant_pointer_null_load() { |
| 198 %val = load i16** null |
| 199 ret i16* %val |
| 200 } |
| 201 ; CHECK: define i32 @constant_pointer_null_load() { |
| 202 ; CHECK-NEXT: %.asptr = inttoptr i32 0 to i32* |
| 203 ; CHECK-NEXT: %val = load i32* %.asptr |
| 204 |
| 205 define i16* @constant_pointer_undef_load() { |
| 206 %val = load i16** undef |
| 207 ret i16* %val |
| 208 } |
| 209 ; CHECK: define i32 @constant_pointer_undef_load() { |
| 210 ; CHECK-NEXT: %.asptr = inttoptr i32 undef to i32* |
| 211 ; CHECK-NEXT: %val = load i32* %.asptr |
| 212 |
| 213 |
| 214 define i8 @load(i8* %ptr) { |
| 215 %x = load i8* %ptr |
| 216 ret i8 %x |
| 217 } |
| 218 ; CHECK: define i8 @load(i32 %ptr) { |
| 219 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i8* |
| 220 ; CHECK-NEXT: %x = load i8* %ptr.asptr |
| 221 |
| 222 define void @store(i8* %ptr, i8 %val) { |
| 223 store i8 %val, i8* %ptr |
| 224 ret void |
| 225 } |
| 226 ; CHECK: define void @store(i32 %ptr, i8 %val) { |
| 227 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i8* |
| 228 ; CHECK-NEXT: store i8 %val, i8* %ptr.asptr |
| 229 |
| 230 |
| 231 define i8* @load_ptr(i8** %ptr) { |
| 232 %x = load i8** %ptr |
| 233 ret i8* %x |
| 234 } |
| 235 ; CHECK: define i32 @load_ptr(i32 %ptr) { |
| 236 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i32* |
| 237 ; CHECK-NEXT: %x = load i32* %ptr.asptr |
| 238 |
| 239 define void @store_ptr(i8** %ptr, i8* %val) { |
| 240 store i8* %val, i8** %ptr |
| 241 ret void |
| 242 } |
| 243 ; CHECK: define void @store_ptr(i32 %ptr, i32 %val) { |
| 244 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i32* |
| 245 ; CHECK-NEXT: store i32 %val, i32* %ptr.asptr |
| 246 |
| 247 |
| 248 define i8 @load_attrs(i8* %ptr) { |
| 249 %x = load atomic volatile i8* %ptr seq_cst, align 128 |
| 250 ret i8 %x |
| 251 } |
| 252 ; CHECK: define i8 @load_attrs(i32 %ptr) { |
| 253 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i8* |
| 254 ; CHECK-NEXT: %x = load atomic volatile i8* %ptr.asptr seq_cst, align 128 |
| 255 |
| 256 define void @store_attrs(i8* %ptr, i8 %val) { |
| 257 store atomic volatile i8 %val, i8* %ptr singlethread release, align 256 |
| 258 ret void |
| 259 } |
| 260 ; CHECK: define void @store_attrs(i32 %ptr, i8 %val) { |
| 261 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i8* |
| 262 ; CHECK-NEXT: store atomic volatile i8 %val, i8* %ptr.asptr singlethread release
, align 256 |
| 263 |
| 264 |
| 265 define i32 @cmpxchg(i32* %ptr, i32 %a, i32 %b) { |
| 266 %r = cmpxchg i32* %ptr, i32 %a, i32 %b seq_cst seq_cst |
| 267 %res = extractvalue { i32, i1 } %r, 0 |
| 268 ret i32 %res |
| 269 } |
| 270 ; CHECK: define i32 @cmpxchg(i32 %ptr, i32 %a, i32 %b) { |
| 271 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i32* |
| 272 ; CHECK-NEXT: %r = cmpxchg i32* %ptr.asptr, i32 %a, i32 %b seq_cst seq_cst |
| 273 |
| 274 define i32 @atomicrmw(i32* %ptr, i32 %x) { |
| 275 %r = atomicrmw add i32* %ptr, i32 %x seq_cst |
| 276 ret i32 %r |
| 277 } |
| 278 ; CHECK: define i32 @atomicrmw(i32 %ptr, i32 %x) { |
| 279 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i32* |
| 280 ; CHECK-NEXT: %r = atomicrmw add i32* %ptr.asptr, i32 %x seq_cst |
| 281 |
| 282 |
| 283 define i8* @indirect_call(i8* (i8*)* %func, i8* %arg) { |
| 284 %result = call i8* %func(i8* %arg) |
| 285 ret i8* %result |
| 286 } |
| 287 ; CHECK: define i32 @indirect_call(i32 %func, i32 %arg) { |
| 288 ; CHECK-NEXT: %func.asptr = inttoptr i32 %func to i32 (i32)* |
| 289 ; CHECK-NEXT: %result = call i32 %func.asptr(i32 %arg) |
| 290 ; CHECK-NEXT: ret i32 %result |
| 291 |
| 292 |
| 293 ; Test forwards reference |
| 294 define i8* @direct_call1(i8* %arg) { |
| 295 %result = call i8* @direct_call2(i8* %arg) |
| 296 ret i8* %result |
| 297 } |
| 298 ; CHECK: define i32 @direct_call1(i32 %arg) { |
| 299 ; CHECK-NEXT: %result = call i32 @direct_call2(i32 %arg) |
| 300 ; CHECK-NEXT: ret i32 %result |
| 301 |
| 302 ; Test backwards reference |
| 303 define i8* @direct_call2(i8* %arg) { |
| 304 %result = call i8* @direct_call1(i8* %arg) |
| 305 ret i8* %result |
| 306 } |
| 307 ; CHECK: define i32 @direct_call2(i32 %arg) { |
| 308 ; CHECK-NEXT: %result = call i32 @direct_call1(i32 %arg) |
| 309 ; CHECK-NEXT: ret i32 %result |
| 310 |
| 311 |
| 312 @var = global i32 0 |
| 313 |
| 314 define i32* @get_addr_of_global() { |
| 315 ret i32* @var |
| 316 } |
| 317 ; CHECK: define i32 @get_addr_of_global() { |
| 318 ; CHECK-NEXT: %expanded = ptrtoint i32* @var to i32 |
| 319 ; CHECK-NEXT: ret i32 %expanded |
| 320 |
| 321 define %struct* (%struct*)* @get_addr_of_func() { |
| 322 ret %struct* (%struct*)* @addr_taken_func |
| 323 } |
| 324 ; CHECK: define i32 @get_addr_of_func() { |
| 325 ; CHECK-NEXT: %expanded = ptrtoint i32 (i32)* @addr_taken_func to i32 |
| 326 ; CEHCK-NEXT: ret i32 %expanded |
| 327 |
| 328 |
| 329 define i32 @load_global() { |
| 330 %val = load i32* @var |
| 331 ret i32 %val |
| 332 } |
| 333 ; CHECK: define i32 @load_global() { |
| 334 ; CHECK-NEXT: %val = load i32* @var |
| 335 ; CHECK-NEXT: ret i32 %val |
| 336 |
| 337 define i16 @load_global_bitcast() { |
| 338 %ptr = bitcast i32* @var to i16* |
| 339 %val = load i16* %ptr |
| 340 ret i16 %val |
| 341 } |
| 342 ; CHECK: define i16 @load_global_bitcast() { |
| 343 ; CHECK-NEXT: %var.bc = bitcast i32* @var to i16* |
| 344 ; CHECK-NEXT: %val = load i16* %var.bc |
| 345 ; CHECK-NEXT: ret i16 %val |
| 346 |
| 347 |
| 348 ; Check that unsimplified allocas are properly handled: |
| 349 declare void @receive_alloca(%struct* %ptr) |
| 350 |
| 351 define void @unsimplified_alloca() { |
| 352 %a = alloca %struct |
| 353 call void @receive_alloca(%struct* %a) |
| 354 unreachable |
| 355 } |
| 356 ; CHECK-LABEL: define void @unsimplified_alloca() |
| 357 ; CHECK-NEXT: %a = alloca %struct |
| 358 ; CHECK-NEXT: %a.asint = ptrtoint %struct* %a to i32 |
| 359 ; CHECK-NEXT: call void @receive_alloca(i32 %a.asint) |
| 360 ; CHECK-NEXT: unreachable |
| 361 |
| 362 |
| 363 define i1 @compare(i8* %ptr1, i8* %ptr2) { |
| 364 %cmp = icmp ult i8* %ptr1, %ptr2 |
| 365 ret i1 %cmp |
| 366 } |
| 367 ; CHECK: define i1 @compare(i32 %ptr1, i32 %ptr2) { |
| 368 ; CHECK-NEXT: %cmp = icmp ult i32 %ptr1, %ptr2 |
| 369 |
| 370 |
| 371 declare i8* @llvm.some.intrinsic(i8* %ptr) |
| 372 |
| 373 define i8* @preserve_intrinsic_type(i8* %ptr) { |
| 374 %result = call i8* @llvm.some.intrinsic(i8* %ptr) |
| 375 ret i8* %result |
| 376 } |
| 377 ; CHECK: define i32 @preserve_intrinsic_type(i32 %ptr) { |
| 378 ; CHECK-NEXT: %ptr.asptr = inttoptr i32 %ptr to i8* |
| 379 ; CHECK-NEXT: %result = call i8* @llvm.some.intrinsic(i8* %ptr.asptr) |
| 380 ; CHECK-NEXT: %result.asint = ptrtoint i8* %result to i32 |
| 381 ; CHECK-NEXT: ret i32 %result.asint |
| 382 |
| 383 |
| 384 ; Just check that the pass does not crash on inline asm. |
| 385 define i16* @inline_asm1(i8* %ptr) { |
| 386 %val = call i16* asm "foo", "=r,r"(i8* %ptr) |
| 387 ret i16* %val |
| 388 } |
| 389 |
| 390 define i16** @inline_asm2(i8** %ptr) { |
| 391 %val = call i16** asm "foo", "=r,r"(i8** %ptr) |
| 392 ret i16** %val |
| 393 } |
| 394 |
| 395 |
| 396 declare void @llvm.dbg.declare(metadata, metadata, metadata) |
| 397 declare void @llvm.dbg.value(metadata, i64, metadata, metadata) |
| 398 |
| 399 define void @debug_declare(i32 %val) { |
| 400 ; We normally expect llvm.dbg.declare to be used on an alloca. |
| 401 %var = alloca i32 |
| 402 call void @llvm.dbg.declare(metadata !{i32* %var}, metadata !2, metadata !14) |
| 403 call void @llvm.dbg.declare(metadata !{i32 %val}, metadata !2, metadata !14) |
| 404 ret void |
| 405 } |
| 406 ; CHECK: define void @debug_declare(i32 %val) { |
| 407 ; CHECK-NEXT: %var = alloca i32 |
| 408 ; CHECK-NEXT: call void @llvm.dbg.declare(metadata !{i32* %var}, metadata !2, me
tadata !14) |
| 409 ; This case is currently not converted. |
| 410 ; CHECK-NEXT: call void @llvm.dbg.declare(metadata !{null}, metadata !2, metadat
a !14) |
| 411 ; CHECK-NEXT: ret void |
| 412 |
| 413 ; For now, debugging info for values is lost. replaceAllUsesWith() |
| 414 ; does not work for metadata references -- it converts them to nulls. |
| 415 ; This makes dbg.value too tricky to handle for now. |
| 416 define void @debug_value(i32 %val, i8* %ptr) { |
| 417 tail call void @llvm.dbg.value(metadata !{i32 %val}, i64 1, metadata !1, metad
ata !14) |
| 418 tail call void @llvm.dbg.value(metadata !{i8* %ptr}, i64 2, metadata !1, metad
ata !14) |
| 419 ret void |
| 420 } |
| 421 ; CHECK: define void @debug_value(i32 %val, i32 %ptr) { |
| 422 ; CHECK-NEXT: call void @llvm.dbg.value(metadata !{null}, i64 1, metadata !1, me
tadata !14) |
| 423 ; CHECK-NEXT: call void @llvm.dbg.value(metadata !{null}, i64 2, metadata !1, me
tadata !14) |
| 424 ; CHECK-NEXT: ret void |
| 425 |
| 426 |
| 427 declare void @llvm.lifetime.start(i64 %size, i8* %ptr) |
| 428 declare {}* @llvm.invariant.start(i64 %size, i8* %ptr) |
| 429 declare void @llvm.invariant.end({}* %start, i64 %size, i8* %ptr) |
| 430 |
| 431 ; GVN can introduce the following horrible corner case of a lifetime |
| 432 ; marker referencing a PHI node. But we convert the phi to i32 type, |
| 433 ; and lifetime.start doesn't work on an inttoptr converting an i32 phi |
| 434 ; to a pointer. Because of this, we just strip out all lifetime |
| 435 ; markers. |
| 436 |
| 437 define void @alloca_lifetime_via_phi() { |
| 438 entry: |
| 439 %buf = alloca i8 |
| 440 br label %block |
| 441 block: |
| 442 %phi = phi i8* [ %buf, %entry ] |
| 443 call void @llvm.lifetime.start(i64 -1, i8* %phi) |
| 444 ret void |
| 445 } |
| 446 ; CHECK: define void @alloca_lifetime_via_phi() { |
| 447 ; CHECK: %phi = phi i32 [ %buf.asint, %entry ] |
| 448 ; CHECK-NEXT: ret void |
| 449 |
| 450 define void @alloca_lifetime() { |
| 451 %buf = alloca i8 |
| 452 call void @llvm.lifetime.start(i64 -1, i8* %buf) |
| 453 ret void |
| 454 } |
| 455 ; CHECK: define void @alloca_lifetime() { |
| 456 ; CHECK-NEXT: %buf = alloca i8 |
| 457 ; CHECK-NEXT: ret void |
| 458 |
| 459 define void @alloca_lifetime_via_bitcast() { |
| 460 %buf = alloca i32 |
| 461 %buf_cast = bitcast i32* %buf to i8* |
| 462 call void @llvm.lifetime.start(i64 -1, i8* %buf_cast) |
| 463 ret void |
| 464 } |
| 465 ; CHECK: define void @alloca_lifetime_via_bitcast() { |
| 466 ; CHECK-NEXT: %buf = alloca i32 |
| 467 ; CHECK-NEXT: ret void |
| 468 |
| 469 |
| 470 define void @strip_invariant_markers() { |
| 471 %buf = alloca i8 |
| 472 %start = call {}* @llvm.invariant.start(i64 1, i8* %buf) |
| 473 call void @llvm.invariant.end({}* %start, i64 1, i8* %buf) |
| 474 ret void |
| 475 } |
| 476 ; CHECK: define void @strip_invariant_markers() { |
| 477 ; CHECK-NEXT: %buf = alloca i8 |
| 478 ; CHECK-NEXT: ret void |
| 479 |
| 480 |
| 481 ; "nocapture" and "noalias" only apply to pointers, so must be stripped. |
| 482 define void @nocapture_attr(i8* nocapture noalias %ptr) { |
| 483 ret void |
| 484 } |
| 485 ; CHECK: define void @nocapture_attr(i32 %ptr) { |
| 486 |
| 487 |
| 488 define void @readonly_readnone(i8* readonly readnone) { |
| 489 ret void |
| 490 } |
| 491 ; CHECK-LABEL: define void @readonly_readnone(i32) |
| 492 |
| 493 ; "nounwind" should be preserved. |
| 494 define void @nounwind_func_attr() nounwind { |
| 495 ret void |
| 496 } |
| 497 ; CHECK: define void @nounwind_func_attr() [[NOUNWIND:#[0-9]+]] { |
| 498 |
| 499 define void @nounwind_call_attr() { |
| 500 call void @nounwind_func_attr() nounwind |
| 501 ret void |
| 502 } |
| 503 ; CHECK: define void @nounwind_call_attr() { |
| 504 ; CHECK: call void @nounwind_func_attr() {{.*}}[[NOUNWIND]] |
| 505 |
| 506 define fastcc void @fastcc_func() { |
| 507 ret void |
| 508 } |
| 509 ; CHECK: define fastcc void @fastcc_func() { |
| 510 |
| 511 define void @fastcc_call() { |
| 512 call fastcc void @fastcc_func() |
| 513 ret void |
| 514 } |
| 515 ; CHECK: define void @fastcc_call() { |
| 516 ; CHECK-NEXT: call fastcc void @fastcc_func() |
| 517 |
| 518 define void @tail_call() { |
| 519 tail call void @tail_call() |
| 520 ret void |
| 521 } |
| 522 ; CHECK: define void @tail_call() |
| 523 ; CHECK-NEXT: tail call void @tail_call() |
| 524 |
| 525 |
| 526 ; Just check that the pass does not crash on getelementptr. (The pass |
| 527 ; should not depend unnecessarily on ExpandGetElementPtr having been |
| 528 ; run.) |
| 529 define i8* @getelementptr(i8* %ptr) { |
| 530 %gep = getelementptr i8* %ptr, i32 10 |
| 531 ret i8* %gep |
| 532 } |
| 533 |
| 534 ; Just check that the pass does not crash on va_arg. |
| 535 define i32* @va_arg(i8* %valist) { |
| 536 %r = va_arg i8* %valist, i32* |
| 537 ret i32* %r |
| 538 } |
| 539 |
| 540 |
| 541 define void @indirectbr(i8* %addr) { |
| 542 indirectbr i8* %addr, [ label %l1, label %l2 ] |
| 543 l1: |
| 544 ret void |
| 545 l2: |
| 546 ret void |
| 547 } |
| 548 ; CHECK: define void @indirectbr(i32 %addr) { |
| 549 ; CHECK-NEXT: %addr.asptr = inttoptr i32 %addr to i8* |
| 550 ; CHECK-NEXT: indirectbr i8* %addr.asptr, [label %l1, label %l2] |
| 551 |
| 552 |
| 553 define i8* @invoke(i8* %val) { |
| 554 %result = invoke i8* @direct_call1(i8* %val) |
| 555 to label %cont unwind label %lpad |
| 556 cont: |
| 557 ret i8* %result |
| 558 lpad: |
| 559 %lp = landingpad { i8*, i32 } personality void (i8*)* @personality_func cleanu
p |
| 560 %p = extractvalue { i8*, i32 } %lp, 0 |
| 561 %s = insertvalue { i8*, i32 } %lp, i8* %val, 0 |
| 562 ret i8* %p |
| 563 } |
| 564 ; CHECK: define i32 @invoke(i32 %val) { |
| 565 ; CHECK-NEXT: %result = invoke i32 @direct_call1(i32 %val) |
| 566 ; CHECK-NEXT: to label %cont unwind label %lpad |
| 567 ; CHECK: %lp = landingpad { i8*, i32 } personality void (i8*)* bitcast (void (i3
2)* @personality_func to void (i8*)*) |
| 568 ; CHECK: %p = extractvalue { i8*, i32 } %lp, 0 |
| 569 ; CHECK-NEXT: %p.asint = ptrtoint i8* %p to i32 |
| 570 ; CHECK-NEXT: %val.asptr = inttoptr i32 %val to i8* |
| 571 ; CHECK-NEXT: %s = insertvalue { i8*, i32 } %lp, i8* %val.asptr, 0 |
| 572 ; CHECK-NEXT: ret i32 %p.asint |
| 573 |
| 574 define void @personality_func(i8* %arg) { |
| 575 ret void |
| 576 } |
| 577 |
| 578 |
| 579 declare i32 @llvm.eh.typeid.for(i8*) |
| 580 |
| 581 @typeid = global i32 0 |
| 582 |
| 583 ; The argument here must be left as a bitcast, otherwise the backend |
| 584 ; rejects it. |
| 585 define void @typeid_for() { |
| 586 %bc = bitcast i32* @typeid to i8* |
| 587 call i32 @llvm.eh.typeid.for(i8* %bc) |
| 588 ret void |
| 589 } |
| 590 ; CHECK: define void @typeid_for() { |
| 591 ; CHECK-NEXT: %typeid.bc = bitcast i32* @typeid to i8* |
| 592 ; CHECK-NEXT: call i32 @llvm.eh.typeid.for(i8* %typeid.bc) |
| 593 |
| 594 |
| 595 ; Subprogram debug metadata may refer to a function. |
| 596 ; Make sure those are updated too. |
| 597 ; Regenerate the debug info from the following C program: |
| 598 ; void nop(void *ptr) { |
| 599 ; } |
| 600 |
| 601 define void @nop(i8* %ptr) { |
| 602 tail call void @llvm.dbg.value(metadata !{i8* %ptr}, i64 0, metadata !10, meta
data !14), !dbg !15 |
| 603 ret void, !dbg !16 |
| 604 } |
| 605 ; CHECK: define void @nop(i32 %ptr) { |
| 606 ; CHECK-NEXT: call void @llvm.dbg.value{{.*}} |
| 607 ; CHECK-NEXT: ret void |
| 608 |
| 609 |
| 610 ; CHECK: attributes {{.*}}[[NOUNWIND]] = { nounwind } |
| 611 |
| 612 !llvm.dbg.cu = !{!0} |
| 613 !llvm.module.flags = !{!11, !12} |
| 614 !llvm.ident = !{!13} |
| 615 |
| 616 !0 = metadata !{metadata !"0x11\0012\00clang version 3.6.0", metadata !1, metada
ta !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_un
it ] [/home/foo/test_debug.c] [DW_LANG_C99] |
| 617 !1 = metadata !{metadata !"test_debug.c", metadata !"/home/foo"} |
| 618 !2 = metadata !{} |
| 619 !3 = metadata !{metadata !4} |
| 620 !4 = metadata !{metadata !"0x2e\00nop\00nop\00\001\000\001\000\000\00256\001\001
", metadata !1, metadata !5, metadata !6, null, void (i8*)* @nop, null, null, me
tadata !9} ; [ DW_TAG_subprogram ] [line 1] [def] [nop] |
| 621 !5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [/home/
foo/test_debug.c] |
| 622 !6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", null, null, null, m
etadata !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, alig
n 0, offset 0] [from ] |
| 623 !7 = metadata !{null, metadata !8} |
| 624 !8 = metadata !{metadata !"0xf\00\000\0032\0032\000\000", null, null, null} ; [
DW_TAG_pointer_type ] [line 0, size 32, align 32, offset 0] [from ] |
| 625 !9 = metadata !{metadata !10} |
| 626 !10 = metadata !{metadata !"0x101\00ptr\0016777217\000", metadata !4, metadata !
5, metadata !8} ; [ DW_TAG_arg_variable ] [ptr] [line 1] |
| 627 !11 = metadata !{i32 2, metadata !"Dwarf Version", i32 4} |
| 628 !12 = metadata !{i32 2, metadata !"Debug Info Version", i32 2} |
| 629 !13 = metadata !{metadata !"clang version 3.6.0"} |
| 630 !14 = metadata !{metadata !"0x102"} ; [ DW_TAG_expression ] |
| 631 !15 = metadata !{i32 1, i32 16, metadata !4, null} |
| 632 !16 = metadata !{i32 2, i32 1, metadata !4, null} |
| 633 |
| 634 ; CHECK: !4 = metadata !{{{.*}}nop{{.*}}, void (i32)* @nop, {{.*}}} ; [ DW_TAG_s
ubprogram ] [line 1] [def] [nop] |
OLD | NEW |