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 !0 = !{i64 0, i64 100}
    145 
    146 ; Negative test - we can't show that the internal branch executes, so we can't
    147 ; fold the test to a loop invariant one.
    148 define void @test1_neg(i64 %start) {
    149 ; CHECK-LABEL: @test1_neg
    150 entry:
    151   br label %loop
    152 
    153 loop:
    154   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
    155   %indvars.iv.next = add nsw i64 %indvars.iv, 1
    156   %cmp = icmp eq i64 %indvars.iv.next, 25
    157   br i1 %cmp, label %backedge, label %skip
    158 skip:
    159   ; prevent flattening, needed to make sure we're testing what we intend
    160   call void @foo() 
    161 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
    162   %cmp1 = icmp slt i64 %indvars.iv, -1
    163   br i1 %cmp1, label %for.end, label %backedge
    164 backedge:
    165   ; prevent flattening, needed to make sure we're testing what we intend
    166   call void @foo() 
    167   br label %loop
    168 
    169 for.end:                                          ; preds = %if.end, %entry
    170   ret void
    171 }
    172 
    173 ; Slightly subtle version of @test4 where the icmp dominates the backedge,
    174 ; but the exit branch doesn't.  
    175 define void @test2_neg(i64 %start) {
    176 ; CHECK-LABEL: @test2_neg
    177 entry:
    178   br label %loop
    179 
    180 loop:
    181   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
    182   %indvars.iv.next = add nsw i64 %indvars.iv, 1
    183   %cmp = icmp eq i64 %indvars.iv.next, 25
    184 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
    185   %cmp1 = icmp slt i64 %indvars.iv, -1
    186   br i1 %cmp, label %backedge, label %skip
    187 skip:
    188   ; prevent flattening, needed to make sure we're testing what we intend
    189   call void @foo() 
    190   br i1 %cmp1, label %for.end, label %backedge
    191 backedge:
    192   ; prevent flattening, needed to make sure we're testing what we intend
    193   call void @foo() 
    194   br label %loop
    195 
    196 for.end:                                          ; preds = %if.end, %entry
    197   ret void
    198 }
    199 
    200 ; The branch has to exit the loop if the condition is true
    201 define void @test3_neg(i64 %start) {
    202 ; CHECK-LABEL: @test3_neg
    203 entry:
    204   br label %loop
    205 
    206 loop:
    207   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
    208   %indvars.iv.next = add nsw i64 %indvars.iv, 1
    209 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
    210   %cmp1 = icmp slt i64 %indvars.iv, -1
    211   br i1 %cmp1, label %loop, label %for.end
    212 
    213 for.end:                                          ; preds = %if.end, %entry
    214   ret void
    215 }
    216 
    217 define void @test4_neg(i64 %start) {
    218 ; CHECK-LABEL: @test4_neg
    219 entry:
    220   br label %loop
    221 
    222 loop:
    223   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %backedge ]
    224   %indvars.iv.next = add nsw i64 %indvars.iv, 1
    225   %cmp = icmp eq i64 %indvars.iv.next, 25
    226   br i1 %cmp, label %backedge, label %for.end
    227 
    228 backedge:
    229   ; prevent flattening, needed to make sure we're testing what we intend
    230   call void @foo() 
    231 ; CHECK: %cmp1 = icmp sgt i64 %indvars.iv, -1
    232   %cmp1 = icmp sgt i64 %indvars.iv, -1
    233 
    234 ; %cmp1 can be made loop invariant only if the branch below goes to
    235 ; %the header when %cmp1 is true.
    236   br i1 %cmp1, label %for.end, label %loop
    237 
    238 for.end:                                          ; preds = %if.end, %entry
    239   ret void
    240 }
    241 
    242 define void @test5_neg(i64 %start, i64 %inc) {
    243 ; CHECK-LABEL: @test5_neg
    244 entry:
    245   br label %loop
    246 
    247 loop:
    248   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
    249   %indvars.iv.next = add nsw i64 %indvars.iv, %inc
    250 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
    251   %cmp1 = icmp slt i64 %indvars.iv, -1
    252   br i1 %cmp1, label %for.end, label %loop
    253 
    254 for.end:                                          ; preds = %if.end, %entry
    255   ret void
    256 }
    257 
    258 define void @test8(i64 %start, i64* %inc_ptr) {
    259 ; CHECK-LABEL: @test8
    260 entry:
    261   %inc = load i64, i64* %inc_ptr, !range !1
    262   %ok = icmp sge i64 %inc, 0
    263   br i1 %ok, label %loop, label %for.end
    264 
    265 loop:
    266   %indvars.iv = phi i64 [ %start, %entry ], [ %indvars.iv.next, %loop ]
    267   %indvars.iv.next = add nsw i64 %indvars.iv, %inc
    268 ; CHECK: %cmp1 = icmp slt i64 %indvars.iv, -1
    269   %cmp1 = icmp slt i64 %indvars.iv, -1
    270   br i1 %cmp1, label %for.end, label %loop
    271 
    272 for.end:                                          ; preds = %if.end, %entry
    273   ret void
    274 }
    275 
    276 !1 = !{i64 -1, i64 100}
    277 
    278 
    279 declare void @foo()
    280