llvm-mirror/test/Transforms/LoopInstSimplify/basic.ll
Alina Sbirlea 1542bebc55 [LoopPassManager + MemorySSA] Only enable use of MemorySSA for LPMs known to preserve it.
Summary:
Add a flag to the FunctionToLoopAdaptor that allows enabling MemorySSA only for the loop pass managers that are known to preserve it.

If an LPM is known to have only loop transforms that *all* preserve MemorySSA, then use MemorySSA if `EnableMSSALoopDependency` is set.
If an LPM has loop passes that do not preserve MemorySSA, then the flag passed is `false`, regardless of the value of `EnableMSSALoopDependency`.

When using a custom loop pass pipeline via `passes=...`, use keyword `loop` vs `loop-mssa` to use MemorySSA in that LPM. If a loop that does not preserve MemorySSA is added while using the `loop-mssa` keyword, that's an error.

Add the new `loop-mssa` keyword to a few tests where a difference occurs when enabling MemorySSA.

Reviewers: chandlerc

Subscribers: mehdi_amini, Prazek, george.burgess.iv, sanjoy.google, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D66376

llvm-svn: 369548
2019-08-21 17:00:57 +00:00

166 lines
5.5 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -S %s -passes=loop-instsimplify | FileCheck %s
; RUN: opt -S %s -passes='loop-mssa(loop-instsimplify)' -verify-memoryssa | FileCheck %s
; Test very basic folding and propagation occurs within a loop body. This should
; collapse to the loop iteration structure and the LCSSA PHI node.
define i32 @test1(i32 %n, i32 %x) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
; CHECK-NEXT: [[I_CMP:%.*]] = icmp slt i32 [[I_NEXT]], [[N:%.*]]
; CHECK-NEXT: br i1 [[I_CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: [[X_LCSSA:%.*]] = phi i32 [ [[X:%.*]], [[LOOP]] ]
; CHECK-NEXT: ret i32 [[X_LCSSA]]
;
entry:
br label %loop
loop:
%i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
%x.add = add nsw i32 %x, 0
%x.sub = sub i32 %x.add, 0
%x.and = and i32 %x.sub, -1
%i.next = add nsw i32 %i, 1
%i.cmp = icmp slt i32 %i.next, %n
br i1 %i.cmp, label %loop, label %exit
exit:
%x.lcssa = phi i32 [ %x.and, %loop ]
ret i32 %x.lcssa
}
; Test basic loop structure that still has a simplification feed a prior PHI.
define i32 @test2(i32 %n, i32 %x) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
; CHECK-NEXT: [[I_CMP:%.*]] = icmp slt i32 [[I_NEXT]], [[N:%.*]]
; CHECK-NEXT: br i1 [[I_CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: [[X_LCSSA:%.*]] = phi i32 [ [[X:%.*]], [[LOOP]] ]
; CHECK-NEXT: ret i32 [[X_LCSSA]]
;
entry:
br label %loop
loop:
%i = phi i32 [ 0, %entry ], [ %i.next, %loop ]
%x.loop = phi i32 [ %x, %entry ], [ %x.next, %loop ]
%x.next = add nsw i32 %x.loop, 0
%i.next = add nsw i32 %i, 1
%i.cmp = icmp slt i32 %i.next, %n
br i1 %i.cmp, label %loop, label %exit
exit:
%x.lcssa = phi i32 [ %x.loop, %loop ]
ret i32 %x.lcssa
}
; Test a diamond CFG with inner PHI nodes.
define i32 @test3(i32 %n, i32 %x) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: [[X_CMP:%.*]] = icmp slt i32 [[I]], 42
; CHECK-NEXT: br i1 [[X_CMP]], label [[LOOP_LHS:%.*]], label [[LOOP_RHS:%.*]]
; CHECK: loop.lhs:
; CHECK-NEXT: br label [[LOOP_LATCH]]
; CHECK: loop.rhs:
; CHECK-NEXT: br label [[LOOP_LATCH]]
; CHECK: loop.latch:
; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
; CHECK-NEXT: [[I_CMP:%.*]] = icmp slt i32 [[I_NEXT]], [[N:%.*]]
; CHECK-NEXT: br i1 [[I_CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: [[X_LCSSA:%.*]] = phi i32 [ [[X:%.*]], [[LOOP_LATCH]] ]
; CHECK-NEXT: ret i32 [[X_LCSSA]]
;
entry:
br label %loop
loop:
%i = phi i32 [ 0, %entry ], [ %i.next, %loop.latch ]
%x.loop = phi i32 [ %x, %entry ], [ %x.phi, %loop.latch ]
%x.add = add nsw i32 %x.loop, 0
%x.cmp = icmp slt i32 %i, 42
br i1 %x.cmp, label %loop.lhs, label %loop.rhs
loop.lhs:
%x.l.add = add nsw i32 %x.add, 0
br label %loop.latch
loop.rhs:
%x.r.sub = sub nsw i32 %x.add, 0
br label %loop.latch
loop.latch:
%x.phi = phi i32 [ %x.l.add, %loop.lhs ], [ %x.r.sub, %loop.rhs ]
%i.next = add nsw i32 %i, 1
%i.cmp = icmp slt i32 %i.next, %n
br i1 %i.cmp, label %loop, label %exit
exit:
%x.lcssa = phi i32 [ %x.loop, %loop.latch ]
ret i32 %x.lcssa
}
; Test an inner loop that is only simplified when processing the outer loop, and
; an outer loop only simplified when processing the inner loop.
define i32 @test4(i32 %n, i32 %m, i32 %x) {
; CHECK-LABEL: @test4(
; CHECK-NEXT: entry:
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[I:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[LOOP_LATCH:%.*]] ]
; CHECK-NEXT: br label [[LOOP_INNER:%.*]]
; CHECK: loop.inner:
; CHECK-NEXT: [[J:%.*]] = phi i32 [ 0, [[LOOP]] ], [ [[J_NEXT:%.*]], [[LOOP_INNER]] ]
; CHECK-NEXT: [[J_NEXT]] = add nsw i32 [[J]], 1
; CHECK-NEXT: [[J_CMP:%.*]] = icmp slt i32 [[J_NEXT]], [[M:%.*]]
; CHECK-NEXT: br i1 [[J_CMP]], label [[LOOP_INNER]], label [[LOOP_LATCH]]
; CHECK: loop.latch:
; CHECK-NEXT: [[I_NEXT]] = add nsw i32 [[I]], 1
; CHECK-NEXT: [[I_CMP:%.*]] = icmp slt i32 [[I_NEXT]], [[N:%.*]]
; CHECK-NEXT: br i1 [[I_CMP]], label [[LOOP]], label [[EXIT:%.*]]
; CHECK: exit:
; CHECK-NEXT: [[X_LCSSA:%.*]] = phi i32 [ [[X:%.*]], [[LOOP_LATCH]] ]
; CHECK-NEXT: ret i32 [[X_LCSSA]]
;
entry:
br label %loop
loop:
%i = phi i32 [ 0, %entry ], [ %i.next, %loop.latch ]
%x.loop = phi i32 [ %x, %entry ], [ %x.inner.lcssa, %loop.latch ]
%x.add = add nsw i32 %x.loop, 0
br label %loop.inner
loop.inner:
%j = phi i32 [ 0, %loop ], [ %j.next, %loop.inner ]
%x.inner.loop = phi i32 [ %x.add, %loop ], [ %x.inner.add, %loop.inner ]
%x.inner.add = add nsw i32 %x.inner.loop, 0
%j.next = add nsw i32 %j, 1
%j.cmp = icmp slt i32 %j.next, %m
br i1 %j.cmp, label %loop.inner, label %loop.latch
loop.latch:
%x.inner.lcssa = phi i32 [ %x.inner.loop, %loop.inner ]
%i.next = add nsw i32 %i, 1
%i.cmp = icmp slt i32 %i.next, %n
br i1 %i.cmp, label %loop, label %exit
exit:
%x.lcssa = phi i32 [ %x.loop, %loop.latch ]
ret i32 %x.lcssa
}