[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / Transforms / LoopInterchange / perserve-lcssa.ll
blobaf61709873c0202140add0e841042497cdc9d8d1
1 ; RUN: opt < %s -loop-interchange -loop-interchange-threshold=-100 -verify-loop-lcssa -S | FileCheck %s
3 ; Test case for PR41725. The induction variables in the latches escape the
4 ; loops and we must move some PHIs around.
6 @a = common dso_local global i64 0, align 4
7 @b = common dso_local global i64 0, align 4
8 @c = common dso_local global [10 x [1 x i32 ]] zeroinitializer, align 16
11 define void @test_lcssa_indvars1()  {
12 ; CHECK-LABEL: @test_lcssa_indvars1()
13 ; CHECK-LABEL: inner.body.split:
14 ; CHECK-NEXT:    %0 = phi i64 [ %iv.outer.next, %outer.latch ]
15 ; CHECK-NEXT:    %iv.inner.next = add nsw i64 %iv.inner, -1
17 ; CHECK-LABEL: exit:
18 ; CHECK-NEXT:    %v4.lcssa = phi i64 [ %0, %inner.body.split ]
19 ; CHECK-NEXT:    %v8.lcssa.lcssa = phi i64 [ %iv.inner.next, %inner.body.split ]
20 ; CHECK-NEXT:    store i64 %v8.lcssa.lcssa, i64* @b, align 4
21 ; CHECK-NEXT:    store i64 %v4.lcssa, i64* @a, align 4
23 entry:
24   br label %outer.header
26 outer.header:                                     ; preds = %outer.latch, %entry
27   %iv.outer = phi i64 [ 0, %entry ], [ %iv.outer.next, %outer.latch ]
28   br label %inner.body
30 inner.body:                                       ; preds = %inner.body, %outer.header
31   %iv.inner = phi i64 [ 5, %outer.header ], [ %iv.inner.next, %inner.body ]
32   %v7 = getelementptr inbounds [10 x [1 x i32]], [10 x [1 x i32]]* @c, i64 0, i64 %iv.inner, i64 %iv.outer
33   store i32 0, i32* %v7, align 4
34   %iv.inner.next = add nsw i64 %iv.inner, -1
35   %v9 = icmp eq i64 %iv.inner, 0
36   br i1 %v9, label %outer.latch, label %inner.body
38 outer.latch:                                      ; preds = %inner.body
39   %v8.lcssa = phi i64 [ %iv.inner.next, %inner.body ]
40   %iv.outer.next = add nuw nsw i64 %iv.outer, 1
41   %v5 = icmp ult i64 %iv.outer, 2
42   br i1 %v5, label %outer.header, label %exit
44 exit:                                             ; preds = %outer.latch
45   %v4.lcssa = phi i64 [ %iv.outer.next, %outer.latch ]
46   %v8.lcssa.lcssa = phi i64 [ %v8.lcssa, %outer.latch ]
47   store i64 %v8.lcssa.lcssa, i64* @b, align 4
48   store i64 %v4.lcssa, i64* @a, align 4
49   ret void
53 define void @test_lcssa_indvars2()  {
54 ; CHECK-LABEL: @test_lcssa_indvars2()
55 ; CHECK-LABEL: inner.body.split:
56 ; CHECK-NEXT:    %0 = phi i64 [ %iv.outer, %outer.latch ]
57 ; CHECK-NEXT:    %iv.inner.next = add nsw i64 %iv.inner, -1
59 ; CHECK-LABEL: exit:
60 ; CHECK-NEXT:    %v4.lcssa = phi i64 [ %0, %inner.body.split ]
61 ; CHECK-NEXT:    %v8.lcssa.lcssa = phi i64 [ %iv.inner, %inner.body.split ]
62 ; CHECK-NEXT:    store i64 %v8.lcssa.lcssa, i64* @b, align 4
63 ; CHECK-NEXT:    store i64 %v4.lcssa, i64* @a, align 4
65 entry:
66   br label %outer.header
68 outer.header:                                     ; preds = %outer.latch, %entry
69   %iv.outer = phi i64 [ 0, %entry ], [ %iv.outer.next, %outer.latch ]
70   br label %inner.body
72 inner.body:                                       ; preds = %inner.body, %outer.header
73   %iv.inner = phi i64 [ 5, %outer.header ], [ %iv.inner.next, %inner.body ]
74   %v7 = getelementptr inbounds [10 x [1 x i32]], [10 x [1 x i32]]* @c, i64 0, i64 %iv.inner, i64 %iv.outer
75   store i32 0, i32* %v7, align 4
76   %iv.inner.next = add nsw i64 %iv.inner, -1
77   %v9 = icmp eq i64 %iv.inner.next, 0
78   br i1 %v9, label %outer.latch, label %inner.body
80 outer.latch:                                      ; preds = %inner.body
81   %v8.lcssa = phi i64 [ %iv.inner, %inner.body ]
82   %iv.outer.next = add nuw nsw i64 %iv.outer, 1
83   %v5 = icmp ult i64 %iv.outer.next, 2
84   br i1 %v5, label %outer.header, label %exit
86 exit:                                             ; preds = %outer.latch
87   %v4.lcssa = phi i64 [ %iv.outer, %outer.latch ]
88   %v8.lcssa.lcssa = phi i64 [ %v8.lcssa, %outer.latch ]
89   store i64 %v8.lcssa.lcssa, i64* @b, align 4
90   store i64 %v4.lcssa, i64* @a, align 4
91   ret void
94 define void @test_lcssa_indvars3()  {
95 ; CHECK-LABEL: @test_lcssa_indvars3()
96 ; CHECK-LABEL: inner.body.split:
97 ; CHECK-NEXT:    %0 = phi i64 [ %iv.outer.next, %outer.latch ]
98 ; CHECK-NEXT:    %iv.inner.next = add nsw i64 %iv.inner, -1
100 ; CHECK-LABEL: exit:
101 ; CHECK-NEXT:    %v4.lcssa = phi i64 [ %0, %inner.body.split ]
102 ; CHECK-NEXT:    %v8.lcssa.lcssa = phi i64 [ %iv.inner.next, %inner.body.split ]
103 ; CHECK-NEXT:    %v8.lcssa.lcssa.2 = phi i64 [ %iv.inner.next, %inner.body.split ]
104 ; CHECK-NEXT:    %r1 = add i64 %v8.lcssa.lcssa, %v8.lcssa.lcssa.2
105 ; CHECK-NEXT:    store i64 %r1, i64* @b, align 4
106 ; CHECK-NEXT:    store i64 %v4.lcssa, i64* @a, align 4
109 entry:
110   br label %outer.header
112 outer.header:                                     ; preds = %outer.latch, %entry
113   %iv.outer = phi i64 [ 0, %entry ], [ %iv.outer.next, %outer.latch ]
114   br label %inner.body
116 inner.body:                                       ; preds = %inner.body, %outer.header
117   %iv.inner = phi i64 [ 5, %outer.header ], [ %iv.inner.next, %inner.body ]
118   %v7 = getelementptr inbounds [10 x [1 x i32]], [10 x [1 x i32]]* @c, i64 0, i64 %iv.inner, i64 %iv.outer
119   store i32 0, i32* %v7, align 4
120   %iv.inner.next = add nsw i64 %iv.inner, -1
121   %v9 = icmp eq i64 %iv.inner, 0
122   br i1 %v9, label %outer.latch, label %inner.body
124 outer.latch:                                      ; preds = %inner.body
125   %v8.lcssa = phi i64 [ %iv.inner.next, %inner.body ]
126   ;%const.lcssa = phi i64 [ 111, %inner.body ]
127   %iv.outer.next = add nuw nsw i64 %iv.outer, 1
128   %v5 = icmp ult i64 %iv.outer, 2
129   br i1 %v5, label %outer.header, label %exit
131 exit:                                             ; preds = %outer.latch
132   %v4.lcssa = phi i64 [ %iv.outer.next, %outer.latch ]
133   %v8.lcssa.lcssa = phi i64 [ %v8.lcssa, %outer.latch ]
134   %v8.lcssa.lcssa.2 = phi i64 [ %v8.lcssa, %outer.latch ]
135   %r1 = add i64 %v8.lcssa.lcssa, %v8.lcssa.lcssa.2
136   store i64 %r1, i64* @b, align 4
137   store i64 %v4.lcssa, i64* @a, align 4
138   ret void
142 ; Make sure we do not crash for loops without reachable exits.
143 define void @no_reachable_exits() {
144 ; Check we interchanged.
145 ; CHECK-LABEL: @no_reachable_exits() {
146 ; CHECK-NEXT:  bb:
147 ; CHECK-NEXT:    br label %inner.ph
148 ; CHECK-LABEL: outer.ph:
149 ; CHECK-NEXT:    br label %outer.header
150 ; CHECK-LABEL: inner.ph:
151 ; CHECK-NEXT:    br label %inner.body
152 ; CHECK-LABEL: inner.body:
153 ; CHECK-NEXT:    %tmp31 = phi i32 [ 0, %inner.ph ], [ %tmp6, %inner.body.split ]
154 ; CHECK-NEXT:    br label %outer.ph
157   br label %outer.ph
159 outer.ph:                              ; preds = %bb
160   br label %outer.header
162 outer.header:                                    ; preds = %outer.ph, %outer.latch
163   %tmp2 = phi i32 [ 0, %outer.ph ], [ %tmp8, %outer.latch ]
164   br i1 undef, label %inner.ph, label %outer.latch
166 inner.ph:                                        ; preds = %outer.header
167   br label %inner.body
169 inner.body:                                              ; preds = %inner.ph, %inner.body
170   %tmp31 = phi i32 [ 0, %inner.ph ], [ %tmp6, %inner.body]
171   %tmp5 = load i32*, i32** undef, align 8
172   %tmp6 = add nsw i32 %tmp31, 1
173   br i1 undef, label %inner.body, label %outer.latch
175 outer.latch:                                              ; preds = %inner.body, %outer.header
176   %tmp8 = add nsw i32 %tmp2, 1
177   br i1 undef, label %outer.header, label %exit
179 exit:                                              ; preds = %outer.latch
180   unreachable