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