diff options
Diffstat (limited to 'llvm/test/Transforms/LoopInterchange')
| -rw-r--r-- | llvm/test/Transforms/LoopInterchange/perserve-lcssa.ll | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/llvm/test/Transforms/LoopInterchange/perserve-lcssa.ll b/llvm/test/Transforms/LoopInterchange/perserve-lcssa.ll new file mode 100644 index 00000000000..af61709873c --- /dev/null +++ b/llvm/test/Transforms/LoopInterchange/perserve-lcssa.ll @@ -0,0 +1,181 @@ +; RUN: opt < %s -loop-interchange -loop-interchange-threshold=-100 -verify-loop-lcssa -S | FileCheck %s + +; Test case for PR41725. The induction variables in the latches escape the +; loops and we must move some PHIs around. + +@a = common dso_local global i64 0, align 4 +@b = common dso_local global i64 0, align 4 +@c = common dso_local global [10 x [1 x i32 ]] zeroinitializer, align 16 + + +define void @test_lcssa_indvars1() { +; CHECK-LABEL: @test_lcssa_indvars1() +; CHECK-LABEL: inner.body.split: +; CHECK-NEXT: %0 = phi i64 [ %iv.outer.next, %outer.latch ] +; CHECK-NEXT: %iv.inner.next = add nsw i64 %iv.inner, -1 + +; CHECK-LABEL: exit: +; CHECK-NEXT: %v4.lcssa = phi i64 [ %0, %inner.body.split ] +; CHECK-NEXT: %v8.lcssa.lcssa = phi i64 [ %iv.inner.next, %inner.body.split ] +; CHECK-NEXT: store i64 %v8.lcssa.lcssa, i64* @b, align 4 +; CHECK-NEXT: store i64 %v4.lcssa, i64* @a, align 4 + +entry: + br label %outer.header + +outer.header: ; preds = %outer.latch, %entry + %iv.outer = phi i64 [ 0, %entry ], [ %iv.outer.next, %outer.latch ] + br label %inner.body + +inner.body: ; preds = %inner.body, %outer.header + %iv.inner = phi i64 [ 5, %outer.header ], [ %iv.inner.next, %inner.body ] + %v7 = getelementptr inbounds [10 x [1 x i32]], [10 x [1 x i32]]* @c, i64 0, i64 %iv.inner, i64 %iv.outer + store i32 0, i32* %v7, align 4 + %iv.inner.next = add nsw i64 %iv.inner, -1 + %v9 = icmp eq i64 %iv.inner, 0 + br i1 %v9, label %outer.latch, label %inner.body + +outer.latch: ; preds = %inner.body + %v8.lcssa = phi i64 [ %iv.inner.next, %inner.body ] + %iv.outer.next = add nuw nsw i64 %iv.outer, 1 + %v5 = icmp ult i64 %iv.outer, 2 + br i1 %v5, label %outer.header, label %exit + +exit: ; preds = %outer.latch + %v4.lcssa = phi i64 [ %iv.outer.next, %outer.latch ] + %v8.lcssa.lcssa = phi i64 [ %v8.lcssa, %outer.latch ] + store i64 %v8.lcssa.lcssa, i64* @b, align 4 + store i64 %v4.lcssa, i64* @a, align 4 + ret void +} + + +define void @test_lcssa_indvars2() { +; CHECK-LABEL: @test_lcssa_indvars2() +; CHECK-LABEL: inner.body.split: +; CHECK-NEXT: %0 = phi i64 [ %iv.outer, %outer.latch ] +; CHECK-NEXT: %iv.inner.next = add nsw i64 %iv.inner, -1 + +; CHECK-LABEL: exit: +; CHECK-NEXT: %v4.lcssa = phi i64 [ %0, %inner.body.split ] +; CHECK-NEXT: %v8.lcssa.lcssa = phi i64 [ %iv.inner, %inner.body.split ] +; CHECK-NEXT: store i64 %v8.lcssa.lcssa, i64* @b, align 4 +; CHECK-NEXT: store i64 %v4.lcssa, i64* @a, align 4 + +entry: + br label %outer.header + +outer.header: ; preds = %outer.latch, %entry + %iv.outer = phi i64 [ 0, %entry ], [ %iv.outer.next, %outer.latch ] + br label %inner.body + +inner.body: ; preds = %inner.body, %outer.header + %iv.inner = phi i64 [ 5, %outer.header ], [ %iv.inner.next, %inner.body ] + %v7 = getelementptr inbounds [10 x [1 x i32]], [10 x [1 x i32]]* @c, i64 0, i64 %iv.inner, i64 %iv.outer + store i32 0, i32* %v7, align 4 + %iv.inner.next = add nsw i64 %iv.inner, -1 + %v9 = icmp eq i64 %iv.inner.next, 0 + br i1 %v9, label %outer.latch, label %inner.body + +outer.latch: ; preds = %inner.body + %v8.lcssa = phi i64 [ %iv.inner, %inner.body ] + %iv.outer.next = add nuw nsw i64 %iv.outer, 1 + %v5 = icmp ult i64 %iv.outer.next, 2 + br i1 %v5, label %outer.header, label %exit + +exit: ; preds = %outer.latch + %v4.lcssa = phi i64 [ %iv.outer, %outer.latch ] + %v8.lcssa.lcssa = phi i64 [ %v8.lcssa, %outer.latch ] + store i64 %v8.lcssa.lcssa, i64* @b, align 4 + store i64 %v4.lcssa, i64* @a, align 4 + ret void +} + +define void @test_lcssa_indvars3() { +; CHECK-LABEL: @test_lcssa_indvars3() +; CHECK-LABEL: inner.body.split: +; CHECK-NEXT: %0 = phi i64 [ %iv.outer.next, %outer.latch ] +; CHECK-NEXT: %iv.inner.next = add nsw i64 %iv.inner, -1 + +; CHECK-LABEL: exit: +; CHECK-NEXT: %v4.lcssa = phi i64 [ %0, %inner.body.split ] +; CHECK-NEXT: %v8.lcssa.lcssa = phi i64 [ %iv.inner.next, %inner.body.split ] +; CHECK-NEXT: %v8.lcssa.lcssa.2 = phi i64 [ %iv.inner.next, %inner.body.split ] +; CHECK-NEXT: %r1 = add i64 %v8.lcssa.lcssa, %v8.lcssa.lcssa.2 +; CHECK-NEXT: store i64 %r1, i64* @b, align 4 +; CHECK-NEXT: store i64 %v4.lcssa, i64* @a, align 4 + + +entry: + br label %outer.header + +outer.header: ; preds = %outer.latch, %entry + %iv.outer = phi i64 [ 0, %entry ], [ %iv.outer.next, %outer.latch ] + br label %inner.body + +inner.body: ; preds = %inner.body, %outer.header + %iv.inner = phi i64 [ 5, %outer.header ], [ %iv.inner.next, %inner.body ] + %v7 = getelementptr inbounds [10 x [1 x i32]], [10 x [1 x i32]]* @c, i64 0, i64 %iv.inner, i64 %iv.outer + store i32 0, i32* %v7, align 4 + %iv.inner.next = add nsw i64 %iv.inner, -1 + %v9 = icmp eq i64 %iv.inner, 0 + br i1 %v9, label %outer.latch, label %inner.body + +outer.latch: ; preds = %inner.body + %v8.lcssa = phi i64 [ %iv.inner.next, %inner.body ] + ;%const.lcssa = phi i64 [ 111, %inner.body ] + %iv.outer.next = add nuw nsw i64 %iv.outer, 1 + %v5 = icmp ult i64 %iv.outer, 2 + br i1 %v5, label %outer.header, label %exit + +exit: ; preds = %outer.latch + %v4.lcssa = phi i64 [ %iv.outer.next, %outer.latch ] + %v8.lcssa.lcssa = phi i64 [ %v8.lcssa, %outer.latch ] + %v8.lcssa.lcssa.2 = phi i64 [ %v8.lcssa, %outer.latch ] + %r1 = add i64 %v8.lcssa.lcssa, %v8.lcssa.lcssa.2 + store i64 %r1, i64* @b, align 4 + store i64 %v4.lcssa, i64* @a, align 4 + ret void +} + + +; Make sure we do not crash for loops without reachable exits. +define void @no_reachable_exits() { +; Check we interchanged. +; CHECK-LABEL: @no_reachable_exits() { +; CHECK-NEXT: bb: +; CHECK-NEXT: br label %inner.ph +; CHECK-LABEL: outer.ph: +; CHECK-NEXT: br label %outer.header +; CHECK-LABEL: inner.ph: +; CHECK-NEXT: br label %inner.body +; CHECK-LABEL: inner.body: +; CHECK-NEXT: %tmp31 = phi i32 [ 0, %inner.ph ], [ %tmp6, %inner.body.split ] +; CHECK-NEXT: br label %outer.ph + +bb: + br label %outer.ph + +outer.ph: ; preds = %bb + br label %outer.header + +outer.header: ; preds = %outer.ph, %outer.latch + %tmp2 = phi i32 [ 0, %outer.ph ], [ %tmp8, %outer.latch ] + br i1 undef, label %inner.ph, label %outer.latch + +inner.ph: ; preds = %outer.header + br label %inner.body + +inner.body: ; preds = %inner.ph, %inner.body + %tmp31 = phi i32 [ 0, %inner.ph ], [ %tmp6, %inner.body] + %tmp5 = load i32*, i32** undef, align 8 + %tmp6 = add nsw i32 %tmp31, 1 + br i1 undef, label %inner.body, label %outer.latch + +outer.latch: ; preds = %inner.body, %outer.header + %tmp8 = add nsw i32 %tmp2, 1 + br i1 undef, label %outer.header, label %exit + +exit: ; preds = %outer.latch + unreachable +} |

