indvars: fixed IV cloning in -disable-iv-rewrite mode with associated
[oota-llvm.git] / test / Transforms / IndVarSimplify / no-iv-rewrite.ll
1 ; RUN: opt < %s -indvars -disable-iv-rewrite -S | FileCheck %s
2 ;
3 ; Make sure that indvars isn't inserting canonical IVs.
4 ; This is kinda hard to do until linear function test replacement is removed.
5
6 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"
7
8 define i32 @sum(i32* %arr, i32 %n) nounwind {
9 entry:
10   %precond = icmp slt i32 0, %n
11   br i1 %precond, label %ph, label %return
12
13 ph:
14   br label %loop
15
16 ; CHECK: loop:
17 ;
18 ; We should only have 2 IVs.
19 ; CHECK: phi
20 ; CHECK: phi
21 ; CHECK-NOT: phi
22 ;
23 ; sext should be eliminated while preserving gep inboundsness.
24 ; CHECK-NOT: sext
25 ; CHECK: getelementptr inbounds
26 loop:
27   %i.02 = phi i32 [ 0, %ph ], [ %iinc, %loop ]
28   %s.01 = phi i32 [ 0, %ph ], [ %sinc, %loop ]
29   %ofs = sext i32 %i.02 to i64
30   %adr = getelementptr inbounds i32* %arr, i64 %ofs
31   %val = load i32* %adr
32   %sinc = add nsw i32 %s.01, %val
33   %iinc = add nsw i32 %i.02, 1
34   %cond = icmp slt i32 %iinc, %n
35   br i1 %cond, label %loop, label %exit
36
37 exit:
38   %s.lcssa = phi i32 [ %sinc, %loop ]
39   br label %return
40
41 return:
42   %s.0.lcssa = phi i32 [ %s.lcssa, %exit ], [ 0, %entry ]
43   ret i32 %s.0.lcssa
44 }
45
46 define i64 @suml(i32* %arr, i32 %n) nounwind {
47 entry:
48   %precond = icmp slt i32 0, %n
49   br i1 %precond, label %ph, label %return
50
51 ph:
52   br label %loop
53
54 ; CHECK: loop:
55 ;
56 ; We should only have 2 IVs.
57 ; CHECK: phi
58 ; CHECK: phi
59 ; CHECK-NOT: phi
60 ;
61 ; %ofs sext should be eliminated while preserving gep inboundsness.
62 ; CHECK-NOT: sext
63 ; CHECK: getelementptr inbounds
64 ; %vall sext should obviously not be eliminated
65 ; CHECK: sext
66 loop:
67   %i.02 = phi i32 [ 0, %ph ], [ %iinc, %loop ]
68   %s.01 = phi i64 [ 0, %ph ], [ %sinc, %loop ]
69   %ofs = sext i32 %i.02 to i64
70   %adr = getelementptr inbounds i32* %arr, i64 %ofs
71   %val = load i32* %adr
72   %vall = sext i32 %val to i64
73   %sinc = add nsw i64 %s.01, %vall
74   %iinc = add nsw i32 %i.02, 1
75   %cond = icmp slt i32 %iinc, %n
76   br i1 %cond, label %loop, label %exit
77
78 exit:
79   %s.lcssa = phi i64 [ %sinc, %loop ]
80   br label %return
81
82 return:
83   %s.0.lcssa = phi i64 [ %s.lcssa, %exit ], [ 0, %entry ]
84   ret i64 %s.0.lcssa
85 }
86
87 define void @outofbounds(i32* %first, i32* %last, i32 %idx) nounwind {
88   %precond = icmp ne i32* %first, %last
89   br i1 %precond, label %ph, label %return
90
91 ; CHECK: ph:
92 ; It's not indvars' job to perform LICM on %ofs
93 ; CHECK-NOT: sext
94 ph:
95   br label %loop
96
97 ; CHECK: loop:
98 ;
99 ; Preserve exactly one pointer type IV.
100 ; CHECK: phi i32*
101 ; CHECK-NOT: phi
102 ;
103 ; Don't create any extra adds.
104 ; CHECK-NOT: add
105 ;
106 ; Preserve gep inboundsness, and don't factor it.
107 ; CHECK: getelementptr inbounds i32* %ptriv, i32 1
108 ; CHECK-NOT: add
109 loop:
110   %ptriv = phi i32* [ %first, %ph ], [ %ptrpost, %loop ]
111   %ofs = sext i32 %idx to i64
112   %adr = getelementptr inbounds i32* %ptriv, i64 %ofs
113   store i32 3, i32* %adr
114   %ptrpost = getelementptr inbounds i32* %ptriv, i32 1
115   %cond = icmp ne i32* %ptrpost, %last
116   br i1 %cond, label %loop, label %exit
117
118 exit:
119   br label %return
120
121 return:
122   ret void
123 }