Home | History | Annotate | Download | only in CorrelatedValuePropagation
      1 ; RUN: opt < %s -correlated-propagation -S | FileCheck %s
      2 ; PR2581
      3 
      4 ; CHECK-LABEL: @test1(
      5 define i32 @test1(i1 %C) nounwind  {
      6         br i1 %C, label %exit, label %body
      7 
      8 body:           ; preds = %0
      9 ; CHECK-NOT: select
     10         %A = select i1 %C, i32 10, i32 11               ; <i32> [#uses=1]
     11 ; CHECK: ret i32 11
     12         ret i32 %A
     13 
     14 exit:           ; preds = %0
     15 ; CHECK: ret i32 10
     16         ret i32 10
     17 }
     18 
     19 ; PR4420
     20 declare i1 @ext()
     21 ; CHECK-LABEL: @test2(
     22 define i1 @test2() {
     23 entry:
     24         %cond = tail call i1 @ext()             ; <i1> [#uses=2]
     25         br i1 %cond, label %bb1, label %bb2
     26 
     27 bb1:            ; preds = %entry
     28         %cond2 = tail call i1 @ext()            ; <i1> [#uses=1]
     29         br i1 %cond2, label %bb3, label %bb2
     30 
     31 bb2:            ; preds = %bb1, %entry
     32 ; CHECK-NOT: phi i1
     33         %cond_merge = phi i1 [ %cond, %entry ], [ false, %bb1 ]         ; <i1> [#uses=1]
     34 ; CHECK: ret i1 false
     35         ret i1 %cond_merge
     36 
     37 bb3:            ; preds = %bb1
     38         %res = tail call i1 @ext()              ; <i1> [#uses=1]
     39 ; CHECK: ret i1 %res
     40         ret i1 %res
     41 }
     42 
     43 ; PR4855
     44 @gv = internal constant i8 7
     45 ; CHECK-LABEL: @test3(
     46 define i8 @test3(i8* %a) nounwind {
     47 entry:
     48         %cond = icmp eq i8* %a, @gv
     49         br i1 %cond, label %bb2, label %bb
     50 
     51 bb:             ; preds = %entry
     52         ret i8 0
     53 
     54 bb2:            ; preds = %entry
     55 ; CHECK: %should_be_const = load i8, i8* @gv
     56         %should_be_const = load i8, i8* %a
     57         ret i8 %should_be_const
     58 }
     59 
     60 ; PR1757
     61 ; CHECK-LABEL: @test4(
     62 define i32 @test4(i32) {
     63 EntryBlock:
     64 ; CHECK: icmp sgt i32 %0, 2  
     65   %.demorgan = icmp sgt i32 %0, 2    
     66   br i1 %.demorgan, label %GreaterThanTwo, label %LessThanOrEqualToTwo
     67 
     68 GreaterThanTwo:
     69 ; CHECK-NOT: icmp eq i32 %0, 2
     70   icmp eq i32 %0, 2
     71 ; CHECK: br i1 false
     72   br i1 %1, label %Impossible, label %NotTwoAndGreaterThanTwo
     73 
     74 NotTwoAndGreaterThanTwo:
     75   ret i32 2
     76 
     77 Impossible:
     78   ret i32 1
     79 
     80 LessThanOrEqualToTwo:
     81   ret i32 0
     82 }
     83 
     84 declare i32* @f(i32*)
     85 define void @test5(i32* %x, i32* %y) {
     86 ; CHECK-LABEL: @test5(
     87 entry:
     88   %pre = icmp eq i32* %x, null
     89   br i1 %pre, label %return, label %loop
     90 
     91 loop:
     92   %phi = phi i32* [ %sel, %loop ], [ %x, %entry ]
     93 ; CHECK: %phi = phi i32* [ %f, %loop ], [ %x, %entry ]
     94   %f = tail call i32* @f(i32* %phi)
     95   %cmp1 = icmp ne i32* %f, %y
     96   %sel = select i1 %cmp1, i32* %f, i32* null
     97   %cmp2 = icmp eq i32* %sel, null
     98   br i1 %cmp2, label %return, label %loop
     99 
    100 return:
    101   ret void
    102 }
    103 
    104 define i32 @switch1(i32 %s) {
    105 ; CHECK-LABEL: @switch1(
    106 entry:
    107   %cmp = icmp slt i32 %s, 0
    108   br i1 %cmp, label %negative, label %out
    109 
    110 negative:
    111   switch i32 %s, label %out [
    112 ; CHECK: switch i32 %s, label %out
    113     i32 0, label %out
    114 ; CHECK-NOT: i32 0
    115     i32 1, label %out
    116 ; CHECK-NOT: i32 1
    117     i32 -1, label %next
    118 ; CHECK: i32 -1, label %next
    119     i32 -2, label %next
    120 ; CHECK: i32 -2, label %next
    121     i32 2, label %out
    122 ; CHECK-NOT: i32 2
    123     i32 3, label %out
    124 ; CHECK-NOT: i32 3
    125   ]
    126 
    127 out:
    128   %p = phi i32 [ 1, %entry ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ], [ -1, %negative ]
    129   ret i32 %p
    130 
    131 next:
    132   %q = phi i32 [ 0, %negative ], [ 0, %negative ]
    133   ret i32 %q
    134 }
    135 
    136 define i32 @switch2(i32 %s) {
    137 ; CHECK-LABEL: @switch2(
    138 entry:
    139   %cmp = icmp sgt i32 %s, 0
    140   br i1 %cmp, label %positive, label %out
    141 
    142 positive:
    143   switch i32 %s, label %out [
    144     i32 0, label %out
    145     i32 -1, label %next
    146     i32 -2, label %next
    147   ]
    148 ; CHECK: br label %out
    149 
    150 out:
    151   %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
    152   ret i32 %p
    153 
    154 next:
    155   %q = phi i32 [ 0, %positive ], [ 0, %positive ]
    156   ret i32 %q
    157 }
    158 
    159 define i32 @switch3(i32 %s) {
    160 ; CHECK-LABEL: @switch3(
    161 entry:
    162   %cmp = icmp sgt i32 %s, 0
    163   br i1 %cmp, label %positive, label %out
    164 
    165 positive:
    166   switch i32 %s, label %out [
    167     i32 -1, label %out
    168     i32 -2, label %next
    169     i32 -3, label %next
    170   ]
    171 ; CHECK: br label %out
    172 
    173 out:
    174   %p = phi i32 [ -1, %entry ], [ 1, %positive ], [ 1, %positive ]
    175   ret i32 %p
    176 
    177 next:
    178   %q = phi i32 [ 0, %positive ], [ 0, %positive ]
    179   ret i32 %q
    180 }
    181 
    182 define void @switch4(i32 %s) {
    183 ; CHECK-LABEL: @switch4(
    184 entry:
    185   %cmp = icmp eq i32 %s, 0
    186   br i1 %cmp, label %zero, label %out
    187 
    188 zero:
    189   switch i32 %s, label %out [
    190     i32 0, label %next
    191     i32 1, label %out
    192     i32 -1, label %out
    193   ]
    194 ; CHECK: br label %next
    195 
    196 out:
    197   ret void
    198 
    199 next:
    200   ret void
    201 }
    202 
    203 define i1 @arg_attribute(i8* nonnull %a) {
    204 ; CHECK-LABEL: @arg_attribute(
    205 ; CHECK: ret i1 false
    206   %cmp = icmp eq i8* %a, null
    207   br label %exit
    208 
    209 exit:
    210   ret i1 %cmp
    211 }
    212 
    213 declare nonnull i8* @return_nonnull()
    214 define i1 @call_attribute() {
    215 ; CHECK-LABEL: @call_attribute(
    216 ; CHECK: ret i1 false
    217   %a = call i8* @return_nonnull()
    218   %cmp = icmp eq i8* %a, null
    219   br label %exit
    220 
    221 exit:
    222   ret i1 %cmp
    223 }
    224 
    225 define i1 @umin(i32 %a, i32 %b) {
    226 ; CHECK-LABEL: @umin(
    227 entry:
    228   %cmp = icmp ult i32 %a, 5
    229   br i1 %cmp, label %a_guard, label %out
    230 
    231 a_guard:
    232   %cmp2 = icmp ult i32 %b, 20
    233   br i1 %cmp2, label %b_guard, label %out
    234 
    235 b_guard:
    236   %sel_cmp = icmp ult i32 %a, %b
    237   %min = select i1 %sel_cmp, i32 %a, i32 %b
    238   %res = icmp eq i32 %min, 7
    239   br label %next
    240 next:
    241 ; CHECK: next:
    242 ; CHECK: ret i1 false
    243   ret i1 %res
    244 out:
    245   ret i1 false
    246 }
    247 
    248 define i1 @smin(i32 %a, i32 %b) {
    249 ; CHECK-LABEL: @smin(
    250 entry:
    251   %cmp = icmp ult i32 %a, 5
    252   br i1 %cmp, label %a_guard, label %out
    253 
    254 a_guard:
    255   %cmp2 = icmp ult i32 %b, 20
    256   br i1 %cmp2, label %b_guard, label %out
    257 
    258 b_guard:
    259   %sel_cmp = icmp sle i32 %a, %b
    260   %min = select i1 %sel_cmp, i32 %a, i32 %b
    261   %res = icmp eq i32 %min, 7
    262   br label %next
    263 next:
    264 ; CHECK: next:
    265 ; CHECK: ret i1 false
    266   ret i1 %res
    267 out:
    268   ret i1 false
    269 }
    270 
    271 define i1 @smax(i32 %a, i32 %b) {
    272 ; CHECK-LABEL: @smax(
    273 entry:
    274   %cmp = icmp sgt i32 %a, 5
    275   br i1 %cmp, label %a_guard, label %out
    276 
    277 a_guard:
    278   %cmp2 = icmp sgt i32 %b, 20
    279   br i1 %cmp2, label %b_guard, label %out
    280 
    281 b_guard:
    282   %sel_cmp = icmp sge i32 %a, %b
    283   %max = select i1 %sel_cmp, i32 %a, i32 %b
    284   %res = icmp eq i32 %max, 7
    285   br label %next
    286 next:
    287 ; CHECK: next:
    288 ; CHECK: ret i1 false
    289   ret i1 %res
    290 out:
    291   ret i1 false
    292 }
    293 
    294 define i1 @umax(i32 %a, i32 %b) {
    295 ; CHECK-LABEL: @umax(
    296 entry:
    297   %cmp = icmp sgt i32 %a, 5
    298   br i1 %cmp, label %a_guard, label %out
    299 
    300 a_guard:
    301   %cmp2 = icmp sgt i32 %b, 20
    302   br i1 %cmp2, label %b_guard, label %out
    303 
    304 b_guard:
    305   %sel_cmp = icmp uge i32 %a, %b
    306   %max = select i1 %sel_cmp, i32 %a, i32 %b
    307   %res = icmp eq i32 %max, 7
    308   br label %next
    309 next:
    310 ; CHECK: next:
    311 ; CHECK: ret i1 false
    312   ret i1 %res
    313 out:
    314   ret i1 false
    315 }
    316 
    317 define i1 @clamp_low1(i32 %a) {
    318 ; CHECK-LABEL: @clamp_low1(
    319 entry:
    320   %cmp = icmp sge i32 %a, 5
    321   br i1 %cmp, label %a_guard, label %out
    322 
    323 a_guard:
    324   %sel_cmp = icmp eq i32 %a, 5
    325   %add = add i32 %a, -1
    326   %sel = select i1 %sel_cmp, i32 5, i32 %a
    327   %res = icmp eq i32 %sel, 4
    328   br label %next
    329 next:
    330 ; CHECK: next:
    331 ; CHECK: ret i1 false
    332   ret i1 %res
    333 out:
    334   ret i1 false
    335 }
    336 
    337 define i1 @clamp_low2(i32 %a) {
    338 ; CHECK-LABEL: @clamp_low2(
    339 entry:
    340   %cmp = icmp sge i32 %a, 5
    341   br i1 %cmp, label %a_guard, label %out
    342 
    343 a_guard:
    344   %sel_cmp = icmp ne i32 %a, 5
    345   %add = add i32 %a, -1
    346   %sel = select i1 %sel_cmp, i32 %a, i32 5
    347   %res = icmp eq i32 %sel, 4
    348   br label %next
    349 next:
    350 ; CHECK: next:
    351 ; CHECK: ret i1 false
    352   ret i1 %res
    353 out:
    354   ret i1 false
    355 }
    356 
    357 define i1 @clamp_high1(i32 %a) {
    358 ; CHECK-LABEL: @clamp_high1(
    359 entry:
    360   %cmp = icmp sle i32 %a, 5
    361   br i1 %cmp, label %a_guard, label %out
    362 
    363 a_guard:
    364   %sel_cmp = icmp eq i32 %a, 5
    365   %add = add i32 %a, 1
    366   %sel = select i1 %sel_cmp, i32 5, i32 %a
    367   %res = icmp eq i32 %sel, 6
    368   br label %next
    369 next:
    370 ; CHECK: next:
    371 ; CHECK: ret i1 false
    372   ret i1 %res
    373 out:
    374   ret i1 false
    375 }
    376 
    377 define i1 @clamp_high2(i32 %a) {
    378 ; CHECK-LABEL: @clamp_high2(
    379 entry:
    380   %cmp = icmp sle i32 %a, 5
    381   br i1 %cmp, label %a_guard, label %out
    382 
    383 a_guard:
    384   %sel_cmp = icmp ne i32 %a, 5
    385   %add = add i32 %a, 1
    386   %sel = select i1 %sel_cmp, i32 %a, i32 5
    387   %res = icmp eq i32 %sel, 6
    388   br label %next
    389 next:
    390 ; CHECK: next:
    391 ; CHECK: ret i1 false
    392   ret i1 %res
    393 out:
    394   ret i1 false
    395 }
    396 
    397 ; Just showing arbitrary constants work, not really a clamp
    398 define i1 @clamp_high3(i32 %a) {
    399 ; CHECK-LABEL: @clamp_high3(
    400 entry:
    401   %cmp = icmp sle i32 %a, 5
    402   br i1 %cmp, label %a_guard, label %out
    403 
    404 a_guard:
    405   %sel_cmp = icmp ne i32 %a, 5
    406   %add = add i32 %a, 100
    407   %sel = select i1 %sel_cmp, i32 %a, i32 5
    408   %res = icmp eq i32 %sel, 105
    409   br label %next
    410 next:
    411 ; CHECK: next:
    412 ; CHECK: ret i1 false
    413   ret i1 %res
    414 out:
    415   ret i1 false
    416 }
    417 
    418 define i1 @zext_unknown(i8 %a) {
    419 ; CHECK-LABEL: @zext_unknown
    420 ; CHECK: ret i1 true
    421 entry:
    422   %a32 = zext i8 %a to i32
    423   %cmp = icmp sle i32 %a32, 256
    424   br label %exit
    425 exit:
    426   ret i1 %cmp
    427 }
    428 
    429 define i1 @trunc_unknown(i32 %a) {
    430 ; CHECK-LABEL: @trunc_unknown
    431 ; CHECK: ret i1 true
    432 entry:
    433   %a8 = trunc i32 %a to i8
    434   %a32 = sext i8 %a8 to i32
    435   %cmp = icmp sle i32 %a32, 128
    436   br label %exit
    437 exit:
    438   ret i1 %cmp
    439 }
    440 
    441 ; TODO: missed optimization
    442 ; Make sure we exercise non-integer inputs to unary operators (i.e. crash 
    443 ; check).
    444 define i1 @bitcast_unknown(float %a) {
    445 ; CHECK-LABEL: @bitcast_unknown
    446 ; CHECK: ret i1 %cmp
    447 entry:
    448   %a32 = bitcast float %a to i32
    449   %cmp = icmp sle i32 %a32, 128
    450   br label %exit
    451 exit:
    452   ret i1 %cmp
    453 }
    454 
    455 define i1 @bitcast_unknown2(i8* %p) {
    456 ; CHECK-LABEL: @bitcast_unknown2
    457 ; CHECK: ret i1 %cmp
    458 entry:
    459   %p64 = ptrtoint i8* %p to i64
    460   %cmp = icmp sle i64 %p64, 128
    461   br label %exit
    462 exit:
    463   ret i1 %cmp
    464 }
    465 
    466 
    467 define i1 @and_unknown(i32 %a) {
    468 ; CHECK-LABEL: @and_unknown
    469 ; CHECK: ret i1 true
    470 entry:
    471   %and = and i32 %a, 128
    472   %cmp = icmp sle i32 %and, 128
    473   br label %exit
    474 exit:
    475   ret i1 %cmp
    476 }
    477 
    478 define i1 @lshr_unknown(i32 %a) {
    479 ; CHECK-LABEL: @lshr_unknown
    480 ; CHECK: ret i1 true
    481 entry:
    482   %and = lshr i32 %a, 30
    483   %cmp = icmp sle i32 %and, 128
    484   br label %exit
    485 exit:
    486   ret i1 %cmp
    487 }
    488