Home | History | Annotate | Download | only in NewGVN
      1 ; XFAIL: *
      2 ; RUN: opt < %s -newgvn -S | FileCheck %s
      3 
      4 %struct.A = type { i32 (...)** }
      5 @_ZTV1A = available_externally unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast (i8** @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A3fooEv to i8*)], align 8
      6 @_ZTI1A = external constant i8*
      7 
      8 @unknownPtr = external global i8
      9 
     10 ; CHECK-LABEL: define i8 @simple() {
     11 define i8 @simple() {
     12 entry:
     13     %ptr = alloca i8
     14     store i8 42, i8* %ptr, !invariant.group !0
     15     call void @foo(i8* %ptr)
     16 
     17     %a = load i8, i8* %ptr, !invariant.group !0
     18     %b = load i8, i8* %ptr, !invariant.group !0
     19     %c = load i8, i8* %ptr, !invariant.group !0
     20 ; CHECK: ret i8 42
     21     ret i8 %a
     22 }
     23 
     24 ; CHECK-LABEL: define i8 @optimizable1() {
     25 define i8 @optimizable1() {
     26 entry:
     27     %ptr = alloca i8
     28     store i8 42, i8* %ptr, !invariant.group !0
     29     %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
     30     %a = load i8, i8* %ptr, !invariant.group !0
     31     
     32     call void @foo(i8* %ptr2); call to use %ptr2
     33 ; CHECK: ret i8 42
     34     ret i8 %a
     35 }
     36 
     37 ; CHECK-LABEL: define i8 @optimizable2() {
     38 define i8 @optimizable2() {
     39 entry:
     40     %ptr = alloca i8
     41     store i8 42, i8* %ptr, !invariant.group !0
     42     call void @foo(i8* %ptr)
     43     
     44     store i8 13, i8* %ptr ; can't use this store with invariant.group
     45     %a = load i8, i8* %ptr 
     46     call void @bar(i8 %a) ; call to use %a
     47     
     48     call void @foo(i8* %ptr)
     49     %b = load i8, i8* %ptr, !invariant.group !0
     50     
     51 ; CHECK: ret i8 42
     52     ret i8 %b
     53 }
     54 
     55 ; CHECK-LABEL: define i1 @proveEqualityForStrip(
     56 define i1 @proveEqualityForStrip(i8* %a) {
     57 ; FIXME: The first call could be also removed by GVN. Right now
     58 ; DCE removes it. The second call is CSE'd with the first one.
     59 ; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
     60   %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
     61 ; CHECK-NOT: llvm.strip.invariant.group
     62   %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
     63   %r = icmp eq i8* %b1, %b2
     64 ; CHECK: ret i1 true
     65   ret i1 %r
     66 }
     67 
     68 ; CHECK-LABEL: define i8 @unoptimizable1() {
     69 define i8 @unoptimizable1() {
     70 entry:
     71     %ptr = alloca i8
     72     store i8 42, i8* %ptr
     73     call void @foo(i8* %ptr)
     74     %a = load i8, i8* %ptr, !invariant.group !0
     75 ; CHECK: ret i8 %a
     76     ret i8 %a
     77 }
     78 
     79 ; CHECK-LABEL: define void @indirectLoads() {
     80 define void @indirectLoads() {
     81 entry:
     82   %a = alloca %struct.A*, align 8
     83   %0 = bitcast %struct.A** %a to i8*
     84   
     85   %call = call i8* @getPointer(i8* null) 
     86   %1 = bitcast i8* %call to %struct.A*
     87   call void @_ZN1AC1Ev(%struct.A* %1)
     88   %2 = bitcast %struct.A* %1 to i8***
     89   
     90 ; CHECK: %vtable = load {{.*}} !invariant.group
     91   %vtable = load i8**, i8*** %2, align 8, !invariant.group !0
     92   %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
     93   call void @llvm.assume(i1 %cmp.vtables)
     94   
     95   store %struct.A* %1, %struct.A** %a, align 8
     96   %3 = load %struct.A*, %struct.A** %a, align 8
     97   %4 = bitcast %struct.A* %3 to void (%struct.A*)***
     98 
     99 ; CHECK: call void @_ZN1A3fooEv(
    100   %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
    101   %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
    102   %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
    103   call void %5(%struct.A* %3)
    104   %6 = load %struct.A*, %struct.A** %a, align 8
    105   %7 = bitcast %struct.A* %6 to void (%struct.A*)***
    106 
    107 ; CHECK: call void @_ZN1A3fooEv(
    108   %vtable2 = load void (%struct.A*)**, void (%struct.A*)*** %7, align 8, !invariant.group !0
    109   %vfn3 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable2, i64 0
    110   %8 = load void (%struct.A*)*, void (%struct.A*)** %vfn3, align 8
    111   
    112   call void %8(%struct.A* %6)
    113   %9 = load %struct.A*, %struct.A** %a, align 8
    114   %10 = bitcast %struct.A* %9 to void (%struct.A*)***
    115   
    116   %vtable4 = load void (%struct.A*)**, void (%struct.A*)*** %10, align 8, !invariant.group !0
    117   %vfn5 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable4, i64 0
    118   %11 = load void (%struct.A*)*, void (%struct.A*)** %vfn5, align 8
    119 ; CHECK: call void @_ZN1A3fooEv(
    120   call void %11(%struct.A* %9)
    121  
    122   %vtable5 = load i8**, i8*** %2, align 8, !invariant.group !0
    123   %vfn6 = getelementptr inbounds i8*, i8** %vtable5, i64 0
    124   %12 = bitcast i8** %vfn6 to void (%struct.A*)**
    125   %13 = load void (%struct.A*)*, void (%struct.A*)** %12, align 8
    126 ; CHECK: call void @_ZN1A3fooEv(
    127   call void %13(%struct.A* %9)
    128   
    129   ret void
    130 }
    131 
    132 ; CHECK-LABEL: define void @combiningBitCastWithLoad() {
    133 define void @combiningBitCastWithLoad() {
    134 entry:
    135   %a = alloca %struct.A*, align 8
    136   %0 = bitcast %struct.A** %a to i8*
    137   
    138   %call = call i8* @getPointer(i8* null) 
    139   %1 = bitcast i8* %call to %struct.A*
    140   call void @_ZN1AC1Ev(%struct.A* %1)
    141   %2 = bitcast %struct.A* %1 to i8***
    142   
    143 ; CHECK: %vtable = load {{.*}} !invariant.group
    144   %vtable = load i8**, i8*** %2, align 8, !invariant.group !0
    145   %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
    146   
    147   store %struct.A* %1, %struct.A** %a, align 8
    148 ; CHECK-NOT: !invariant.group
    149   %3 = load %struct.A*, %struct.A** %a, align 8
    150   %4 = bitcast %struct.A* %3 to void (%struct.A*)***
    151 
    152   %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
    153   %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
    154   %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
    155   call void %5(%struct.A* %3)
    156 
    157   ret void
    158 }
    159 
    160 ; CHECK-LABEL:define void @loadCombine() {
    161 define void @loadCombine() {
    162 enter:
    163   %ptr = alloca i8
    164   store i8 42, i8* %ptr
    165   call void @foo(i8* %ptr)
    166 ; CHECK: %[[A:.*]] = load i8, i8* %ptr, !invariant.group
    167   %a = load i8, i8* %ptr, !invariant.group !0
    168 ; CHECK-NOT: load
    169   %b = load i8, i8* %ptr, !invariant.group !0
    170 ; CHECK: call void @bar(i8 %[[A]])
    171   call void @bar(i8 %a)
    172 ; CHECK: call void @bar(i8 %[[A]])
    173   call void @bar(i8 %b)
    174   ret void
    175 }
    176 
    177 ; CHECK-LABEL: define void @loadCombine1() {
    178 define void @loadCombine1() {
    179 enter:
    180   %ptr = alloca i8
    181   store i8 42, i8* %ptr
    182   call void @foo(i8* %ptr)
    183 ; CHECK: %[[D:.*]] = load i8, i8* %ptr, !invariant.group
    184   %c = load i8, i8* %ptr
    185 ; CHECK-NOT: load
    186   %d = load i8, i8* %ptr, !invariant.group !0
    187 ; CHECK: call void @bar(i8 %[[D]])
    188   call void @bar(i8 %c)
    189 ; CHECK: call void @bar(i8 %[[D]])
    190   call void @bar(i8 %d)
    191   ret void
    192 }
    193 
    194 ; CHECK-LABEL: define void @loadCombine2() {    
    195 define void @loadCombine2() {
    196 enter:
    197   %ptr = alloca i8
    198   store i8 42, i8* %ptr
    199   call void @foo(i8* %ptr)
    200 ; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
    201   %e = load i8, i8* %ptr, !invariant.group !0
    202 ; CHECK-NOT: load
    203   %f = load i8, i8* %ptr
    204 ; CHECK: call void @bar(i8 %[[E]])
    205   call void @bar(i8 %e)
    206 ; CHECK: call void @bar(i8 %[[E]])
    207   call void @bar(i8 %f)
    208   ret void
    209 }
    210 
    211 ; CHECK-LABEL: define void @loadCombine3() {
    212 define void @loadCombine3() {
    213 enter:
    214   %ptr = alloca i8
    215   store i8 42, i8* %ptr
    216   call void @foo(i8* %ptr)
    217 ; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
    218   %e = load i8, i8* %ptr, !invariant.group !0
    219 ; CHECK-NOT: load
    220   %f = load i8, i8* %ptr, !invariant.group !0
    221 ; CHECK: call void @bar(i8 %[[E]])
    222   call void @bar(i8 %e)
    223 ; CHECK: call void @bar(i8 %[[E]])
    224   call void @bar(i8 %f)
    225   ret void
    226 }
    227 
    228 ; CHECK-LABEL: define i8 @unoptimizable2() {
    229 define i8 @unoptimizable2() {
    230 entry:
    231     %ptr = alloca i8
    232     store i8 42, i8* %ptr
    233     call void @foo(i8* %ptr)
    234     %a = load i8, i8* %ptr
    235     call void @foo(i8* %ptr)
    236     %b = load i8, i8* %ptr, !invariant.group !0
    237     
    238 ; CHECK: ret i8 %a
    239     ret i8 %a
    240 }
    241 
    242 ; CHECK-LABEL: define i8 @unoptimizable3() {
    243 define i8 @unoptimizable3() {
    244 entry:
    245     %ptr = alloca i8
    246     store i8 42, i8* %ptr, !invariant.group !0
    247     %ptr2 = call i8* @getPointer(i8* %ptr)
    248     %a = load i8, i8* %ptr2, !invariant.group !0
    249     
    250 ; CHECK: ret i8 %a
    251     ret i8 %a
    252 }
    253 
    254 ; CHECK-LABEL: define i8 @optimizable4() {
    255 define i8 @optimizable4() {
    256 entry:
    257     %ptr = alloca i8
    258     store i8 42, i8* %ptr, !invariant.group !0
    259     %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
    260 ; CHECK-NOT: load
    261     %a = load i8, i8* %ptr2, !invariant.group !0
    262     
    263 ; CHECK: ret i8 42
    264     ret i8 %a
    265 }
    266 
    267 ; CHECK-LABEL: define i8 @volatile1() {
    268 define i8 @volatile1() {
    269 entry:
    270     %ptr = alloca i8
    271     store i8 42, i8* %ptr, !invariant.group !0
    272     call void @foo(i8* %ptr)
    273     %a = load i8, i8* %ptr, !invariant.group !0
    274     %b = load volatile i8, i8* %ptr
    275 ; CHECK: call void @bar(i8 %b)
    276     call void @bar(i8 %b)
    277 
    278     %c = load volatile i8, i8* %ptr, !invariant.group !0
    279 ; FIXME: we could change %c to 42, preserving volatile load
    280 ; CHECK: call void @bar(i8 %c)
    281     call void @bar(i8 %c)
    282 ; CHECK: ret i8 42
    283     ret i8 %a
    284 }
    285 
    286 ; CHECK-LABEL: define i8 @volatile2() {
    287 define i8 @volatile2() {
    288 entry:
    289     %ptr = alloca i8
    290     store i8 42, i8* %ptr, !invariant.group !0
    291     call void @foo(i8* %ptr)
    292     %a = load i8, i8* %ptr, !invariant.group !0
    293     %b = load volatile i8, i8* %ptr
    294 ; CHECK: call void @bar(i8 %b)
    295     call void @bar(i8 %b)
    296 
    297     %c = load volatile i8, i8* %ptr, !invariant.group !0
    298 ; FIXME: we could change %c to 42, preserving volatile load
    299 ; CHECK: call void @bar(i8 %c)
    300     call void @bar(i8 %c)
    301 ; CHECK: ret i8 42
    302     ret i8 %a
    303 }
    304 
    305 ; CHECK-LABEL: define i8 @fun() {
    306 define i8 @fun() {
    307 entry:
    308     %ptr = alloca i8
    309     store i8 42, i8* %ptr, !invariant.group !0
    310     call void @foo(i8* %ptr)
    311 
    312     %a = load i8, i8* %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change
    313 ; CHECK: call void @bar(i8 42)
    314     call void @bar(i8 %a)
    315 
    316     %newPtr = call i8* @getPointer(i8* %ptr) 
    317     %c = load i8, i8* %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr
    318 ; CHECK: call void @bar(i8 %c)
    319     call void @bar(i8 %c)
    320     
    321     %unknownValue = load i8, i8* @unknownPtr
    322 ; FIXME: Can assume that %unknownValue == 42
    323 ; CHECK: store i8 %unknownValue, i8* %ptr, !invariant.group !0
    324     store i8 %unknownValue, i8* %ptr, !invariant.group !0 
    325 
    326     %newPtr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
    327 ; CHECK-NOT: load
    328     %d = load i8, i8* %newPtr2, !invariant.group !0
    329 ; CHECK: ret i8 %unknownValue
    330     ret i8 %d
    331 }
    332 
    333 ; This test checks if invariant.group understands gep with zeros
    334 ; CHECK-LABEL: define void @testGEP0() {
    335 define void @testGEP0() {
    336   %a = alloca %struct.A, align 8
    337   %1 = bitcast %struct.A* %a to i8*
    338   %2 = getelementptr inbounds %struct.A, %struct.A* %a, i64 0, i32 0
    339   store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**), i32 (...)*** %2, align 8, !invariant.group !0
    340 ; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull dereferenceable(8) %a)
    341   call void @_ZN1A3fooEv(%struct.A* nonnull dereferenceable(8) %a) ; This call may change vptr
    342   %3 = load i8, i8* @unknownPtr, align 4
    343   %4 = icmp eq i8 %3, 0
    344   br i1 %4, label %_Z1gR1A.exit, label %5
    345 
    346 ; This should be devirtualized by invariant.group
    347   %6 = bitcast %struct.A* %a to void (%struct.A*)***
    348   %7 = load void (%struct.A*)**, void (%struct.A*)*** %6, align 8, !invariant.group !0
    349   %8 = load void (%struct.A*)*, void (%struct.A*)** %7, align 8
    350 ; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull %a)
    351   call void %8(%struct.A* nonnull %a)
    352   br label %_Z1gR1A.exit
    353 
    354 _Z1gR1A.exit:                                     ; preds = %0, %5
    355   ret void
    356 }
    357 
    358 ; Check if no optimizations are performed with global pointers.
    359 ; FIXME: we could do the optimizations if we would check if dependency comes
    360 ; from the same function.
    361 ; CHECK-LABEL: define void @testGlobal() {
    362 define void @testGlobal() {
    363 ; CHECK:  %a = load i8, i8* @unknownPtr, !invariant.group !0
    364    %a = load i8, i8* @unknownPtr, !invariant.group !0
    365    call void @foo2(i8* @unknownPtr, i8 %a)
    366 ; CHECK:  %1 = load i8, i8* @unknownPtr, !invariant.group !0
    367    %1 = load i8, i8* @unknownPtr, !invariant.group !0
    368    call void @bar(i8 %1)
    369 
    370    %b0 = bitcast i8* @unknownPtr to i1*
    371    call void @fooBit(i1* %b0, i1 1)
    372 ; Adding regex because of canonicalization of bitcasts
    373 ; CHECK: %2 = load i1, i1* {{.*}}, !invariant.group !0
    374    %2 = load i1, i1* %b0, !invariant.group !0
    375    call void @fooBit(i1* %b0, i1 %2)
    376 ; CHECK:  %3 = load i1, i1* {{.*}}, !invariant.group !0
    377    %3 = load i1, i1* %b0, !invariant.group !0
    378    call void @fooBit(i1* %b0, i1 %3)
    379    ret void
    380 }
    381 ; And in the case it is not global
    382 ; CHECK-LABEL: define void @testNotGlobal() {
    383 define void @testNotGlobal() {
    384    %a = alloca i8
    385    call void @foo(i8* %a)
    386 ; CHECK:  %b = load i8, i8* %a, !invariant.group !0
    387    %b = load i8, i8* %a, !invariant.group !0
    388    call void @foo2(i8* %a, i8 %b)
    389 
    390    %1 = load i8, i8* %a, !invariant.group !0
    391 ; CHECK: call void @bar(i8 %b)
    392    call void @bar(i8 %1)
    393 
    394    %b0 = bitcast i8* %a to i1*
    395    call void @fooBit(i1* %b0, i1 1)
    396 ; CHECK: %1 = trunc i8 %b to i1
    397    %2 = load i1, i1* %b0, !invariant.group !0
    398 ; CHECK-NEXT: call void @fooBit(i1* %b0, i1 %1)
    399    call void @fooBit(i1* %b0, i1 %2)
    400    %3 = load i1, i1* %b0, !invariant.group !0
    401 ; CHECK-NEXT: call void @fooBit(i1* %b0, i1 %1)
    402    call void @fooBit(i1* %b0, i1 %3)
    403    ret void
    404 }
    405 
    406 ; CHECK-LABEL: define void @handling_loops()
    407 define void @handling_loops() {
    408   %a = alloca %struct.A, align 8
    409   %1 = bitcast %struct.A* %a to i8*
    410   %2 = getelementptr inbounds %struct.A, %struct.A* %a, i64 0, i32 0
    411   store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**), i32 (...)*** %2, align 8, !invariant.group !0
    412   %3 = load i8, i8* @unknownPtr, align 4
    413   %4 = icmp sgt i8 %3, 0
    414   br i1 %4, label %.lr.ph.i, label %_Z2g2R1A.exit
    415 
    416 .lr.ph.i:                                         ; preds = %0
    417   %5 = bitcast %struct.A* %a to void (%struct.A*)***
    418   %6 = load i8, i8* @unknownPtr, align 4
    419   %7 = icmp sgt i8 %6, 1
    420   br i1 %7, label %._crit_edge.preheader, label %_Z2g2R1A.exit
    421 
    422 ._crit_edge.preheader:                            ; preds = %.lr.ph.i
    423   br label %._crit_edge
    424 
    425 ._crit_edge:                                      ; preds = %._crit_edge.preheader, %._crit_edge
    426   %8 = phi i8 [ %10, %._crit_edge ], [ 1, %._crit_edge.preheader ]
    427   %.pre = load void (%struct.A*)**, void (%struct.A*)*** %5, align 8, !invariant.group !0
    428   %9 = load void (%struct.A*)*, void (%struct.A*)** %.pre, align 8
    429   ; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull %a)
    430   call void %9(%struct.A* nonnull %a) #3
    431   ; CHECK-NOT: call void %
    432   %10 = add nuw nsw i8 %8, 1
    433   %11 = load i8, i8* @unknownPtr, align 4
    434   %12 = icmp slt i8 %10, %11
    435   br i1 %12, label %._crit_edge, label %_Z2g2R1A.exit.loopexit
    436 
    437 _Z2g2R1A.exit.loopexit:                           ; preds = %._crit_edge
    438   br label %_Z2g2R1A.exit
    439 
    440 _Z2g2R1A.exit:                                    ; preds = %_Z2g2R1A.exit.loopexit, %.lr.ph.i, %0
    441   ret void
    442 }
    443 
    444 
    445 declare void @foo(i8*)
    446 declare void @foo2(i8*, i8)
    447 declare void @bar(i8)
    448 declare i8* @getPointer(i8*)
    449 declare void @_ZN1A3fooEv(%struct.A*)
    450 declare void @_ZN1AC1Ev(%struct.A*)
    451 declare void @fooBit(i1*, i1)
    452 
    453 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
    454 
    455 ; Function Attrs: nounwind
    456 declare void @llvm.assume(i1 %cmp.vtables) #0
    457 
    458 
    459 attributes #0 = { nounwind }
    460 !0 = !{}