1; RUN: opt -analyze -enable-new-pm=0 -scalar-evolution < %s | FileCheck %s
2; RUN: opt -disable-output "-passes=print<scalar-evolution>" < %s 2>&1 | FileCheck %s
3
4define i32 @f0(i32 %x, i32 %y) {
5; CHECK-LABEL: Classifying expressions for: @f0
6 entry:
7  %c = icmp sgt i32 %y, 0
8  br i1 %c, label %add, label %merge
9
10 add:
11  %sum = add i32 %x, %y
12  br label %merge
13
14 merge:
15  %v = phi i32 [ %sum, %add ], [ %x, %entry ]
16; CHECK:  %v = phi i32 [ %sum, %add ], [ %x, %entry ]
17; CHECK-NEXT:  -->  ((0 smax %y) + %x) U: full-set S: full-set
18  ret i32 %v
19}
20
21define i32 @f1(i32 %x, i32 %y) {
22; CHECK-LABEL: Classifying expressions for: @f1
23 entry:
24  %c = icmp sge i32 %y, 0
25  br i1 %c, label %add, label %merge
26
27 add:
28  %sum = add i32 %x, %y
29  br label %merge
30
31 merge:
32  %v = phi i32 [ %sum, %add ], [ %x, %entry ]
33; CHECK:  %v = phi i32 [ %sum, %add ], [ %x, %entry ]
34; CHECK-NEXT:  -->  ((0 smax %y) + %x) U: full-set S: full-set
35  ret i32 %v
36}
37
38define i32 @f2(i32 %x, i32 %y, i32* %ptr) {
39; CHECK-LABEL: Classifying expressions for: @f2
40 entry:
41  %c = icmp sge i32 %y, 0
42  br i1 %c, label %add, label %merge
43
44 add:
45  %lv = load i32, i32* %ptr
46  br label %merge
47
48 merge:
49  %v = phi i32 [ %lv, %add ], [ %x, %entry ]
50; CHECK:  %v = phi i32 [ %lv, %add ], [ %x, %entry ]
51; CHECK-NEXT:  -->  %v U: full-set S: full-set
52  ret i32 %v
53}
54
55define i32 @f3(i32 %x, i32 %init, i32 %lim) {
56; CHECK-LABEL: Classifying expressions for: @f3
57 entry:
58  br label %loop
59
60loop:
61  %iv = phi i32 [ %init, %entry ], [ %iv.inc, %merge ]
62  %iv.inc = add i32 %iv, 1
63  %c = icmp sge i32 %iv, 0
64  br i1 %c, label %add, label %merge
65
66 add:
67  %sum = add i32 %x, %iv
68  br label %merge
69
70 merge:
71  %v = phi i32 [ %sum, %add ], [ %x, %loop ]
72; CHECK:  %v = phi i32 [ %sum, %add ], [ %x, %loop ]
73; CHECK-NEXT:  -->  ((0 smax {%init,+,1}<%loop>) + %x) U: full-set S: full-set
74  %be.cond = icmp eq i32 %iv.inc, %lim
75  br i1 %be.cond, label %loop, label %leave
76
77 leave:
78  ret i32 0
79}
80
81define i32 @f4(i32 %x, i32 %init, i32 %lim) {
82; CHECK-LABEL: Classifying expressions for: @f4
83 entry:
84  %c = icmp sge i32 %init, 0
85  br i1 %c, label %add, label %merge
86
87 add:
88  br label %loop
89
90 loop:
91  %iv = phi i32 [ %init, %add ], [ %iv.inc, %loop ]
92  %iv.inc = add i32 %iv, 1
93  %be.cond = icmp eq i32 %iv.inc, %lim
94  br i1 %be.cond, label %loop, label %add.cont
95
96 add.cont:
97  %sum = add i32 %x, %iv
98  br label %merge
99
100 merge:
101  %v = phi i32 [ %sum, %add.cont ], [ %x, %entry ]
102; CHECK:  %v = phi i32 [ %sum, %add.cont ], [ %x, %entry ]
103; CHECK-NEXT:  -->  %v U: full-set S: full-set
104  ret i32 %v
105}
106
107define i32 @f5(i32* %val) {
108; CHECK-LABEL: Classifying expressions for: @f5
109entry:
110  br label %for.end
111
112for.condt:
113  br i1 true, label %for.cond.0, label %for.end
114
115for.end:
116  %inc = load i32, i32* %val
117  br i1 false, label %for.condt, label %for.cond.0
118
119for.cond.0:
120  %init = phi i32 [ 0, %for.condt ], [ %inc, %for.end ]
121
122; CHECK:  %init = phi i32 [ 0, %for.condt ], [ %inc, %for.end ]
123; CHECK-NEXT:  -->  %init U: full-set S: full-set
124
125; Matching "through" %init will break LCSSA at the SCEV expression
126; level.
127
128  ret i32 %init
129}
130
131define i32 @f6(i32 %x, i32 %y) {
132; Do the right thing for unreachable code:
133
134; CHECK-LABEL: Classifying expressions for: @f6
135 entry:
136  %c0 = icmp sgt i32 %y, 0
137  %sum = add i32 %x, %y
138  br i1 %c0, label %merge, label %leave_1
139
140 merge:
141  %v0 = phi i32 [ %sum, %entry ], [ %v1, %unreachable ]
142  %c1 = icmp slt i32 %y, 0
143  br i1 %c1, label %leave_0, label %leave_0_cond
144
145leave_0_cond:
146  br label %leave_0
147
148leave_0:
149  %v1 = phi i32 [ %v0, %merge ], [ 0, %leave_0_cond ]
150  ret i32 0
151
152leave_1:
153  ret i32 0
154
155unreachable:
156  br label %merge
157}
158