indvars -disable-iv-rewrite: handle cloning binary operators that cannot overflow.
[oota-llvm.git] / test / Transforms / IndVarSimplify / addrec-gep.ll
1 ; RUN: opt < %s -indvars -S > %t
2 ; RUN: grep getelementptr %t | count 1
3 ; RUN: grep {mul .*, 37}  %t | count 1
4 ; RUN: grep {add .*, 5203}  %t | count 1
5 ; RUN: not grep cast %t
6
7 ; This test tests several things. The load and store should use the
8 ; same address instead of having it computed twice, and SCEVExpander should
9 ; be able to reconstruct the full getelementptr, despite it having a few
10 ; obstacles set in its way.
11
12 target datalayout = "e-p:64:64:64-n:32:64"
13
14 define void @foo(i64 %n, i64 %m, i64 %o, i64 %q, double* nocapture %p) nounwind {
15 entry:
16         %tmp = icmp sgt i64 %n, 0               ; <i1> [#uses=1]
17         br i1 %tmp, label %bb.nph3, label %return
18
19 bb.nph:         ; preds = %bb2.preheader
20         %tmp1 = mul i64 %tmp16, %i.02           ; <i64> [#uses=1]
21         %tmp2 = mul i64 %tmp19, %i.02           ; <i64> [#uses=1]
22         br label %bb1
23
24 bb1:            ; preds = %bb2, %bb.nph
25         %j.01 = phi i64 [ %tmp9, %bb2 ], [ 0, %bb.nph ]         ; <i64> [#uses=3]
26         %tmp3 = add i64 %j.01, %tmp1            ; <i64> [#uses=1]
27         %tmp4 = add i64 %j.01, %tmp2            ; <i64> [#uses=1]
28         %z0 = add i64 %tmp3, 5203
29         %tmp5 = getelementptr double* %p, i64 %z0               ; <double*> [#uses=1]
30         %tmp6 = load double* %tmp5, align 8             ; <double> [#uses=1]
31         %tmp7 = fdiv double %tmp6, 2.100000e+00         ; <double> [#uses=1]
32         %z1 = add i64 %tmp4, 5203
33         %tmp8 = getelementptr double* %p, i64 %z1               ; <double*> [#uses=1]
34         store double %tmp7, double* %tmp8, align 8
35         %tmp9 = add i64 %j.01, 1                ; <i64> [#uses=2]
36         br label %bb2
37
38 bb2:            ; preds = %bb1
39         %tmp10 = icmp slt i64 %tmp9, %m         ; <i1> [#uses=1]
40         br i1 %tmp10, label %bb1, label %bb2.bb3_crit_edge
41
42 bb2.bb3_crit_edge:              ; preds = %bb2
43         br label %bb3
44
45 bb3:            ; preds = %bb2.preheader, %bb2.bb3_crit_edge
46         %tmp11 = add i64 %i.02, 1               ; <i64> [#uses=2]
47         br label %bb4
48
49 bb4:            ; preds = %bb3
50         %tmp12 = icmp slt i64 %tmp11, %n                ; <i1> [#uses=1]
51         br i1 %tmp12, label %bb2.preheader, label %bb4.return_crit_edge
52
53 bb4.return_crit_edge:           ; preds = %bb4
54         br label %bb4.return_crit_edge.split
55
56 bb4.return_crit_edge.split:             ; preds = %bb.nph3, %bb4.return_crit_edge
57         br label %return
58
59 bb.nph3:                ; preds = %entry
60         %tmp13 = icmp sgt i64 %m, 0             ; <i1> [#uses=1]
61         %tmp14 = mul i64 %n, 37         ; <i64> [#uses=1]
62         %tmp15 = mul i64 %tmp14, %o             ; <i64> [#uses=1]
63         %tmp16 = mul i64 %tmp15, %q             ; <i64> [#uses=1]
64         %tmp17 = mul i64 %n, 37         ; <i64> [#uses=1]
65         %tmp18 = mul i64 %tmp17, %o             ; <i64> [#uses=1]
66         %tmp19 = mul i64 %tmp18, %q             ; <i64> [#uses=1]
67         br i1 %tmp13, label %bb.nph3.split, label %bb4.return_crit_edge.split
68
69 bb.nph3.split:          ; preds = %bb.nph3
70         br label %bb2.preheader
71
72 bb2.preheader:          ; preds = %bb.nph3.split, %bb4
73         %i.02 = phi i64 [ %tmp11, %bb4 ], [ 0, %bb.nph3.split ]         ; <i64> [#uses=3]
74         br i1 true, label %bb.nph, label %bb3
75
76 return:         ; preds = %bb4.return_crit_edge.split, %entry
77         ret void
78 }