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