Home | History | Annotate | Download | only in IRCE
      1 ; RUN: opt -verify-loop-info -irce-print-changed-loops -irce < %s 2>&1 | FileCheck %s
      2 
      3 ; This test checks if we update the LoopInfo correctly in the presence
      4 ; of parents, uncles and cousins.
      5 
      6 ; Function Attrs: alwaysinline
      7 define void @inner_loop(i32* %arr, i32* %a_len_ptr, i32 %n) #0 {
      8 ; CHECK: irce: in function inner_loop: constrained Loop at depth 1 containing: %loop<header><exiting>,%in.bounds<latch><exiting>
      9 
     10 entry:
     11   %len = load i32, i32* %a_len_ptr, !range !0
     12   %first.itr.check = icmp sgt i32 %n, 0
     13   br i1 %first.itr.check, label %loop, label %exit
     14 
     15 loop:                                             ; preds = %in.bounds, %entry
     16   %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds ]
     17   %idx.next = add i32 %idx, 1
     18   %abc = icmp slt i32 %idx, %len
     19   br i1 %abc, label %in.bounds, label %out.of.bounds, !prof !1
     20 
     21 in.bounds:                                        ; preds = %loop
     22   %addr = getelementptr i32, i32* %arr, i32 %idx
     23   store i32 0, i32* %addr
     24   %next = icmp slt i32 %idx.next, %n
     25   br i1 %next, label %loop, label %exit
     26 
     27 out.of.bounds:                                    ; preds = %loop
     28   ret void
     29 
     30 exit:                                             ; preds = %in.bounds, %entry
     31   ret void
     32 }
     33 
     34 ; Function Attrs: alwaysinline
     35 define void @with_parent(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count) #0 {
     36 ; CHECK: irce: in function with_parent: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
     37 
     38 entry:
     39   br label %loop
     40 
     41 loop:                                             ; preds = %inner_loop.exit, %entry
     42   %idx = phi i32 [ 0, %entry ], [ %idx.next, %inner_loop.exit ]
     43   %idx.next = add i32 %idx, 1
     44   %next = icmp ult i32 %idx.next, %parent.count
     45   %len.i = load i32, i32* %a_len_ptr, !range !0
     46   %first.itr.check.i = icmp sgt i32 %n, 0
     47   br i1 %first.itr.check.i, label %loop.i, label %exit.i
     48 
     49 loop.i:                                           ; preds = %in.bounds.i, %loop
     50   %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
     51   %idx.next.i = add i32 %idx.i, 1
     52   %abc.i = icmp slt i32 %idx.i, %len.i
     53   br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
     54 
     55 in.bounds.i:                                      ; preds = %loop.i
     56   %addr.i = getelementptr i32, i32* %arr, i32 %idx.i
     57   store i32 0, i32* %addr.i
     58   %next.i = icmp slt i32 %idx.next.i, %n
     59   br i1 %next.i, label %loop.i, label %exit.i
     60 
     61 out.of.bounds.i:                                  ; preds = %loop.i
     62   br label %inner_loop.exit
     63 
     64 exit.i:                                           ; preds = %in.bounds.i, %loop
     65   br label %inner_loop.exit
     66 
     67 inner_loop.exit:                                  ; preds = %exit.i, %out.of.bounds.i
     68   br i1 %next, label %loop, label %exit
     69 
     70 exit:                                             ; preds = %inner_loop.exit
     71   ret void
     72 }
     73 
     74 ; Function Attrs: alwaysinline
     75 define void @with_grandparent(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
     76 ; CHECK: irce: in function with_grandparent: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
     77 
     78 entry:
     79   br label %loop
     80 
     81 loop:                                             ; preds = %with_parent.exit, %entry
     82   %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit ]
     83   %idx.next = add i32 %idx, 1
     84   %next = icmp ult i32 %idx.next, %grandparent.count
     85   br label %loop.i
     86 
     87 loop.i:                                           ; preds = %inner_loop.exit.i, %loop
     88   %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %inner_loop.exit.i ]
     89   %idx.next.i = add i32 %idx.i, 1
     90   %next.i = icmp ult i32 %idx.next.i, %parent.count
     91   %len.i.i = load i32, i32* %a_len_ptr, !range !0
     92   %first.itr.check.i.i = icmp sgt i32 %n, 0
     93   br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
     94 
     95 loop.i.i:                                         ; preds = %in.bounds.i.i, %loop.i
     96   %idx.i.i = phi i32 [ 0, %loop.i ], [ %idx.next.i.i, %in.bounds.i.i ]
     97   %idx.next.i.i = add i32 %idx.i.i, 1
     98   %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
     99   br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
    100 
    101 in.bounds.i.i:                                    ; preds = %loop.i.i
    102   %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i
    103   store i32 0, i32* %addr.i.i
    104   %next.i.i = icmp slt i32 %idx.next.i.i, %n
    105   br i1 %next.i.i, label %loop.i.i, label %exit.i.i
    106 
    107 out.of.bounds.i.i:                                ; preds = %loop.i.i
    108   br label %inner_loop.exit.i
    109 
    110 exit.i.i:                                         ; preds = %in.bounds.i.i, %loop.i
    111   br label %inner_loop.exit.i
    112 
    113 inner_loop.exit.i:                                ; preds = %exit.i.i, %out.of.bounds.i.i
    114   br i1 %next.i, label %loop.i, label %with_parent.exit
    115 
    116 with_parent.exit:                                 ; preds = %inner_loop.exit.i
    117   br i1 %next, label %loop, label %exit
    118 
    119 exit:                                             ; preds = %with_parent.exit
    120   ret void
    121 }
    122 
    123 ; Function Attrs: alwaysinline
    124 define void @with_sibling(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count) #0 {
    125 ; CHECK: irce: in function with_sibling: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
    126 ; CHECK: irce: in function with_sibling: constrained Loop at depth 2 containing: %loop.i6<header><exiting>,%in.bounds.i9<latch><exiting>
    127 
    128 entry:
    129   br label %loop
    130 
    131 loop:                                             ; preds = %inner_loop.exit12, %entry
    132   %idx = phi i32 [ 0, %entry ], [ %idx.next, %inner_loop.exit12 ]
    133   %idx.next = add i32 %idx, 1
    134   %next = icmp ult i32 %idx.next, %parent.count
    135   %len.i = load i32, i32* %a_len_ptr, !range !0
    136   %first.itr.check.i = icmp sgt i32 %n, 0
    137   br i1 %first.itr.check.i, label %loop.i, label %exit.i
    138 
    139 loop.i:                                           ; preds = %in.bounds.i, %loop
    140   %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
    141   %idx.next.i = add i32 %idx.i, 1
    142   %abc.i = icmp slt i32 %idx.i, %len.i
    143   br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
    144 
    145 in.bounds.i:                                      ; preds = %loop.i
    146   %addr.i = getelementptr i32, i32* %arr, i32 %idx.i
    147   store i32 0, i32* %addr.i
    148   %next.i = icmp slt i32 %idx.next.i, %n
    149   br i1 %next.i, label %loop.i, label %exit.i
    150 
    151 out.of.bounds.i:                                  ; preds = %loop.i
    152   br label %inner_loop.exit
    153 
    154 exit.i:                                           ; preds = %in.bounds.i, %loop
    155   br label %inner_loop.exit
    156 
    157 inner_loop.exit:                                  ; preds = %exit.i, %out.of.bounds.i
    158   %len.i1 = load i32, i32* %a_len_ptr, !range !0
    159   %first.itr.check.i2 = icmp sgt i32 %n, 0
    160   br i1 %first.itr.check.i2, label %loop.i6, label %exit.i11
    161 
    162 loop.i6:                                          ; preds = %in.bounds.i9, %inner_loop.exit
    163   %idx.i3 = phi i32 [ 0, %inner_loop.exit ], [ %idx.next.i4, %in.bounds.i9 ]
    164   %idx.next.i4 = add i32 %idx.i3, 1
    165   %abc.i5 = icmp slt i32 %idx.i3, %len.i1
    166   br i1 %abc.i5, label %in.bounds.i9, label %out.of.bounds.i10, !prof !1
    167 
    168 in.bounds.i9:                                     ; preds = %loop.i6
    169   %addr.i7 = getelementptr i32, i32* %arr, i32 %idx.i3
    170   store i32 0, i32* %addr.i7
    171   %next.i8 = icmp slt i32 %idx.next.i4, %n
    172   br i1 %next.i8, label %loop.i6, label %exit.i11
    173 
    174 out.of.bounds.i10:                                ; preds = %loop.i6
    175   br label %inner_loop.exit12
    176 
    177 exit.i11:                                         ; preds = %in.bounds.i9, %inner_loop.exit
    178   br label %inner_loop.exit12
    179 
    180 inner_loop.exit12:                                ; preds = %exit.i11, %out.of.bounds.i10
    181   br i1 %next, label %loop, label %exit
    182 
    183 exit:                                             ; preds = %inner_loop.exit12
    184   ret void
    185 }
    186 
    187 ; Function Attrs: alwaysinline
    188 define void @with_cousin(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
    189 ; CHECK: irce: in function with_cousin: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
    190 ; CHECK: irce: in function with_cousin: constrained Loop at depth 3 containing: %loop.i.i10<header><exiting>,%in.bounds.i.i13<latch><exiting>
    191 
    192 entry:
    193   br label %loop
    194 
    195 loop:                                             ; preds = %with_parent.exit17, %entry
    196   %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit17 ]
    197   %idx.next = add i32 %idx, 1
    198   %next = icmp ult i32 %idx.next, %grandparent.count
    199   br label %loop.i
    200 
    201 loop.i:                                           ; preds = %inner_loop.exit.i, %loop
    202   %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %inner_loop.exit.i ]
    203   %idx.next.i = add i32 %idx.i, 1
    204   %next.i = icmp ult i32 %idx.next.i, %parent.count
    205   %len.i.i = load i32, i32* %a_len_ptr, !range !0
    206   %first.itr.check.i.i = icmp sgt i32 %n, 0
    207   br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
    208 
    209 loop.i.i:                                         ; preds = %in.bounds.i.i, %loop.i
    210   %idx.i.i = phi i32 [ 0, %loop.i ], [ %idx.next.i.i, %in.bounds.i.i ]
    211   %idx.next.i.i = add i32 %idx.i.i, 1
    212   %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
    213   br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
    214 
    215 in.bounds.i.i:                                    ; preds = %loop.i.i
    216   %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i
    217   store i32 0, i32* %addr.i.i
    218   %next.i.i = icmp slt i32 %idx.next.i.i, %n
    219   br i1 %next.i.i, label %loop.i.i, label %exit.i.i
    220 
    221 out.of.bounds.i.i:                                ; preds = %loop.i.i
    222   br label %inner_loop.exit.i
    223 
    224 exit.i.i:                                         ; preds = %in.bounds.i.i, %loop.i
    225   br label %inner_loop.exit.i
    226 
    227 inner_loop.exit.i:                                ; preds = %exit.i.i, %out.of.bounds.i.i
    228   br i1 %next.i, label %loop.i, label %with_parent.exit
    229 
    230 with_parent.exit:                                 ; preds = %inner_loop.exit.i
    231   br label %loop.i6
    232 
    233 loop.i6:                                          ; preds = %inner_loop.exit.i16, %with_parent.exit
    234   %idx.i1 = phi i32 [ 0, %with_parent.exit ], [ %idx.next.i2, %inner_loop.exit.i16 ]
    235   %idx.next.i2 = add i32 %idx.i1, 1
    236   %next.i3 = icmp ult i32 %idx.next.i2, %parent.count
    237   %len.i.i4 = load i32, i32* %a_len_ptr, !range !0
    238   %first.itr.check.i.i5 = icmp sgt i32 %n, 0
    239   br i1 %first.itr.check.i.i5, label %loop.i.i10, label %exit.i.i15
    240 
    241 loop.i.i10:                                       ; preds = %in.bounds.i.i13, %loop.i6
    242   %idx.i.i7 = phi i32 [ 0, %loop.i6 ], [ %idx.next.i.i8, %in.bounds.i.i13 ]
    243   %idx.next.i.i8 = add i32 %idx.i.i7, 1
    244   %abc.i.i9 = icmp slt i32 %idx.i.i7, %len.i.i4
    245   br i1 %abc.i.i9, label %in.bounds.i.i13, label %out.of.bounds.i.i14, !prof !1
    246 
    247 in.bounds.i.i13:                                  ; preds = %loop.i.i10
    248   %addr.i.i11 = getelementptr i32, i32* %arr, i32 %idx.i.i7
    249   store i32 0, i32* %addr.i.i11
    250   %next.i.i12 = icmp slt i32 %idx.next.i.i8, %n
    251   br i1 %next.i.i12, label %loop.i.i10, label %exit.i.i15
    252 
    253 out.of.bounds.i.i14:                              ; preds = %loop.i.i10
    254   br label %inner_loop.exit.i16
    255 
    256 exit.i.i15:                                       ; preds = %in.bounds.i.i13, %loop.i6
    257   br label %inner_loop.exit.i16
    258 
    259 inner_loop.exit.i16:                              ; preds = %exit.i.i15, %out.of.bounds.i.i14
    260   br i1 %next.i3, label %loop.i6, label %with_parent.exit17
    261 
    262 with_parent.exit17:                               ; preds = %inner_loop.exit.i16
    263   br i1 %next, label %loop, label %exit
    264 
    265 exit:                                             ; preds = %with_parent.exit17
    266   ret void
    267 }
    268 
    269 ; Function Attrs: alwaysinline
    270 define void @with_uncle(i32* %arr, i32* %a_len_ptr, i32 %n, i32 %parent.count, i32 %grandparent.count) #0 {
    271 ; CHECK: irce: in function with_uncle: constrained Loop at depth 2 containing: %loop.i<header><exiting>,%in.bounds.i<latch><exiting>
    272 ; CHECK: irce: in function with_uncle: constrained Loop at depth 3 containing: %loop.i.i<header><exiting>,%in.bounds.i.i<latch><exiting>
    273 
    274 entry:
    275   br label %loop
    276 
    277 loop:                                             ; preds = %with_parent.exit, %entry
    278   %idx = phi i32 [ 0, %entry ], [ %idx.next, %with_parent.exit ]
    279   %idx.next = add i32 %idx, 1
    280   %next = icmp ult i32 %idx.next, %grandparent.count
    281   %len.i = load i32, i32* %a_len_ptr, !range !0
    282   %first.itr.check.i = icmp sgt i32 %n, 0
    283   br i1 %first.itr.check.i, label %loop.i, label %exit.i
    284 
    285 loop.i:                                           ; preds = %in.bounds.i, %loop
    286   %idx.i = phi i32 [ 0, %loop ], [ %idx.next.i, %in.bounds.i ]
    287   %idx.next.i = add i32 %idx.i, 1
    288   %abc.i = icmp slt i32 %idx.i, %len.i
    289   br i1 %abc.i, label %in.bounds.i, label %out.of.bounds.i, !prof !1
    290 
    291 in.bounds.i:                                      ; preds = %loop.i
    292   %addr.i = getelementptr i32, i32* %arr, i32 %idx.i
    293   store i32 0, i32* %addr.i
    294   %next.i = icmp slt i32 %idx.next.i, %n
    295   br i1 %next.i, label %loop.i, label %exit.i
    296 
    297 out.of.bounds.i:                                  ; preds = %loop.i
    298   br label %inner_loop.exit
    299 
    300 exit.i:                                           ; preds = %in.bounds.i, %loop
    301   br label %inner_loop.exit
    302 
    303 inner_loop.exit:                                  ; preds = %exit.i, %out.of.bounds.i
    304   br label %loop.i4
    305 
    306 loop.i4:                                          ; preds = %inner_loop.exit.i, %inner_loop.exit
    307   %idx.i1 = phi i32 [ 0, %inner_loop.exit ], [ %idx.next.i2, %inner_loop.exit.i ]
    308   %idx.next.i2 = add i32 %idx.i1, 1
    309   %next.i3 = icmp ult i32 %idx.next.i2, %parent.count
    310   %len.i.i = load i32, i32* %a_len_ptr, !range !0
    311   %first.itr.check.i.i = icmp sgt i32 %n, 0
    312   br i1 %first.itr.check.i.i, label %loop.i.i, label %exit.i.i
    313 
    314 loop.i.i:                                         ; preds = %in.bounds.i.i, %loop.i4
    315   %idx.i.i = phi i32 [ 0, %loop.i4 ], [ %idx.next.i.i, %in.bounds.i.i ]
    316   %idx.next.i.i = add i32 %idx.i.i, 1
    317   %abc.i.i = icmp slt i32 %idx.i.i, %len.i.i
    318   br i1 %abc.i.i, label %in.bounds.i.i, label %out.of.bounds.i.i, !prof !1
    319 
    320 in.bounds.i.i:                                    ; preds = %loop.i.i
    321   %addr.i.i = getelementptr i32, i32* %arr, i32 %idx.i.i
    322   store i32 0, i32* %addr.i.i
    323   %next.i.i = icmp slt i32 %idx.next.i.i, %n
    324   br i1 %next.i.i, label %loop.i.i, label %exit.i.i
    325 
    326 out.of.bounds.i.i:                                ; preds = %loop.i.i
    327   br label %inner_loop.exit.i
    328 
    329 exit.i.i:                                         ; preds = %in.bounds.i.i, %loop.i4
    330   br label %inner_loop.exit.i
    331 
    332 inner_loop.exit.i:                                ; preds = %exit.i.i, %out.of.bounds.i.i
    333   br i1 %next.i3, label %loop.i4, label %with_parent.exit
    334 
    335 with_parent.exit:                                 ; preds = %inner_loop.exit.i
    336   br i1 %next, label %loop, label %exit
    337 
    338 exit:                                             ; preds = %with_parent.exit
    339   ret void
    340 }
    341 
    342 attributes #0 = { alwaysinline }
    343 
    344 !0 = !{i32 0, i32 2147483647}
    345 !1 = !{!"branch_weights", i32 64, i32 4}
    346