1 ; RUN: opt < %s -default-data-layout="e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-n8:16:32" -basicaa -gvn -S -die | FileCheck %s 2 ; RUN: opt < %s -default-data-layout="E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-n32" -basicaa -gvn -S -die | FileCheck %s 3 4 ;; Trivial RLE test. 5 define i32 @test0(i32 %V, i32* %P) { 6 store i32 %V, i32* %P 7 8 %A = load i32* %P 9 ret i32 %A 10 ; CHECK-LABEL: @test0( 11 ; CHECK: ret i32 %V 12 } 13 14 15 ;;===----------------------------------------------------------------------===;; 16 ;; Tests for crashers 17 ;;===----------------------------------------------------------------------===;; 18 19 ;; PR5016 20 define i8 @crash0({i32, i32} %A, {i32, i32}* %P) { 21 store {i32, i32} %A, {i32, i32}* %P 22 %X = bitcast {i32, i32}* %P to i8* 23 %Y = load i8* %X 24 ret i8 %Y 25 } 26 27 ;; No PR filed, crashed in CaptureTracker. 28 declare void @helper() 29 define void @crash1() { 30 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* undef, i8* undef, i64 undef, i32 1, i1 false) nounwind 31 %tmp = load i8* bitcast (void ()* @helper to i8*) 32 %x = icmp eq i8 %tmp, 15 33 ret void 34 } 35 36 37 ;;===----------------------------------------------------------------------===;; 38 ;; Store -> Load and Load -> Load forwarding where src and dst are different 39 ;; types, but where the base pointer is a must alias. 40 ;;===----------------------------------------------------------------------===;; 41 42 ;; i32 -> f32 forwarding. 43 define float @coerce_mustalias1(i32 %V, i32* %P) { 44 store i32 %V, i32* %P 45 46 %P2 = bitcast i32* %P to float* 47 48 %A = load float* %P2 49 ret float %A 50 ; CHECK-LABEL: @coerce_mustalias1( 51 ; CHECK-NOT: load 52 ; CHECK: ret float 53 } 54 55 ;; i32* -> float forwarding. 56 define float @coerce_mustalias2(i32* %V, i32** %P) { 57 store i32* %V, i32** %P 58 59 %P2 = bitcast i32** %P to float* 60 61 %A = load float* %P2 62 ret float %A 63 ; CHECK-LABEL: @coerce_mustalias2( 64 ; CHECK-NOT: load 65 ; CHECK: ret float 66 } 67 68 ;; float -> i32* forwarding. 69 define i32* @coerce_mustalias3(float %V, float* %P) { 70 store float %V, float* %P 71 72 %P2 = bitcast float* %P to i32** 73 74 %A = load i32** %P2 75 ret i32* %A 76 ; CHECK-LABEL: @coerce_mustalias3( 77 ; CHECK-NOT: load 78 ; CHECK: ret i32* 79 } 80 81 ;; i32 -> f32 load forwarding. 82 define float @coerce_mustalias4(i32* %P, i1 %cond) { 83 %A = load i32* %P 84 85 %P2 = bitcast i32* %P to float* 86 %B = load float* %P2 87 br i1 %cond, label %T, label %F 88 T: 89 ret float %B 90 91 F: 92 %X = bitcast i32 %A to float 93 ret float %X 94 95 ; CHECK-LABEL: @coerce_mustalias4( 96 ; CHECK: %A = load i32* %P 97 ; CHECK-NOT: load 98 ; CHECK: ret float 99 ; CHECK: F: 100 } 101 102 ;; i32 -> i8 forwarding 103 define i8 @coerce_mustalias5(i32 %V, i32* %P) { 104 store i32 %V, i32* %P 105 106 %P2 = bitcast i32* %P to i8* 107 108 %A = load i8* %P2 109 ret i8 %A 110 ; CHECK-LABEL: @coerce_mustalias5( 111 ; CHECK-NOT: load 112 ; CHECK: ret i8 113 } 114 115 ;; i64 -> float forwarding 116 define float @coerce_mustalias6(i64 %V, i64* %P) { 117 store i64 %V, i64* %P 118 119 %P2 = bitcast i64* %P to float* 120 121 %A = load float* %P2 122 ret float %A 123 ; CHECK-LABEL: @coerce_mustalias6( 124 ; CHECK-NOT: load 125 ; CHECK: ret float 126 } 127 128 ;; i64 -> i8* (32-bit) forwarding 129 define i8* @coerce_mustalias7(i64 %V, i64* %P) { 130 store i64 %V, i64* %P 131 132 %P2 = bitcast i64* %P to i8** 133 134 %A = load i8** %P2 135 ret i8* %A 136 ; CHECK-LABEL: @coerce_mustalias7( 137 ; CHECK-NOT: load 138 ; CHECK: ret i8* 139 } 140 141 ; memset -> i16 forwarding. 142 define signext i16 @memset_to_i16_local(i16* %A) nounwind ssp { 143 entry: 144 %conv = bitcast i16* %A to i8* 145 tail call void @llvm.memset.p0i8.i64(i8* %conv, i8 1, i64 200, i32 1, i1 false) 146 %arrayidx = getelementptr inbounds i16* %A, i64 42 147 %tmp2 = load i16* %arrayidx 148 ret i16 %tmp2 149 ; CHECK-LABEL: @memset_to_i16_local( 150 ; CHECK-NOT: load 151 ; CHECK: ret i16 257 152 } 153 154 ; memset -> float forwarding. 155 define float @memset_to_float_local(float* %A, i8 %Val) nounwind ssp { 156 entry: 157 %conv = bitcast float* %A to i8* ; <i8*> [#uses=1] 158 tail call void @llvm.memset.p0i8.i64(i8* %conv, i8 %Val, i64 400, i32 1, i1 false) 159 %arrayidx = getelementptr inbounds float* %A, i64 42 ; <float*> [#uses=1] 160 %tmp2 = load float* %arrayidx ; <float> [#uses=1] 161 ret float %tmp2 162 ; CHECK-LABEL: @memset_to_float_local( 163 ; CHECK-NOT: load 164 ; CHECK: zext 165 ; CHECK-NEXT: shl 166 ; CHECK-NEXT: or 167 ; CHECK-NEXT: shl 168 ; CHECK-NEXT: or 169 ; CHECK-NEXT: bitcast 170 ; CHECK-NEXT: ret float 171 } 172 173 ;; non-local memset -> i16 load forwarding. 174 define i16 @memset_to_i16_nonlocal0(i16* %P, i1 %cond) { 175 %P3 = bitcast i16* %P to i8* 176 br i1 %cond, label %T, label %F 177 T: 178 tail call void @llvm.memset.p0i8.i64(i8* %P3, i8 1, i64 400, i32 1, i1 false) 179 br label %Cont 180 181 F: 182 tail call void @llvm.memset.p0i8.i64(i8* %P3, i8 2, i64 400, i32 1, i1 false) 183 br label %Cont 184 185 Cont: 186 %P2 = getelementptr i16* %P, i32 4 187 %A = load i16* %P2 188 ret i16 %A 189 190 ; CHECK-LABEL: @memset_to_i16_nonlocal0( 191 ; CHECK: Cont: 192 ; CHECK-NEXT: %A = phi i16 [ 514, %F ], [ 257, %T ] 193 ; CHECK-NOT: load 194 ; CHECK: ret i16 %A 195 } 196 197 @GCst = constant {i32, float, i32 } { i32 42, float 14., i32 97 } 198 199 ; memset -> float forwarding. 200 define float @memcpy_to_float_local(float* %A) nounwind ssp { 201 entry: 202 %conv = bitcast float* %A to i8* ; <i8*> [#uses=1] 203 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %conv, i8* bitcast ({i32, float, i32 }* @GCst to i8*), i64 12, i32 1, i1 false) 204 %arrayidx = getelementptr inbounds float* %A, i64 1 ; <float*> [#uses=1] 205 %tmp2 = load float* %arrayidx ; <float> [#uses=1] 206 ret float %tmp2 207 ; CHECK-LABEL: @memcpy_to_float_local( 208 ; CHECK-NOT: load 209 ; CHECK: ret float 1.400000e+01 210 } 211 212 213 214 ;; non-local i32/float -> i8 load forwarding. 215 define i8 @coerce_mustalias_nonlocal0(i32* %P, i1 %cond) { 216 %P2 = bitcast i32* %P to float* 217 %P3 = bitcast i32* %P to i8* 218 br i1 %cond, label %T, label %F 219 T: 220 store i32 42, i32* %P 221 br label %Cont 222 223 F: 224 store float 1.0, float* %P2 225 br label %Cont 226 227 Cont: 228 %A = load i8* %P3 229 ret i8 %A 230 231 ; CHECK-LABEL: @coerce_mustalias_nonlocal0( 232 ; CHECK: Cont: 233 ; CHECK: %A = phi i8 [ 234 ; CHECK-NOT: load 235 ; CHECK: ret i8 %A 236 } 237 238 239 ;; non-local i32/float -> i8 load forwarding. This also tests that the "P3" 240 ;; bitcast equivalence can be properly phi translated. 241 define i8 @coerce_mustalias_nonlocal1(i32* %P, i1 %cond) { 242 %P2 = bitcast i32* %P to float* 243 br i1 %cond, label %T, label %F 244 T: 245 store i32 42, i32* %P 246 br label %Cont 247 248 F: 249 store float 1.0, float* %P2 250 br label %Cont 251 252 Cont: 253 %P3 = bitcast i32* %P to i8* 254 %A = load i8* %P3 255 ret i8 %A 256 257 ; CHECK-LABEL: @coerce_mustalias_nonlocal1( 258 ; CHECK: Cont: 259 ; CHECK: %A = phi i8 [ 260 ; CHECK-NOT: load 261 ; CHECK: ret i8 %A 262 } 263 264 265 ;; non-local i32 -> i8 partial redundancy load forwarding. 266 define i8 @coerce_mustalias_pre0(i32* %P, i1 %cond) { 267 %P3 = bitcast i32* %P to i8* 268 br i1 %cond, label %T, label %F 269 T: 270 store i32 42, i32* %P 271 br label %Cont 272 273 F: 274 br label %Cont 275 276 Cont: 277 %A = load i8* %P3 278 ret i8 %A 279 280 ; CHECK-LABEL: @coerce_mustalias_pre0( 281 ; CHECK: F: 282 ; CHECK: load i8* %P3 283 ; CHECK: Cont: 284 ; CHECK: %A = phi i8 [ 285 ; CHECK-NOT: load 286 ; CHECK: ret i8 %A 287 } 288 289 ;;===----------------------------------------------------------------------===;; 290 ;; Store -> Load and Load -> Load forwarding where src and dst are different 291 ;; types, and the reload is an offset from the store pointer. 292 ;;===----------------------------------------------------------------------===;; 293 294 ;; i32 -> i8 forwarding. 295 ;; PR4216 296 define i8 @coerce_offset0(i32 %V, i32* %P) { 297 store i32 %V, i32* %P 298 299 %P2 = bitcast i32* %P to i8* 300 %P3 = getelementptr i8* %P2, i32 2 301 302 %A = load i8* %P3 303 ret i8 %A 304 ; CHECK-LABEL: @coerce_offset0( 305 ; CHECK-NOT: load 306 ; CHECK: ret i8 307 } 308 309 ;; non-local i32/float -> i8 load forwarding. 310 define i8 @coerce_offset_nonlocal0(i32* %P, i1 %cond) { 311 %P2 = bitcast i32* %P to float* 312 %P3 = bitcast i32* %P to i8* 313 %P4 = getelementptr i8* %P3, i32 2 314 br i1 %cond, label %T, label %F 315 T: 316 store i32 57005, i32* %P 317 br label %Cont 318 319 F: 320 store float 1.0, float* %P2 321 br label %Cont 322 323 Cont: 324 %A = load i8* %P4 325 ret i8 %A 326 327 ; CHECK-LABEL: @coerce_offset_nonlocal0( 328 ; CHECK: Cont: 329 ; CHECK: %A = phi i8 [ 330 ; CHECK-NOT: load 331 ; CHECK: ret i8 %A 332 } 333 334 335 ;; non-local i32 -> i8 partial redundancy load forwarding. 336 define i8 @coerce_offset_pre0(i32* %P, i1 %cond) { 337 %P3 = bitcast i32* %P to i8* 338 %P4 = getelementptr i8* %P3, i32 2 339 br i1 %cond, label %T, label %F 340 T: 341 store i32 42, i32* %P 342 br label %Cont 343 344 F: 345 br label %Cont 346 347 Cont: 348 %A = load i8* %P4 349 ret i8 %A 350 351 ; CHECK-LABEL: @coerce_offset_pre0( 352 ; CHECK: F: 353 ; CHECK: load i8* %P4 354 ; CHECK: Cont: 355 ; CHECK: %A = phi i8 [ 356 ; CHECK-NOT: load 357 ; CHECK: ret i8 %A 358 } 359 360 define i32 @chained_load(i32** %p) { 361 block1: 362 %A = alloca i32* 363 364 %z = load i32** %p 365 store i32* %z, i32** %A 366 br i1 true, label %block2, label %block3 367 368 block2: 369 %a = load i32** %p 370 br label %block4 371 372 block3: 373 %b = load i32** %p 374 br label %block4 375 376 block4: 377 %c = load i32** %p 378 %d = load i32* %c 379 ret i32 %d 380 381 ; CHECK-LABEL: @chained_load( 382 ; CHECK: %z = load i32** %p 383 ; CHECK-NOT: load 384 ; CHECK: %d = load i32* %z 385 ; CHECK-NEXT: ret i32 %d 386 } 387 388 389 declare i1 @cond() readonly 390 declare i1 @cond2() readonly 391 392 define i32 @phi_trans2() { 393 ; CHECK-LABEL: @phi_trans2( 394 entry: 395 %P = alloca i32, i32 400 396 br label %F1 397 398 F1: 399 %A = phi i32 [1, %entry], [2, %F] 400 %cond2 = call i1 @cond() 401 br i1 %cond2, label %T1, label %TY 402 403 T1: 404 %P2 = getelementptr i32* %P, i32 %A 405 %x = load i32* %P2 406 %cond = call i1 @cond2() 407 br i1 %cond, label %TX, label %F 408 409 F: 410 %P3 = getelementptr i32* %P, i32 2 411 store i32 17, i32* %P3 412 413 store i32 42, i32* %P2 ; Provides "P[A]". 414 br label %F1 415 416 TX: 417 ; This load should not be compiled to 'ret i32 42'. An overly clever 418 ; implementation of GVN would see that we're returning 17 if the loop 419 ; executes once or 42 if it executes more than that, but we'd have to do 420 ; loop restructuring to expose this, and GVN shouldn't do this sort of CFG 421 ; transformation. 422 423 ; CHECK: TX: 424 ; CHECK: ret i32 %x 425 ret i32 %x 426 TY: 427 ret i32 0 428 } 429 430 define i32 @phi_trans3(i32* %p) { 431 ; CHECK-LABEL: @phi_trans3( 432 block1: 433 br i1 true, label %block2, label %block3 434 435 block2: 436 store i32 87, i32* %p 437 br label %block4 438 439 block3: 440 %p2 = getelementptr i32* %p, i32 43 441 store i32 97, i32* %p2 442 br label %block4 443 444 block4: 445 %A = phi i32 [-1, %block2], [42, %block3] 446 br i1 true, label %block5, label %exit 447 448 ; CHECK: block4: 449 ; CHECK-NEXT: %D = phi i32 [ 87, %block2 ], [ 97, %block3 ] 450 ; CHECK-NOT: load 451 452 block5: 453 %B = add i32 %A, 1 454 br i1 true, label %block6, label %exit 455 456 block6: 457 %C = getelementptr i32* %p, i32 %B 458 br i1 true, label %block7, label %exit 459 460 block7: 461 %D = load i32* %C 462 ret i32 %D 463 464 ; CHECK: block7: 465 ; CHECK-NEXT: ret i32 %D 466 467 exit: 468 ret i32 -1 469 } 470 471 define i8 @phi_trans4(i8* %p) { 472 ; CHECK-LABEL: @phi_trans4( 473 entry: 474 %X3 = getelementptr i8* %p, i32 192 475 store i8 192, i8* %X3 476 477 %X = getelementptr i8* %p, i32 4 478 %Y = load i8* %X 479 br label %loop 480 481 loop: 482 %i = phi i32 [4, %entry], [192, %loop] 483 %X2 = getelementptr i8* %p, i32 %i 484 %Y2 = load i8* %X2 485 486 ; CHECK: loop: 487 ; CHECK-NEXT: %Y2 = phi i8 [ %Y, %entry ], [ 0, %loop ] 488 ; CHECK-NOT: load i8 489 490 %cond = call i1 @cond2() 491 492 %Z = bitcast i8 *%X3 to i32* 493 store i32 0, i32* %Z 494 br i1 %cond, label %loop, label %out 495 496 out: 497 %R = add i8 %Y, %Y2 498 ret i8 %R 499 } 500 501 define i8 @phi_trans5(i8* %p) { 502 ; CHECK-LABEL: @phi_trans5( 503 entry: 504 505 %X4 = getelementptr i8* %p, i32 2 506 store i8 19, i8* %X4 507 508 %X = getelementptr i8* %p, i32 4 509 %Y = load i8* %X 510 br label %loop 511 512 loop: 513 %i = phi i32 [4, %entry], [3, %cont] 514 %X2 = getelementptr i8* %p, i32 %i 515 %Y2 = load i8* %X2 ; Ensure this load is not being incorrectly replaced. 516 %cond = call i1 @cond2() 517 br i1 %cond, label %cont, label %out 518 519 cont: 520 %Z = getelementptr i8* %X2, i32 -1 521 %Z2 = bitcast i8 *%Z to i32* 522 store i32 50462976, i32* %Z2 ;; (1 << 8) | (2 << 16) | (3 << 24) 523 524 525 ; CHECK: store i32 526 ; CHECK-NEXT: getelementptr i8* %p, i32 3 527 ; CHECK-NEXT: load i8* 528 br label %loop 529 530 out: 531 %R = add i8 %Y, %Y2 532 ret i8 %R 533 } 534 535 536 ; PR6642 537 define i32 @memset_to_load() nounwind readnone { 538 entry: 539 %x = alloca [256 x i32], align 4 ; <[256 x i32]*> [#uses=2] 540 %tmp = bitcast [256 x i32]* %x to i8* ; <i8*> [#uses=1] 541 call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 1024, i32 4, i1 false) 542 %arraydecay = getelementptr inbounds [256 x i32]* %x, i32 0, i32 0 ; <i32*> 543 %tmp1 = load i32* %arraydecay ; <i32> [#uses=1] 544 ret i32 %tmp1 545 ; CHECK-LABEL: @memset_to_load( 546 ; CHECK: ret i32 0 547 } 548 549 550 ;;===----------------------------------------------------------------------===;; 551 ;; Load -> Load forwarding in partial alias case. 552 ;;===----------------------------------------------------------------------===;; 553 554 define i32 @load_load_partial_alias(i8* %P) nounwind ssp { 555 entry: 556 %0 = bitcast i8* %P to i32* 557 %tmp2 = load i32* %0 558 %add.ptr = getelementptr inbounds i8* %P, i64 1 559 %tmp5 = load i8* %add.ptr 560 %conv = zext i8 %tmp5 to i32 561 %add = add nsw i32 %tmp2, %conv 562 ret i32 %add 563 564 ; TEMPORARILYDISABLED-LABEL: @load_load_partial_alias( 565 ; TEMPORARILYDISABLED: load i32* 566 ; TEMPORARILYDISABLED-NOT: load 567 ; TEMPORARILYDISABLED: lshr i32 {{.*}}, 8 568 ; TEMPORARILYDISABLED-NOT: load 569 ; TEMPORARILYDISABLED: trunc i32 {{.*}} to i8 570 ; TEMPORARILYDISABLED-NOT: load 571 ; TEMPORARILYDISABLED: ret i32 572 } 573 574 575 ; Cross block partial alias case. 576 define i32 @load_load_partial_alias_cross_block(i8* %P) nounwind ssp { 577 entry: 578 %xx = bitcast i8* %P to i32* 579 %x1 = load i32* %xx, align 4 580 %cmp = icmp eq i32 %x1, 127 581 br i1 %cmp, label %land.lhs.true, label %if.end 582 583 land.lhs.true: ; preds = %entry 584 %arrayidx4 = getelementptr inbounds i8* %P, i64 1 585 %tmp5 = load i8* %arrayidx4, align 1 586 %conv6 = zext i8 %tmp5 to i32 587 ret i32 %conv6 588 589 if.end: 590 ret i32 52 591 ; TEMPORARILY_DISABLED-LABEL: @load_load_partial_alias_cross_block( 592 ; TEMPORARILY_DISABLED: land.lhs.true: 593 ; TEMPORARILY_DISABLED-NOT: load i8 594 ; TEMPORARILY_DISABLED: ret i32 %conv6 595 } 596 597 598 ;;===----------------------------------------------------------------------===;; 599 ;; Load Widening 600 ;;===----------------------------------------------------------------------===;; 601 602 %widening1 = type { i32, i8, i8, i8, i8 } 603 604 @f = global %widening1 zeroinitializer, align 4 605 606 define i32 @test_widening1(i8* %P) nounwind ssp noredzone { 607 entry: 608 %tmp = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 1), align 4 609 %conv = zext i8 %tmp to i32 610 %tmp1 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 2), align 1 611 %conv2 = zext i8 %tmp1 to i32 612 %add = add nsw i32 %conv, %conv2 613 ret i32 %add 614 ; CHECK-LABEL: @test_widening1( 615 ; CHECK-NOT: load 616 ; CHECK: load i16* 617 ; CHECK-NOT: load 618 ; CHECK: ret i32 619 } 620 621 define i32 @test_widening2() nounwind ssp noredzone { 622 entry: 623 %tmp = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 1), align 4 624 %conv = zext i8 %tmp to i32 625 %tmp1 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 2), align 1 626 %conv2 = zext i8 %tmp1 to i32 627 %add = add nsw i32 %conv, %conv2 628 629 %tmp2 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 3), align 2 630 %conv3 = zext i8 %tmp2 to i32 631 %add2 = add nsw i32 %add, %conv3 632 633 %tmp3 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 4), align 1 634 %conv4 = zext i8 %tmp3 to i32 635 %add3 = add nsw i32 %add2, %conv3 636 637 ret i32 %add3 638 ; CHECK-LABEL: @test_widening2( 639 ; CHECK-NOT: load 640 ; CHECK: load i32* 641 ; CHECK-NOT: load 642 ; CHECK: ret i32 643 } 644 645 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind 646 647 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind 648 649 ;;===----------------------------------------------------------------------===;; 650 ;; Load -> Store dependency which isn't interfered with by a call that happens 651 ;; before the pointer was captured. 652 ;;===----------------------------------------------------------------------===;; 653 654 %class.X = type { [8 x i8] } 655 656 @_ZTV1X = weak_odr constant [5 x i8*] zeroinitializer 657 @_ZTV1Y = weak_odr constant [5 x i8*] zeroinitializer 658 659 declare void @use() 660 declare void @use3(i8***, i8**) 661 662 ; PR8908 663 define void @test_escape1() nounwind { 664 %x = alloca i8**, align 8 665 store i8** getelementptr inbounds ([5 x i8*]* @_ZTV1X, i64 0, i64 2), i8*** %x, align 8 666 call void @use() nounwind 667 %DEAD = load i8*** %x, align 8 668 call void @use3(i8*** %x, i8** %DEAD) nounwind 669 ret void 670 ; CHECK: test_escape1 671 ; CHECK-NOT: DEAD 672 ; CHECK: ret 673 } 674