mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
1542bebc55
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
166 lines
5.5 KiB
LLVM
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
|
|
}
|