mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-23 15:29:51 +00:00
6a67a3f3ec
because of the inside-out run of LoopSimplify in the LoopPassManager and the fact that LoopSimplify couldn't be "preserved" across two independent LoopPassManagers. Anyways, in that case, IndVars wasn't correctly preserving an LCSSA PHI node because it thought it was rewriting (via SCEV) the incoming value to a loop invariant value. While it may well be invariant for the current loop, it may be rewritten in terms of an enclosing loop's values. This in and of itself is fine, as the LCSSA PHI node in the enclosing loop for the inner loop value we're rewriting will have its own LCSSA PHI node if used outside of the enclosing loop. With me so far? Well, the current loop and the enclosing loop may share an exiting block and exit block, and when they do they also share LCSSA PHI nodes. In this case, its not valid to RAUW through the LCSSA PHI node. Expected crazy test included. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200372 91177308-0d34-0410-b5e6-96231b3b80d8
52 lines
1.6 KiB
LLVM
52 lines
1.6 KiB
LLVM
; RUN: opt < %s -indvars -S | FileCheck %s
|
|
;
|
|
; Make sure IndVars preserves LCSSA form, especially across loop nests.
|
|
|
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
|
|
|
define void @PR18642(i32 %x) {
|
|
; CHECK-LABEL: @PR18642(
|
|
entry:
|
|
br label %outer.header
|
|
; CHECK: br label %outer.header
|
|
|
|
outer.header:
|
|
; CHECK: outer.header:
|
|
%outer.iv = phi i32 [ 0, %entry ], [ %x, %outer.latch ]
|
|
br label %inner.header
|
|
; CHECK: %[[SCEV_EXPANDED:.*]] = add i32
|
|
; CHECK: br label %inner.header
|
|
|
|
inner.header:
|
|
; CHECK: inner.header:
|
|
%inner.iv = phi i32 [ undef, %outer.header ], [ %inc, %inner.latch ]
|
|
%cmp1 = icmp slt i32 %inner.iv, %outer.iv
|
|
br i1 %cmp1, label %inner.latch, label %outer.latch
|
|
; CHECK: br i1 {{.*}}, label %inner.latch, label %outer.latch
|
|
|
|
inner.latch:
|
|
; CHECK: inner.latch:
|
|
%inc = add nsw i32 %inner.iv, 1
|
|
%cmp2 = icmp slt i32 %inner.iv, %outer.iv
|
|
br i1 %cmp2, label %inner.header, label %exit
|
|
; CHECK: br i1 {{.*}}, label %inner.header, label %[[EXIT_FROM_INNER:.*]]
|
|
|
|
outer.latch:
|
|
; CHECK: outer.latch:
|
|
br i1 undef, label %outer.header, label %exit
|
|
; CHECK: br i1 {{.*}}, label %outer.header, label %[[EXIT_FROM_OUTER:.*]]
|
|
|
|
; CHECK: [[EXIT_FROM_INNER]]:
|
|
; CHECK-NEXT: %[[LCSSA:.*]] = phi i32 [ %[[SCEV_EXPANDED]], %inner.latch ]
|
|
; CHECK-NEXT: br label %exit
|
|
|
|
; CHECK: [[EXIT_FROM_OUTER]]:
|
|
; CHECK-NEXT: br label %exit
|
|
|
|
exit:
|
|
; CHECK: exit:
|
|
%exit.phi = phi i32 [ %inc, %inner.latch ], [ undef, %outer.latch ]
|
|
; CHECK-NEXT: phi i32 [ %[[LCSSA]], %[[EXIT_FROM_INNER]] ], [ undef, %[[EXIT_FROM_OUTER]] ]
|
|
ret void
|
|
}
|