Home | History | Annotate | Download | only in GVN
      1 ; RUN: opt < %s -default-data-layout="e-p:32:32:32-p1:16:16:16-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-p1:16:16:16-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 @GCst_as1 = addrspace(1) constant {i32, float, i32 } { i32 42, float 14., i32 97 }
    199 
    200 ; memset -> float forwarding.
    201 define float @memcpy_to_float_local(float* %A) nounwind ssp {
    202 entry:
    203   %conv = bitcast float* %A to i8*                ; <i8*> [#uses=1]
    204   tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %conv, i8* bitcast ({i32, float, i32 }* @GCst to i8*), i64 12, i32 1, i1 false)
    205   %arrayidx = getelementptr inbounds float* %A, i64 1 ; <float*> [#uses=1]
    206   %tmp2 = load float* %arrayidx                   ; <float> [#uses=1]
    207   ret float %tmp2
    208 ; CHECK-LABEL: @memcpy_to_float_local(
    209 ; CHECK-NOT: load
    210 ; CHECK: ret float 1.400000e+01
    211 }
    212 
    213 ; memcpy from address space 1
    214 define float @memcpy_to_float_local_as1(float* %A) nounwind ssp {
    215 entry:
    216   %conv = bitcast float* %A to i8*                ; <i8*> [#uses=1]
    217   tail call void @llvm.memcpy.p0i8.p1i8.i64(i8* %conv, i8 addrspace(1)* bitcast ({i32, float, i32 } addrspace(1)* @GCst_as1 to i8 addrspace(1)*), i64 12, i32 1, i1 false)
    218   %arrayidx = getelementptr inbounds float* %A, i64 1 ; <float*> [#uses=1]
    219   %tmp2 = load float* %arrayidx                   ; <float> [#uses=1]
    220   ret float %tmp2
    221 ; CHECK-LABEL: @memcpy_to_float_local_as1(
    222 ; CHECK-NOT: load
    223 ; CHECK: ret float 1.400000e+01
    224 }
    225 
    226 ;; non-local i32/float -> i8 load forwarding.
    227 define i8 @coerce_mustalias_nonlocal0(i32* %P, i1 %cond) {
    228   %P2 = bitcast i32* %P to float*
    229   %P3 = bitcast i32* %P to i8*
    230   br i1 %cond, label %T, label %F
    231 T:
    232   store i32 42, i32* %P
    233   br label %Cont
    234   
    235 F:
    236   store float 1.0, float* %P2
    237   br label %Cont
    238 
    239 Cont:
    240   %A = load i8* %P3
    241   ret i8 %A
    242 
    243 ; CHECK-LABEL: @coerce_mustalias_nonlocal0(
    244 ; CHECK: Cont:
    245 ; CHECK:   %A = phi i8 [
    246 ; CHECK-NOT: load
    247 ; CHECK: ret i8 %A
    248 }
    249 
    250 
    251 ;; non-local i32/float -> i8 load forwarding.  This also tests that the "P3"
    252 ;; bitcast equivalence can be properly phi translated.
    253 define i8 @coerce_mustalias_nonlocal1(i32* %P, i1 %cond) {
    254   %P2 = bitcast i32* %P to float*
    255   br i1 %cond, label %T, label %F
    256 T:
    257   store i32 42, i32* %P
    258   br label %Cont
    259   
    260 F:
    261   store float 1.0, float* %P2
    262   br label %Cont
    263 
    264 Cont:
    265   %P3 = bitcast i32* %P to i8*
    266   %A = load i8* %P3
    267   ret i8 %A
    268 
    269 ; CHECK-LABEL: @coerce_mustalias_nonlocal1(
    270 ; CHECK: Cont:
    271 ; CHECK:   %A = phi i8 [
    272 ; CHECK-NOT: load
    273 ; CHECK: ret i8 %A
    274 }
    275 
    276 
    277 ;; non-local i32 -> i8 partial redundancy load forwarding.
    278 define i8 @coerce_mustalias_pre0(i32* %P, i1 %cond) {
    279   %P3 = bitcast i32* %P to i8*
    280   br i1 %cond, label %T, label %F
    281 T:
    282   store i32 42, i32* %P
    283   br label %Cont
    284   
    285 F:
    286   br label %Cont
    287 
    288 Cont:
    289   %A = load i8* %P3
    290   ret i8 %A
    291 
    292 ; CHECK-LABEL: @coerce_mustalias_pre0(
    293 ; CHECK: F:
    294 ; CHECK:   load i8* %P3
    295 ; CHECK: Cont:
    296 ; CHECK:   %A = phi i8 [
    297 ; CHECK-NOT: load
    298 ; CHECK: ret i8 %A
    299 }
    300 
    301 ;;===----------------------------------------------------------------------===;;
    302 ;; Store -> Load  and  Load -> Load forwarding where src and dst are different
    303 ;; types, and the reload is an offset from the store pointer.
    304 ;;===----------------------------------------------------------------------===;;
    305 
    306 ;; i32 -> i8 forwarding.
    307 ;; PR4216
    308 define i8 @coerce_offset0(i32 %V, i32* %P) {
    309   store i32 %V, i32* %P
    310    
    311   %P2 = bitcast i32* %P to i8*
    312   %P3 = getelementptr i8* %P2, i32 2
    313 
    314   %A = load i8* %P3
    315   ret i8 %A
    316 ; CHECK-LABEL: @coerce_offset0(
    317 ; CHECK-NOT: load
    318 ; CHECK: ret i8
    319 }
    320 
    321 ;; non-local i32/float -> i8 load forwarding.
    322 define i8 @coerce_offset_nonlocal0(i32* %P, i1 %cond) {
    323   %P2 = bitcast i32* %P to float*
    324   %P3 = bitcast i32* %P to i8*
    325   %P4 = getelementptr i8* %P3, i32 2
    326   br i1 %cond, label %T, label %F
    327 T:
    328   store i32 57005, i32* %P
    329   br label %Cont
    330   
    331 F:
    332   store float 1.0, float* %P2
    333   br label %Cont
    334 
    335 Cont:
    336   %A = load i8* %P4
    337   ret i8 %A
    338 
    339 ; CHECK-LABEL: @coerce_offset_nonlocal0(
    340 ; CHECK: Cont:
    341 ; CHECK:   %A = phi i8 [
    342 ; CHECK-NOT: load
    343 ; CHECK: ret i8 %A
    344 }
    345 
    346 
    347 ;; non-local i32 -> i8 partial redundancy load forwarding.
    348 define i8 @coerce_offset_pre0(i32* %P, i1 %cond) {
    349   %P3 = bitcast i32* %P to i8*
    350   %P4 = getelementptr i8* %P3, i32 2
    351   br i1 %cond, label %T, label %F
    352 T:
    353   store i32 42, i32* %P
    354   br label %Cont
    355   
    356 F:
    357   br label %Cont
    358 
    359 Cont:
    360   %A = load i8* %P4
    361   ret i8 %A
    362 
    363 ; CHECK-LABEL: @coerce_offset_pre0(
    364 ; CHECK: F:
    365 ; CHECK:   load i8* %P4
    366 ; CHECK: Cont:
    367 ; CHECK:   %A = phi i8 [
    368 ; CHECK-NOT: load
    369 ; CHECK: ret i8 %A
    370 }
    371 
    372 define i32 @chained_load(i32** %p, i32 %x, i32 %y) {
    373 block1:
    374   %A = alloca i32*
    375 
    376   %z = load i32** %p
    377   store i32* %z, i32** %A
    378   %cmp = icmp eq i32 %x, %y
    379   br i1 %cmp, label %block2, label %block3
    380 
    381 block2:
    382  %a = load i32** %p
    383  br label %block4
    384 
    385 block3:
    386   %b = load i32** %p
    387   br label %block4
    388 
    389 block4:
    390   %c = load i32** %p
    391   %d = load i32* %c
    392   ret i32 %d
    393   
    394 ; CHECK-LABEL: @chained_load(
    395 ; CHECK: %z = load i32** %p
    396 ; CHECK-NOT: load
    397 ; CHECK: %d = load i32* %z
    398 ; CHECK-NEXT: ret i32 %d
    399 }
    400 
    401 
    402 declare i1 @cond() readonly
    403 declare i1 @cond2() readonly
    404 
    405 define i32 @phi_trans2() {
    406 ; CHECK-LABEL: @phi_trans2(
    407 entry:
    408   %P = alloca i32, i32 400
    409   br label %F1
    410   
    411 F1:
    412   %A = phi i32 [1, %entry], [2, %F]
    413   %cond2 = call i1 @cond()
    414   br i1 %cond2, label %T1, label %TY
    415   
    416 T1:
    417   %P2 = getelementptr i32* %P, i32 %A
    418   %x = load i32* %P2
    419   %cond = call i1 @cond2()
    420   br i1 %cond, label %TX, label %F
    421   
    422 F:
    423   %P3 = getelementptr i32* %P, i32 2
    424   store i32 17, i32* %P3
    425   
    426   store i32 42, i32* %P2  ; Provides "P[A]".
    427   br label %F1
    428 
    429 TX:
    430   ; This load should not be compiled to 'ret i32 42'.  An overly clever
    431   ; implementation of GVN would see that we're returning 17 if the loop
    432   ; executes once or 42 if it executes more than that, but we'd have to do
    433   ; loop restructuring to expose this, and GVN shouldn't do this sort of CFG
    434   ; transformation.
    435   
    436 ; CHECK: TX:
    437 ; CHECK: ret i32 %x
    438   ret i32 %x
    439 TY:
    440   ret i32 0
    441 }
    442 
    443 define i32 @phi_trans3(i32* %p, i32 %x, i32 %y, i32 %z) {
    444 ; CHECK-LABEL: @phi_trans3(
    445 block1:
    446   %cmpxy = icmp eq i32 %x, %y
    447   br i1 %cmpxy, label %block2, label %block3
    448 
    449 block2:
    450  store i32 87, i32* %p
    451  br label %block4
    452 
    453 block3:
    454   %p2 = getelementptr i32* %p, i32 43
    455   store i32 97, i32* %p2
    456   br label %block4
    457 
    458 block4:
    459   %A = phi i32 [-1, %block2], [42, %block3]
    460   br i1 %cmpxy, label %block5, label %exit
    461   
    462 ; CHECK: block4:
    463 ; CHECK-NEXT: %D = phi i32 [ 87, %block2 ], [ 97, %block3 ]  
    464 ; CHECK-NOT: load
    465 
    466 block5:
    467   %B = add i32 %A, 1
    468   br i1 %cmpxy, label %block6, label %exit
    469   
    470 block6:
    471   %C = getelementptr i32* %p, i32 %B
    472   br i1 %cmpxy, label %block7, label %exit
    473   
    474 block7:
    475   %D = load i32* %C
    476   ret i32 %D
    477   
    478 ; CHECK: block7:
    479 ; CHECK-NEXT: ret i32 %D
    480 
    481 exit:
    482   ret i32 -1
    483 }
    484 
    485 define i8 @phi_trans4(i8* %p) {
    486 ; CHECK-LABEL: @phi_trans4(
    487 entry:
    488   %X3 = getelementptr i8* %p, i32 192
    489   store i8 192, i8* %X3
    490   
    491   %X = getelementptr i8* %p, i32 4
    492   %Y = load i8* %X
    493   br label %loop
    494 
    495 loop:
    496   %i = phi i32 [4, %entry], [192, %loop]
    497   %X2 = getelementptr i8* %p, i32 %i
    498   %Y2 = load i8* %X2
    499   
    500 ; CHECK: loop:
    501 ; CHECK-NEXT: %Y2 = phi i8 [ %Y, %entry ], [ 0, %loop ]
    502 ; CHECK-NOT: load i8
    503   
    504   %cond = call i1 @cond2()
    505 
    506   %Z = bitcast i8 *%X3 to i32*
    507   store i32 0, i32* %Z
    508   br i1 %cond, label %loop, label %out
    509   
    510 out:
    511   %R = add i8 %Y, %Y2
    512   ret i8 %R
    513 }
    514 
    515 define i8 @phi_trans5(i8* %p) {
    516 ; CHECK-LABEL: @phi_trans5(
    517 entry:
    518   
    519   %X4 = getelementptr i8* %p, i32 2
    520   store i8 19, i8* %X4
    521   
    522   %X = getelementptr i8* %p, i32 4
    523   %Y = load i8* %X
    524   br label %loop
    525 
    526 loop:
    527   %i = phi i32 [4, %entry], [3, %cont]
    528   %X2 = getelementptr i8* %p, i32 %i
    529   %Y2 = load i8* %X2  ; Ensure this load is not being incorrectly replaced.
    530   %cond = call i1 @cond2()
    531   br i1 %cond, label %cont, label %out
    532 
    533 cont:
    534   %Z = getelementptr i8* %X2, i32 -1
    535   %Z2 = bitcast i8 *%Z to i32*
    536   store i32 50462976, i32* %Z2  ;; (1 << 8) | (2 << 16) | (3 << 24)
    537 
    538 
    539 ; CHECK: store i32
    540 ; CHECK-NEXT: getelementptr i8* %p, i32 3
    541 ; CHECK-NEXT: load i8*
    542   br label %loop
    543   
    544 out:
    545   %R = add i8 %Y, %Y2
    546   ret i8 %R
    547 }
    548 
    549 
    550 ; PR6642
    551 define i32 @memset_to_load() nounwind readnone {
    552 entry:
    553   %x = alloca [256 x i32], align 4                ; <[256 x i32]*> [#uses=2]
    554   %tmp = bitcast [256 x i32]* %x to i8*           ; <i8*> [#uses=1]
    555   call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 1024, i32 4, i1 false)
    556   %arraydecay = getelementptr inbounds [256 x i32]* %x, i32 0, i32 0 ; <i32*>
    557   %tmp1 = load i32* %arraydecay                   ; <i32> [#uses=1]
    558   ret i32 %tmp1
    559 ; CHECK-LABEL: @memset_to_load(
    560 ; CHECK: ret i32 0
    561 }
    562 
    563 
    564 ;;===----------------------------------------------------------------------===;;
    565 ;; Load -> Load forwarding in partial alias case.
    566 ;;===----------------------------------------------------------------------===;;
    567 
    568 define i32 @load_load_partial_alias(i8* %P) nounwind ssp {
    569 entry:
    570   %0 = bitcast i8* %P to i32*
    571   %tmp2 = load i32* %0
    572   %add.ptr = getelementptr inbounds i8* %P, i64 1
    573   %tmp5 = load i8* %add.ptr
    574   %conv = zext i8 %tmp5 to i32
    575   %add = add nsw i32 %tmp2, %conv
    576   ret i32 %add
    577 
    578 ; TEMPORARILYDISABLED-LABEL: @load_load_partial_alias(
    579 ; TEMPORARILYDISABLED: load i32*
    580 ; TEMPORARILYDISABLED-NOT: load
    581 ; TEMPORARILYDISABLED: lshr i32 {{.*}}, 8
    582 ; TEMPORARILYDISABLED-NOT: load
    583 ; TEMPORARILYDISABLED: trunc i32 {{.*}} to i8
    584 ; TEMPORARILYDISABLED-NOT: load
    585 ; TEMPORARILYDISABLED: ret i32
    586 }
    587 
    588 
    589 ; Cross block partial alias case.
    590 define i32 @load_load_partial_alias_cross_block(i8* %P) nounwind ssp {
    591 entry:
    592   %xx = bitcast i8* %P to i32*
    593   %x1 = load i32* %xx, align 4
    594   %cmp = icmp eq i32 %x1, 127
    595   br i1 %cmp, label %land.lhs.true, label %if.end
    596 
    597 land.lhs.true:                                    ; preds = %entry
    598   %arrayidx4 = getelementptr inbounds i8* %P, i64 1
    599   %tmp5 = load i8* %arrayidx4, align 1
    600   %conv6 = zext i8 %tmp5 to i32
    601   ret i32 %conv6
    602 
    603 if.end:
    604   ret i32 52
    605 ; TEMPORARILY_DISABLED-LABEL: @load_load_partial_alias_cross_block(
    606 ; TEMPORARILY_DISABLED: land.lhs.true:
    607 ; TEMPORARILY_DISABLED-NOT: load i8
    608 ; TEMPORARILY_DISABLED: ret i32 %conv6
    609 }
    610 
    611 
    612 ;;===----------------------------------------------------------------------===;;
    613 ;; Load Widening
    614 ;;===----------------------------------------------------------------------===;;
    615 
    616 %widening1 = type { i32, i8, i8, i8, i8 }
    617 
    618 @f = global %widening1 zeroinitializer, align 4
    619 
    620 define i32 @test_widening1(i8* %P) nounwind ssp noredzone {
    621 entry:
    622   %tmp = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 1), align 4
    623   %conv = zext i8 %tmp to i32
    624   %tmp1 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 2), align 1
    625   %conv2 = zext i8 %tmp1 to i32
    626   %add = add nsw i32 %conv, %conv2
    627   ret i32 %add
    628 ; CHECK-LABEL: @test_widening1(
    629 ; CHECK-NOT: load
    630 ; CHECK: load i16*
    631 ; CHECK-NOT: load
    632 ; CHECK: ret i32
    633 }
    634 
    635 define i32 @test_widening2() nounwind ssp noredzone {
    636 entry:
    637   %tmp = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 1), align 4
    638   %conv = zext i8 %tmp to i32
    639   %tmp1 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 2), align 1
    640   %conv2 = zext i8 %tmp1 to i32
    641   %add = add nsw i32 %conv, %conv2
    642 
    643   %tmp2 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 3), align 2
    644   %conv3 = zext i8 %tmp2 to i32
    645   %add2 = add nsw i32 %add, %conv3
    646 
    647   %tmp3 = load i8* getelementptr inbounds (%widening1* @f, i64 0, i32 4), align 1
    648   %conv4 = zext i8 %tmp3 to i32
    649   %add3 = add nsw i32 %add2, %conv3
    650 
    651   ret i32 %add3
    652 ; CHECK-LABEL: @test_widening2(
    653 ; CHECK-NOT: load
    654 ; CHECK: load i32*
    655 ; CHECK-NOT: load
    656 ; CHECK: ret i32
    657 }
    658 
    659 declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind
    660 
    661 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind
    662 declare void @llvm.memcpy.p0i8.p1i8.i64(i8* nocapture, i8 addrspace(1)* nocapture, i64, i32, i1) nounwind
    663 
    664 
    665 ;;===----------------------------------------------------------------------===;;
    666 ;; Load -> Store dependency which isn't interfered with by a call that happens
    667 ;; before the pointer was captured.
    668 ;;===----------------------------------------------------------------------===;;
    669 
    670 %class.X = type { [8 x i8] }
    671 
    672 @_ZTV1X = weak_odr constant [5 x i8*] zeroinitializer
    673 @_ZTV1Y = weak_odr constant [5 x i8*] zeroinitializer
    674 
    675 declare void @use()
    676 declare void @use3(i8***, i8**)
    677 
    678 ; PR8908
    679 define void @test_escape1() nounwind {
    680   %x = alloca i8**, align 8
    681   store i8** getelementptr inbounds ([5 x i8*]* @_ZTV1X, i64 0, i64 2), i8*** %x, align 8
    682   call void @use() nounwind
    683   %DEAD = load i8*** %x, align 8
    684   call void @use3(i8*** %x, i8** %DEAD) nounwind
    685   ret void
    686 ; CHECK: test_escape1
    687 ; CHECK-NOT: DEAD
    688 ; CHECK: ret
    689 }
    690