Home | History | Annotate | Download | only in IndVarSimplify
      1 ; RUN: opt -S -indvars %s | FileCheck %s
      2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
      3 target triple = "x86_64-unknown-linux-gnu"
      4 
      5 define void @test1(i64 %start) {
      6 ; CHECK-LABEL: @test1
      7 entry:
      8   br label %loop
      9 
     10 loop:
     11   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
     12   %indvars.iv.next = add nsw i64 %indvars.iv, 1
     13 ; CHECK: %cmp1 = icmp slt i64 %start, -1
     14   %cmp1 = icmp slt i64 %indvars.iv, -1
     15   br i1 %cmp1, label %for.end, label %loop
     16 
     17 for.end:                                          ; preds = %if.end, %entry
     18   ret void
     19 }
     20 
     21 define void @test2(i64 %start) {
     22 ; CHECK-LABEL: @test2
     23 entry:
     24   br label %loop
     25 
     26 loop:
     27   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
     28   %indvars.iv.next = add nsw i64 %indvars.iv, 1
     29 ; CHECK: %cmp1 = icmp sle i64 %start, -1
     30   %cmp1 = icmp sle i64 %indvars.iv, -1
     31   br i1 %cmp1, label %for.end, label %loop
     32 
     33 for.end:                                          ; preds = %if.end, %entry
     34   ret void
     35 }
     36 
     37 ; As long as the test dominates the backedge, we're good
     38 define void @test3(i64 %start) {
     39 ; CHECK-LABEL: @test3
     40 entry:
     41   br label %loop
     42 
     43 loop:
     44   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
     45   %indvars.iv.next = add nsw i64 %indvars.iv, 1
     46   %cmp = icmp eq i64 %indvars.iv.next, 25
     47   br i1 %cmp, label %backedge, label %for.end
     48 
     49 backedge:
     50   ; prevent flattening, needed to make sure we're testing what we intend
     51   call void @foo() 
     52 ; CHECK: %cmp1 = icmp slt i64 %start, -1
     53   %cmp1 = icmp slt i64 %indvars.iv, -1
     54   br i1 %cmp1, label %for.end, label %loop
     55 
     56 for.end:                                          ; preds = %if.end, %entry
     57   ret void
     58 }
     59 
     60 define void @test4(i64 %start) {
     61 ; CHECK-LABEL: @test4
     62 entry:
     63   br label %loop
     64 
     65 loop:
     66   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
     67   %indvars.iv.next = add nsw i64 %indvars.iv, 1
     68   %cmp = icmp eq i64 %indvars.iv.next, 25
     69   br i1 %cmp, label %backedge, label %for.end
     70 
     71 backedge:
     72   ; prevent flattening, needed to make sure we're testing what we intend
     73   call void @foo() 
     74 ; CHECK: %cmp1 = icmp sgt i64 %start, -1
     75   %cmp1 = icmp sgt i64 %indvars.iv, -1
     76   br i1 %cmp1, label %loop, label %for.end
     77 
     78 for.end:                                          ; preds = %if.end, %entry
     79   ret void
     80 }
     81 
     82 define void @test5(i64 %start) {
     83 ; CHECK-LABEL: @test5
     84 entry:
     85   br label %loop
     86 
     87 loop:
     88   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
     89   %indvars.iv.next = add nuw i64 %indvars.iv, 1
     90   %cmp = icmp eq i64 %indvars.iv.next, 25
     91   br i1 %cmp, label %backedge, label %for.end
     92 
     93 backedge:
     94   ; prevent flattening, needed to make sure we're testing what we intend
     95   call void @foo() 
     96 ; CHECK: %cmp1 = icmp ugt i64 %start, 100
     97   %cmp1 = icmp ugt i64 %indvars.iv, 100
     98   br i1 %cmp1, label %loop, label %for.end
     99 
    100 for.end:                                          ; preds = %if.end, %entry
    101   ret void
    102 }
    103 
    104 define void @test6(i64 %start) {
    105 ; CHECK-LABEL: @test6
    106 entry:
    107   br label %loop
    108 
    109 loop:
    110   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
    111   %indvars.iv.next = add nuw i64 %indvars.iv, 1
    112   %cmp = icmp eq i64 %indvars.iv.next, 25
    113   br i1 %cmp, label %backedge, label %for.end
    114 
    115 backedge:
    116   ; prevent flattening, needed to make sure we're testing what we intend
    117   call void @foo() 
    118 ; CHECK: %cmp1 = icmp ult i64 %start, 100
    119   %cmp1 = icmp ult i64 %indvars.iv, 100
    120   br i1 %cmp1, label %for.end, label %loop
    121 
    122 for.end:                                          ; preds = %if.end, %entry
    123   ret void
    124 }
    125 
    126 define void @test7(i64 %start, i64* %inc_ptr) {
    127 ; CHECK-LABEL: @test7
    128 entry:
    129   %inc = load i64, i64* %inc_ptr, !range !0
    130   %ok = icmp sge i64 %inc, 0
    131   br i1 %ok, label %loop, label %for.end
    132 
    133 loop:
    134   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
    135   %indvars.iv.next = add nsw i64 %indvars.iv, %inc
    136 ; CHECK: %cmp1 = icmp slt i64 %start, -1
    137   %cmp1 = icmp slt i64 %indvars.iv, -1
    138   br i1 %cmp1, label %for.end, label %loop
    139 
    140 for.end:                                          ; preds = %if.end, %entry
    141   ret void
    142 }
    143 
    144 ; Negative test - we can't show that the internal branch executes, so we can't
    145 ; fold the test to a loop invariant one.
    146 define void @test1_neg(i64 %start) {
    147 ; CHECK-LABEL: @test1_neg
    148 entry:
    149   br label %loop
    150 
    151 loop:
    152   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
    153   %indvars.iv.next = add nsw i64 %indvars.iv, 1
    154   %cmp = icmp eq i64 %indvars.iv.next, 25
    155   br i1 %cmp, label %backedge, label %skip
    156 skip:
    157   ; prevent flattening, needed to make sure we're testing what we intend
    158   call void @foo() 
    159 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
    160   %cmp1 = icmp slt i64 %indvars.iv, -1
    161   br i1 %cmp1, label %for.end, label %backedge
    162 backedge:
    163   ; prevent flattening, needed to make sure we're testing what we intend
    164   call void @foo() 
    165   br label %loop
    166 
    167 for.end:                                          ; preds = %if.end, %entry
    168   ret void
    169 }
    170 
    171 ; Slightly subtle version of @test4 where the icmp dominates the backedge,
    172 ; but the exit branch doesn't.  
    173 define void @test2_neg(i64 %start) {
    174 ; CHECK-LABEL: @test2_neg
    175 entry:
    176   br label %loop
    177 
    178 loop:
    179   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
    180   %indvars.iv.next = add nsw i64 %indvars.iv, 1
    181   %cmp = icmp eq i64 %indvars.iv.next, 25
    182 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
    183   %cmp1 = icmp slt i64 %indvars.iv, -1
    184   br i1 %cmp, label %backedge, label %skip
    185 skip:
    186   ; prevent flattening, needed to make sure we're testing what we intend
    187   call void @foo() 
    188   br i1 %cmp1, label %for.end, label %backedge
    189 backedge:
    190   ; prevent flattening, needed to make sure we're testing what we intend
    191   call void @foo() 
    192   br label %loop
    193 
    194 for.end:                                          ; preds = %if.end, %entry
    195   ret void
    196 }
    197 
    198 ; The branch has to exit the loop if the condition is true
    199 define void @test3_neg(i64 %start) {
    200 ; CHECK-LABEL: @test3_neg
    201 entry:
    202   br label %loop
    203 
    204 loop:
    205   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
    206   %indvars.iv.next = add nsw i64 %indvars.iv, 1
    207 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
    208   %cmp1 = icmp slt i64 %indvars.iv, -1
    209   br i1 %cmp1, label %loop, label %for.end
    210 
    211 for.end:                                          ; preds = %if.end, %entry
    212   ret void
    213 }
    214 
    215 define void @test4_neg(i64 %start) {
    216 ; CHECK-LABEL: @test4_neg
    217 entry:
    218   br label %loop
    219 
    220 loop:
    221   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
    222   %indvars.iv.next = add nsw i64 %indvars.iv, 1
    223   %cmp = icmp eq i64 %indvars.iv.next, 25
    224   br i1 %cmp, label %backedge, label %for.end
    225 
    226 backedge:
    227   ; prevent flattening, needed to make sure we're testing what we intend
    228   call void @foo() 
    229 ; CHECK: %cmp1 = icmp sgt i64 %indvars.iv, -1
    230   %cmp1 = icmp sgt i64 %indvars.iv, -1
    231 
    232 ; %cmp1 can be made loop invariant only if the branch below goes to
    233 ; %the header when %cmp1 is true.
    234   br i1 %cmp1, label %for.end, label %loop
    235 
    236 for.end:                                          ; preds = %if.end, %entry
    237   ret void
    238 }
    239 
    240 define void @test5_neg(i64 %start, i64 %inc) {
    241 ; CHECK-LABEL: @test5_neg
    242 entry:
    243   br label %loop
    244 
    245 loop:
    246   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
    247   %indvars.iv.next = add nsw i64 %indvars.iv, %inc
    248 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
    249   %cmp1 = icmp slt i64 %indvars.iv, -1
    250   br i1 %cmp1, label %for.end, label %loop
    251 
    252 for.end:                                          ; preds = %if.end, %entry
    253   ret void
    254 }
    255 
    256 define void @test8(i64 %start, i64* %inc_ptr) {
    257 ; CHECK-LABEL: @test8
    258 entry:
    259   %inc = load i64, i64* %inc_ptr, !range !1
    260   %ok = icmp sge i64 %inc, 0
    261   br i1 %ok, label %loop, label %for.end
    262 
    263 loop:
    264   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
    265   %indvars.iv.next = add nsw i64 %indvars.iv, %inc
    266 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
    267   %cmp1 = icmp slt i64 %indvars.iv, -1
    268   br i1 %cmp1, label %for.end, label %loop
    269 
    270 for.end:                                          ; preds = %if.end, %entry
    271   ret void
    272 }
    273 
    274 ; check to handle loops without preheaders, but invariant operands
    275 ; (we handle this today by inserting a preheader)
    276 define void @test9(i1 %cnd, i64 %start) {
    277 ; CHECK-LABEL: @test9
    278 ; CHECK-LABEL: loop.preheader:
    279 entry:
    280   br i1 %cnd, label %entry1, label %entry2
    281 entry1:
    282   br label %loop
    283 entry2:
    284   br label %loop
    285 loop:
    286   %indvars.iv = phi i64 [ %start, %entry1 ],[ %start, %entry2 ], [ %indvars.iv.next, %loop ]
    287   %indvars.iv.next = add nsw i64 %indvars.iv, 1
    288 ; CHECK: %cmp1 = icmp slt i64 %start, -1
    289   %cmp1 = icmp slt i64 %indvars.iv, -1
    290   br i1 %cmp1, label %for.end, label %loop
    291 
    292 for.end:                                          ; preds = %if.end, %entry
    293   ret void
    294 }
    295 
    296 declare void @use(i1 %x)
    297 
    298 ; check that we handle conditions with loop invariant operands which
    299 ; *aren't* in the header - this is a very rare and fragile case where
    300 ; we have a "loop" which is known to run exactly one iteration but
    301 ; haven't yet simplified the uses of the IV
    302 define void @test10() {
    303 ; CHECK-LABEL: @test10
    304 entry:
    305   br label %loop
    306 
    307 loop:
    308   %phi1 = phi i32 [ %phi2, %latch ], [ 0, %entry ]
    309   %dec = add i32 %phi1, -1
    310   br i1 false, label %left, label %right
    311 
    312 left:
    313   br label %latch
    314 
    315 right:
    316   br label %latch
    317 
    318 latch:
    319   %phi2 = phi i32 [ %phi1, %left ], [ %dec, %right ]
    320   ; CHECK: %cmp = icmp slt i32 -1, undef
    321   %cmp = icmp slt i32 %phi2, undef
    322   br i1 true, label %exit, label %loop
    323 
    324 exit:
    325   call void @use(i1 %cmp)
    326   ret void
    327 }
    328 
    329 ; check that we can figure out that iv.next > 1 from the facts that iv >= 0 and
    330 ; iv.start != 0.
    331 define void @test11(i64* %inc_ptr) {
    332 ; CHECK-LABEL: @test11
    333 entry:
    334   %inc = load i64, i64* %inc_ptr, !range !0
    335   %ne.cond = icmp ne i64 %inc, 0
    336   br i1 %ne.cond, label %loop, label %exit
    337 
    338 loop:
    339   %iv = phi i64 [ %inc, %entry ], [ %iv.next, %backedge ]
    340   %iv.next = add i64 %iv, 1
    341   %brcond = icmp sgt i64 %iv.next, 1
    342   ; CHECK: br i1 true, label %if.true, label %if.false
    343   br i1 %brcond, label %if.true, label %if.false
    344 
    345 if.true:
    346   br label %backedge
    347 
    348 if.false:
    349   br label %backedge
    350 
    351 backedge:
    352   %loopcond = icmp slt i64 %iv, 200
    353   br i1 %loopcond, label %loop, label %exit
    354 
    355 exit:
    356   ret void
    357 }
    358 
    359 ; check that we can prove that a recurrency is greater than another recurrency
    360 ; in the same loop, with the same step, and with smaller starting value.
    361 define void @test12(i64* %inc_ptr) {
    362 ; CHECK-LABEL: @test12
    363 entry:
    364   %inc = load i64, i64* %inc_ptr, !range !0
    365   %inc.minus.1 = sub i64 %inc, 1
    366   br label %loop
    367 
    368 loop:
    369   %iv = phi i64 [ %inc, %entry ], [ %iv.next, %backedge ]
    370   %iv.minus.1 = phi i64 [ %inc.minus.1, %entry ], [ %iv.minus.1.next, %backedge ]
    371   %iv.next = add i64 %iv, 1
    372   %iv.minus.1.next = add i64 %iv.minus.1, 1
    373   %brcond = icmp sgt i64 %iv.next, %iv.minus.1.next
    374   ; CHECK: br i1 true, label %if.true, label %if.false
    375   br i1 %brcond, label %if.true, label %if.false
    376 
    377 if.true:
    378   br label %backedge
    379 
    380 if.false:
    381   br label %backedge
    382 
    383 backedge:
    384   %loopcond = icmp slt i64 %iv, 200
    385   br i1 %loopcond, label %loop, label %exit
    386 
    387 exit:
    388   ret void
    389 }
    390 
    391 !0 = !{i64 0, i64 100}
    392 !1 = !{i64 -1, i64 100}
    393 
    394 declare void @foo()
    395