Home | History | Annotate | Download | only in LoopInstSimplify
      1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
      2 ; RUN: opt -S %s -passes=loop-instsimplify | FileCheck %s
      3 
      4 ; Test very basic folding and propagation occurs within a loop body. This should
      5 ; collapse to the loop iteration structure and the LCSSA PHI node.
      6 define i32 @test1(i32 %n, i32 %x) {
      7 ; CHECK-LABEL: @test1(
      8 ; CHECK-NEXT:  entry:
      9 ; CHECK-NEXT:    br label [[LOOP:%.*]]
     10 ; CHECK:       loop:
     11 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
     12 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
     13 ; CHECK-NEXT:    [[I_CMP:%.*]] = icmp slt i32 [[I_NEXT]], [[N:%.*]]
     14 ; CHECK-NEXT:    br i1 [[I_CMP]], label [[LOOP]], label [[EXIT:%.*]]
     15 ; CHECK:       exit:
     16 ; CHECK-NEXT:    [[X_LCSSA:%.*]] = phi i32 [ [[X:%.*]], [[LOOP]] ]
     17 ; CHECK-NEXT:    ret i32 [[X_LCSSA]]
     18 ;
     19 entry:
     20   br label %loop
     21 
     22 loop:
     23   %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
     24   %x.add = add nsw i32 %x, 0
     25   %x.sub = sub i32 %x.add, 0
     26   %x.and = and i32 %x.sub, -1
     27   %i.next = add nsw i32 %i, 1
     28   %i.cmp = icmp slt i32 %i.next, %n
     29   br i1 %i.cmp, label %loop, label %exit
     30 
     31 exit:
     32   %x.lcssa = phi i32 [ %x.and, %loop ]
     33   ret i32 %x.lcssa
     34 }
     35 
     36 ; Test basic loop structure that still has a simplification feed a prior PHI.
     37 define i32 @test2(i32 %n, i32 %x) {
     38 ; CHECK-LABEL: @test2(
     39 ; CHECK-NEXT:  entry:
     40 ; CHECK-NEXT:    br label [[LOOP:%.*]]
     41 ; CHECK:       loop:
     42 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
     43 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
     44 ; CHECK-NEXT:    [[I_CMP:%.*]] = icmp slt i32 [[I_NEXT]], [[N:%.*]]
     45 ; CHECK-NEXT:    br i1 [[I_CMP]], label [[LOOP]], label [[EXIT:%.*]]
     46 ; CHECK:       exit:
     47 ; CHECK-NEXT:    [[X_LCSSA:%.*]] = phi i32 [ [[X:%.*]], [[LOOP]] ]
     48 ; CHECK-NEXT:    ret i32 [[X_LCSSA]]
     49 ;
     50 entry:
     51   br label %loop
     52 
     53 loop:
     54   %i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
     55   %x.loop = phi i32 [ %x, %entry ], [ %x.next, %loop ]
     56   %x.next = add nsw i32 %x.loop, 0
     57   %i.next = add nsw i32 %i, 1
     58   %i.cmp = icmp slt i32 %i.next, %n
     59   br i1 %i.cmp, label %loop, label %exit
     60 
     61 exit:
     62   %x.lcssa = phi i32 [ %x.loop, %loop ]
     63   ret i32 %x.lcssa
     64 }
     65 
     66 ; Test a diamond CFG with inner PHI nodes.
     67 define i32 @test3(i32 %n, i32 %x) {
     68 ; CHECK-LABEL: @test3(
     69 ; CHECK-NEXT:  entry:
     70 ; CHECK-NEXT:    br label [[LOOP:%.*]]
     71 ; CHECK:       loop:
     72 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
     73 ; CHECK-NEXT:    [[X_CMP:%.*]] = icmp slt i32 [[I]], 42
     74 ; CHECK-NEXT:    br i1 [[X_CMP]], label [[LOOP_LHS:%.*]], label [[LOOP_RHS:%.*]]
     75 ; CHECK:       loop.lhs:
     76 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
     77 ; CHECK:       loop.rhs:
     78 ; CHECK-NEXT:    br label [[LOOP_LATCH]]
     79 ; CHECK:       loop.latch:
     80 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
     81 ; CHECK-NEXT:    [[I_CMP:%.*]] = icmp slt i32 [[I_NEXT]], [[N:%.*]]
     82 ; CHECK-NEXT:    br i1 [[I_CMP]], label [[LOOP]], label [[EXIT:%.*]]
     83 ; CHECK:       exit:
     84 ; CHECK-NEXT:    [[X_LCSSA:%.*]] = phi i32 [ [[X:%.*]], [[LOOP_LATCH]] ]
     85 ; CHECK-NEXT:    ret i32 [[X_LCSSA]]
     86 ;
     87 entry:
     88   br label %loop
     89 
     90 loop:
     91   %i = phi i32 [ 0, %entry ], [ %i.next, %loop.latch ]
     92   %x.loop = phi i32 [ %x, %entry ], [ %x.phi, %loop.latch ]
     93   %x.add = add nsw i32 %x.loop, 0
     94   %x.cmp = icmp slt i32 %i, 42
     95   br i1 %x.cmp, label %loop.lhs, label %loop.rhs
     96 
     97 loop.lhs:
     98   %x.l.add = add nsw i32 %x.add, 0
     99   br label %loop.latch
    100 
    101 loop.rhs:
    102   %x.r.sub = sub nsw i32 %x.add, 0
    103   br label %loop.latch
    104 
    105 loop.latch:
    106   %x.phi = phi i32 [ %x.l.add, %loop.lhs ], [ %x.r.sub, %loop.rhs ]
    107   %i.next = add nsw i32 %i, 1
    108   %i.cmp = icmp slt i32 %i.next, %n
    109   br i1 %i.cmp, label %loop, label %exit
    110 
    111 exit:
    112   %x.lcssa = phi i32 [ %x.loop, %loop.latch ]
    113   ret i32 %x.lcssa
    114 }
    115 
    116 ; Test an inner loop that is only simplified when processing the outer loop, and
    117 ; an outer loop only simplified when processing the inner loop.
    118 define i32 @test4(i32 %n, i32 %m, i32 %x) {
    119 ; CHECK-LABEL: @test4(
    120 ; CHECK-NEXT:  entry:
    121 ; CHECK-NEXT:    br label [[LOOP:%.*]]
    122 ; CHECK:       loop:
    123 ; CHECK-NEXT:    [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
    124 ; CHECK-NEXT:    br label [[LOOP_INNER:%.*]]
    125 ; CHECK:       loop.inner:
    126 ; CHECK-NEXT:    [[J:%.*]] = phi i32 [ 0, [[LOOP]] ], [ [[J_NEXT:%.*]], [[LOOP_INNER]] ]
    127 ; CHECK-NEXT:    [[J_NEXT]] = add nsw i32 [[J]], 1
    128 ; CHECK-NEXT:    [[J_CMP:%.*]] = icmp slt i32 [[J_NEXT]], [[M:%.*]]
    129 ; CHECK-NEXT:    br i1 [[J_CMP]], label [[LOOP_INNER]], label [[LOOP_LATCH]]
    130 ; CHECK:       loop.latch:
    131 ; CHECK-NEXT:    [[I_NEXT]] = add nsw i32 [[I]], 1
    132 ; CHECK-NEXT:    [[I_CMP:%.*]] = icmp slt i32 [[I_NEXT]], [[N:%.*]]
    133 ; CHECK-NEXT:    br i1 [[I_CMP]], label [[LOOP]], label [[EXIT:%.*]]
    134 ; CHECK:       exit:
    135 ; CHECK-NEXT:    [[X_LCSSA:%.*]] = phi i32 [ [[X:%.*]], [[LOOP_LATCH]] ]
    136 ; CHECK-NEXT:    ret i32 [[X_LCSSA]]
    137 ;
    138 entry:
    139   br label %loop
    140 
    141 loop:
    142   %i = phi i32 [ 0, %entry ], [ %i.next, %loop.latch ]
    143   %x.loop = phi i32 [ %x, %entry ], [ %x.inner.lcssa, %loop.latch ]
    144   %x.add = add nsw i32 %x.loop, 0
    145   br label %loop.inner
    146 
    147 loop.inner:
    148   %j = phi i32 [ 0, %loop ], [ %j.next, %loop.inner ]
    149   %x.inner.loop = phi i32 [ %x.add, %loop ], [ %x.inner.add, %loop.inner ]
    150   %x.inner.add = add nsw i32 %x.inner.loop, 0
    151   %j.next = add nsw i32 %j, 1
    152   %j.cmp = icmp slt i32 %j.next, %m
    153   br i1 %j.cmp, label %loop.inner, label %loop.latch
    154 
    155 loop.latch:
    156   %x.inner.lcssa = phi i32 [ %x.inner.loop, %loop.inner ]
    157   %i.next = add nsw i32 %i, 1
    158   %i.cmp = icmp slt i32 %i.next, %n
    159   br i1 %i.cmp, label %loop, label %exit
    160 
    161 exit:
    162   %x.lcssa = phi i32 [ %x.loop, %loop.latch ]
    163   ret i32 %x.lcssa
    164 }
    165