1; Test that we can evaluate the exit values of various expression types.  Since
2; these loops all have predictable exit values we can replace the use outside
3; of the loop with a closed-form computation, making the loop dead.
4;
5; RUN: opt < %s -indvars -loop-deletion -simplifycfg -S | FileCheck %s
6
7; CHECK-NOT: br
8
9define i32 @polynomial_constant() {
10; <label>:0
11	br label %Loop
12
13Loop:		; preds = %Loop, %0
14	%A1 = phi i32 [ 0, %0 ], [ %A2, %Loop ]		; <i32> [#uses=3]
15	%B1 = phi i32 [ 0, %0 ], [ %B2, %Loop ]		; <i32> [#uses=1]
16	%A2 = add i32 %A1, 1		; <i32> [#uses=1]
17	%B2 = add i32 %B1, %A1		; <i32> [#uses=2]
18	%C = icmp eq i32 %A1, 1000		; <i1> [#uses=1]
19	br i1 %C, label %Out, label %Loop
20
21Out:		; preds = %Loop
22	ret i32 %B2
23}
24
25define i32 @NSquare(i32 %N) {
26; <label>:0
27	br label %Loop
28
29Loop:		; preds = %Loop, %0
30	%X = phi i32 [ 0, %0 ], [ %X2, %Loop ]		; <i32> [#uses=4]
31	%X2 = add i32 %X, 1		; <i32> [#uses=1]
32	%c = icmp eq i32 %X, %N		; <i1> [#uses=1]
33	br i1 %c, label %Out, label %Loop
34
35Out:		; preds = %Loop
36	%Y = mul i32 %X, %X		; <i32> [#uses=1]
37	ret i32 %Y
38}
39
40define i32 @NSquareOver2(i32 %N) {
41; <label>:0
42	br label %Loop
43
44Loop:		; preds = %Loop, %0
45	%X = phi i32 [ 0, %0 ], [ %X2, %Loop ]		; <i32> [#uses=3]
46	%Y = phi i32 [ 15, %0 ], [ %Y2, %Loop ]		; <i32> [#uses=1]
47	%Y2 = add i32 %Y, %X		; <i32> [#uses=2]
48	%X2 = add i32 %X, 1		; <i32> [#uses=1]
49	%c = icmp eq i32 %X, %N		; <i1> [#uses=1]
50	br i1 %c, label %Out, label %Loop
51
52Out:		; preds = %Loop
53	ret i32 %Y2
54}
55
56define i32 @strength_reduced() {
57; <label>:0
58	br label %Loop
59
60Loop:		; preds = %Loop, %0
61	%A1 = phi i32 [ 0, %0 ], [ %A2, %Loop ]		; <i32> [#uses=3]
62	%B1 = phi i32 [ 0, %0 ], [ %B2, %Loop ]		; <i32> [#uses=1]
63	%A2 = add i32 %A1, 1		; <i32> [#uses=1]
64	%B2 = add i32 %B1, %A1		; <i32> [#uses=2]
65	%C = icmp eq i32 %A1, 1000		; <i1> [#uses=1]
66	br i1 %C, label %Out, label %Loop
67
68Out:		; preds = %Loop
69	ret i32 %B2
70}
71
72define i32 @chrec_equals() {
73entry:
74	br label %no_exit
75
76no_exit:		; preds = %no_exit, %entry
77	%i0 = phi i32 [ 0, %entry ], [ %i1, %no_exit ]		; <i32> [#uses=3]
78	%ISq = mul i32 %i0, %i0		; <i32> [#uses=1]
79	%i1 = add i32 %i0, 1		; <i32> [#uses=2]
80	%tmp.1 = icmp ne i32 %ISq, 10000		; <i1> [#uses=1]
81	br i1 %tmp.1, label %no_exit, label %loopexit
82
83loopexit:		; preds = %no_exit
84	ret i32 %i1
85}
86
87define i16 @cast_chrec_test() {
88; <label>:0
89	br label %Loop
90
91Loop:		; preds = %Loop, %0
92	%A1 = phi i32 [ 0, %0 ], [ %A2, %Loop ]		; <i32> [#uses=2]
93	%B1 = trunc i32 %A1 to i16		; <i16> [#uses=2]
94	%A2 = add i32 %A1, 1		; <i32> [#uses=1]
95	%C = icmp eq i16 %B1, 1000		; <i1> [#uses=1]
96	br i1 %C, label %Out, label %Loop
97
98Out:		; preds = %Loop
99	ret i16 %B1
100}
101
102define i32 @linear_div_fold() {
103entry:
104	br label %loop
105
106loop:		; preds = %loop, %entry
107	%i = phi i32 [ 4, %entry ], [ %i.next, %loop ]		; <i32> [#uses=3]
108	%i.next = add i32 %i, 8		; <i32> [#uses=1]
109	%RV = udiv i32 %i, 2		; <i32> [#uses=1]
110	%c = icmp ne i32 %i, 68		; <i1> [#uses=1]
111	br i1 %c, label %loop, label %loopexit
112
113loopexit:		; preds = %loop
114	ret i32 %RV
115}
116