Home | History | Annotate | Download | only in GVN
      1 ; RUN: opt < %s -gvn -S | FileCheck %s
      2 
      3 %struct.A = type { i32 (...)** }
      4 @_ZTV1A = available_externally unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast (i8** @_ZTI1A to i8*), i8* bitcast (i32 (%struct.A*)* @_ZN1A3fooEv to i8*), i8* bitcast (i32 (%struct.A*)* @_ZN1A3barEv to i8*)], align 8
      5 @_ZTI1A = external constant i8*
      6 
      7 ; Checks if indirect calls can be replaced with direct
      8 ; assuming that %vtable == @_ZTV1A (with alignment).
      9 ; Checking const propagation across other BBs
     10 ; CHECK-LABEL: define void @_Z1gb(
     11 
     12 define void @_Z1gb(i1 zeroext %p) {
     13 entry:
     14   %call = tail call noalias i8* @_Znwm(i64 8) #4
     15   %0 = bitcast i8* %call to %struct.A*
     16   tail call void @_ZN1AC1Ev(%struct.A* %0) #1
     17   %1 = bitcast i8* %call to i8***
     18   %vtable = load i8**, i8*** %1, align 8
     19   %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTV1A, i64 0, i64 2)
     20   tail call void @llvm.assume(i1 %cmp.vtables)
     21   br i1 %p, label %if.then, label %if.else
     22 
     23 if.then:                                          ; preds = %entry
     24   %vtable1.cast = bitcast i8** %vtable to i32 (%struct.A*)**
     25   %2 = load i32 (%struct.A*)*, i32 (%struct.A*)** %vtable1.cast, align 8
     26   
     27   ; CHECK: call i32 @_ZN1A3fooEv(
     28   %call2 = tail call i32 %2(%struct.A* %0) #1
     29   
     30   br label %if.end
     31 
     32 if.else:                                          ; preds = %entry
     33   %vfn47 = getelementptr inbounds i8*, i8** %vtable, i64 1
     34   %vfn4 = bitcast i8** %vfn47 to i32 (%struct.A*)**
     35   
     36   ; CHECK: call i32 @_ZN1A3barEv(
     37   %3 = load i32 (%struct.A*)*, i32 (%struct.A*)** %vfn4, align 8
     38   
     39   %call5 = tail call i32 %3(%struct.A* %0) #1
     40   br label %if.end
     41 
     42 if.end:                                           ; preds = %if.else, %if.then
     43   ret void
     44 }
     45 
     46 ; Check integration with invariant.group handling
     47 ; CHECK-LABEL: define void @invariantGroupHandling(i1 zeroext %p) {
     48 define void @invariantGroupHandling(i1 zeroext %p) {
     49 entry:
     50   %call = tail call noalias i8* @_Znwm(i64 8) #4
     51   %0 = bitcast i8* %call to %struct.A*
     52   tail call void @_ZN1AC1Ev(%struct.A* %0) #1
     53   %1 = bitcast i8* %call to i8***
     54   %vtable = load i8**, i8*** %1, align 8, !invariant.group !0
     55   %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTV1A, i64 0, i64 2)
     56   tail call void @llvm.assume(i1 %cmp.vtables)
     57   br i1 %p, label %if.then, label %if.else
     58 
     59 if.then:                                          ; preds = %entry
     60   %vtable1.cast = bitcast i8** %vtable to i32 (%struct.A*)**
     61   %2 = load i32 (%struct.A*)*, i32 (%struct.A*)** %vtable1.cast, align 8
     62   
     63 ; CHECK: call i32 @_ZN1A3fooEv(
     64   %call2 = tail call i32 %2(%struct.A* %0) #1
     65   %vtable1 = load i8**, i8*** %1, align 8, !invariant.group !0
     66   %vtable2.cast = bitcast i8** %vtable1 to i32 (%struct.A*)**
     67   %call1 = load i32 (%struct.A*)*, i32 (%struct.A*)** %vtable2.cast, align 8
     68 ; CHECK: call i32 @_ZN1A3fooEv(
     69   %callx = tail call i32 %call1(%struct.A* %0) #1
     70   
     71   %vtable2 = load i8**, i8*** %1, align 8, !invariant.group !0
     72   %vtable3.cast = bitcast i8** %vtable2 to i32 (%struct.A*)**
     73   %call4 = load i32 (%struct.A*)*, i32 (%struct.A*)** %vtable3.cast, align 8
     74 ; CHECK: call i32 @_ZN1A3fooEv(
     75   %cally = tail call i32 %call4(%struct.A* %0) #1
     76   
     77   %b = bitcast i8* %call to %struct.A**
     78   %vtable3 = load %struct.A*, %struct.A** %b, align 8, !invariant.group !0
     79   %vtable4.cast = bitcast %struct.A* %vtable3 to i32 (%struct.A*)**
     80   %vfun = load i32 (%struct.A*)*, i32 (%struct.A*)** %vtable4.cast, align 8
     81 ; CHECK: call i32 @_ZN1A3fooEv(
     82   %unknown = tail call i32 %vfun(%struct.A* %0) #1
     83   
     84   br label %if.end
     85 
     86 if.else:                                          ; preds = %entry
     87   %vfn47 = getelementptr inbounds i8*, i8** %vtable, i64 1
     88   %vfn4 = bitcast i8** %vfn47 to i32 (%struct.A*)**
     89   
     90   ; CHECK: call i32 @_ZN1A3barEv(
     91   %3 = load i32 (%struct.A*)*, i32 (%struct.A*)** %vfn4, align 8
     92   
     93   %call5 = tail call i32 %3(%struct.A* %0) #1
     94   br label %if.end
     95 
     96 if.end:                                           ; preds = %if.else, %if.then
     97   ret void
     98 }
     99 
    100 
    101 ; Checking const propagation in the same BB
    102 ; CHECK-LABEL: define i32 @main()
    103 
    104 define i32 @main() {
    105 entry:
    106   %call = tail call noalias i8* @_Znwm(i64 8) 
    107   %0 = bitcast i8* %call to %struct.A*
    108   tail call void @_ZN1AC1Ev(%struct.A* %0) 
    109   %1 = bitcast i8* %call to i8***
    110   %vtable = load i8**, i8*** %1, align 8
    111   %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTV1A, i64 0, i64 2)
    112   tail call void @llvm.assume(i1 %cmp.vtables)
    113   %vtable1.cast = bitcast i8** %vtable to i32 (%struct.A*)**
    114   
    115   ; CHECK: call i32 @_ZN1A3fooEv(
    116   %2 = load i32 (%struct.A*)*, i32 (%struct.A*)** %vtable1.cast, align 8
    117   
    118   %call2 = tail call i32 %2(%struct.A* %0)
    119   ret i32 0
    120 }
    121 
    122 ; This tests checks const propatation with fcmp instruction.
    123 ; CHECK-LABEL: define float @_Z1gf(float %p)
    124 
    125 define float @_Z1gf(float %p) {
    126 entry:
    127   %p.addr = alloca float, align 4
    128   %f = alloca float, align 4
    129   store float %p, float* %p.addr, align 4
    130   
    131   store float 3.000000e+00, float* %f, align 4
    132   %0 = load float, float* %p.addr, align 4
    133   %1 = load float, float* %f, align 4
    134   %cmp = fcmp oeq float %1, %0 ; note const on lhs
    135   call void @llvm.assume(i1 %cmp)
    136   
    137   ; CHECK: ret float 3.000000e+00
    138   ret float %0
    139 }
    140 
    141 ; CHECK-LABEL: define float @_Z1hf(float %p)
    142 
    143 define float @_Z1hf(float %p) {
    144 entry:
    145   %p.addr = alloca float, align 4
    146   store float %p, float* %p.addr, align 4
    147   
    148   %0 = load float, float* %p.addr, align 4
    149   %cmp = fcmp nnan ueq float %0, 3.000000e+00
    150   call void @llvm.assume(i1 %cmp)
    151   
    152   ; CHECK: ret float 3.000000e+00
    153   ret float %0
    154 }
    155 
    156 ; CHECK-LABEL: define float @_Z1if(float %p)
    157 define float @_Z1if(float %p) {
    158 entry:
    159   %p.addr = alloca float, align 4
    160   store float %p, float* %p.addr, align 4
    161   
    162   %0 = load float, float* %p.addr, align 4
    163   %cmp = fcmp ueq float %0, 3.000000e+00 ; no nnan flag - can't propagate
    164   call void @llvm.assume(i1 %cmp)
    165   
    166   ; CHECK-NOT: ret float 3.000000e+00
    167   ret float %0
    168 }
    169 
    170 ; This test checks if constant propagation works for multiple node edges
    171 ; CHECK-LABEL: define i32 @_Z1ii(i32 %p)
    172 define i32 @_Z1ii(i32 %p) {
    173 entry:
    174   %cmp = icmp eq i32 %p, 42
    175   call void @llvm.assume(i1 %cmp)
    176   
    177   ; CHECK: br i1 true, label %bb2, label %bb2
    178   br i1 %cmp, label %bb2, label %bb2
    179 bb2:
    180   call void @llvm.assume(i1 true)
    181   ; CHECK: br i1 true, label %bb2, label %bb2
    182   br i1 %cmp, label %bb2, label %bb2
    183   
    184   ; CHECK: ret i32 42
    185   ret i32 %p
    186 }
    187 
    188 ; CHECK-LABEL: define i32 @_Z1ij(i32 %p)
    189 define i32 @_Z1ij(i32 %p) {
    190 entry:
    191   %cmp = icmp eq i32 %p, 42
    192   call void @llvm.assume(i1 %cmp)
    193   
    194   ; CHECK: br i1 true, label %bb2, label %bb2
    195   br i1 %cmp, label %bb2, label %bb2
    196 bb2:
    197    ; CHECK-NOT: %cmp2 = 
    198   %cmp2 = icmp eq i32 %p, 42
    199   ; CHECK-NOT: call void @llvm.assume(
    200   call void @llvm.assume(i1 %cmp2)
    201   
    202   ; CHECK: br i1 true, label %bb2, label %bb2
    203   br i1 %cmp, label %bb2, label %bb2
    204   
    205   ; CHECK: ret i32 42
    206   ret i32 %p
    207 }
    208 
    209 ; CHECK-LABEL: define i32 @_Z1ik(i32 %p)
    210 define i32 @_Z1ik(i32 %p) {
    211 entry:
    212   %cmp = icmp eq i32 %p, 42
    213   call void @llvm.assume(i1 %cmp)
    214   
    215   ; CHECK: br i1 true, label %bb2, label %bb3
    216   br i1 %cmp, label %bb2, label %bb3
    217 bb2:
    218   ; CHECK-NOT: %cmp3 = 
    219   %cmp3 = icmp eq i32 %p, 43
    220   ; CHECK: store i8 undef, i8* null
    221   call void @llvm.assume(i1 %cmp3)
    222   ret i32 15
    223 bb3:
    224   ret i32 17
    225 }
    226 
    227 ; This test checks if GVN can do the constant propagation correctly
    228 ; when there are multiple uses of the same assume value in the 
    229 ; basic block that has a loop back-edge pointing to itself.
    230 ;
    231 ; CHECK-LABEL: define i32 @_Z1il(i32 %val, i1 %k)
    232 define i32 @_Z1il(i32 %val, i1 %k) {
    233   br label %next
    234 
    235 next:
    236 ; CHECK: tail call void @llvm.assume(i1 %k)
    237 ; CHECK-NEXT: %cmp = icmp eq i32 %val, 50
    238   tail call void @llvm.assume(i1 %k)
    239   tail call void @llvm.assume(i1 %k)
    240   %cmp = icmp eq i32 %val, 50
    241   br i1 %cmp, label %next, label %meh
    242 
    243 meh:
    244   ret i32 0 
    245 }
    246 
    247 ; This test checks if GVN can prevent the constant propagation correctly
    248 ; in the successor blocks that are not dominated by the basic block
    249 ; with the assume instruction.
    250 ;
    251 ; CHECK-LABEL: define i1 @_z1im(i32 %val, i1 %k, i1 %j)
    252 define i1 @_z1im(i32 %val, i1 %k, i1 %j) {
    253   br i1 %j, label %next, label %meh
    254 
    255 next:
    256 ; CHECK: tail call void @llvm.assume(i1 %k)
    257 ; CHECK-NEXT: br label %meh
    258   tail call void @llvm.assume(i1 %k)
    259   tail call void @llvm.assume(i1 %k)
    260   br label %meh
    261 
    262 meh:
    263 ; CHECK: ret i1 %k
    264   ret i1 %k
    265 }
    266 
    267 declare noalias i8* @_Znwm(i64)
    268 declare void @_ZN1AC1Ev(%struct.A*)
    269 declare void @llvm.assume(i1)
    270 declare i32 @_ZN1A3fooEv(%struct.A*)
    271 declare i32 @_ZN1A3barEv(%struct.A*)
    272 
    273 !0 = !{!"struct A"}
    274