Add straight-line strength reduction to LLVM
[oota-llvm.git] / test / Transforms / StraightLineStrengthReduce / slsr.ll
1 ; RUN: opt < %s -slsr -gvn -dce -S | FileCheck %s
2
3 declare i32 @foo(i32 %a)
4
5 define i32 @slsr1(i32 %b, i32 %s) {
6 ; CHECK-LABEL: @slsr1(
7   ; v0 = foo(b * s);
8   %mul0 = mul i32 %b, %s
9 ; CHECK: mul i32
10 ; CHECK-NOT: mul i32
11   %v0 = call i32 @foo(i32 %mul0)
12
13   ; v1 = foo((b + 1) * s);
14   %b1 = add i32 %b, 1
15   %mul1 = mul i32 %b1, %s
16   %v1 = call i32 @foo(i32 %mul1)
17
18   ; v2 = foo((b + 2) * s);
19   %b2 = add i32 %b, 2
20   %mul2 = mul i32 %b2, %s
21   %v2 = call i32 @foo(i32 %mul2)
22
23   ; return v0 + v1 + v2;
24   %1 = add i32 %v0, %v1
25   %2 = add i32 %1, %v2
26   ret i32 %2
27 }
28
29 ; v0 = foo(a * b)
30 ; v1 = foo((a + 1) * b)
31 ; v2 = foo(a * (b + 1))
32 ; v3 = foo((a + 1) * (b + 1))
33 define i32 @slsr2(i32 %a, i32 %b) {
34 ; CHECK-LABEL: @slsr2(
35   %a1 = add i32 %a, 1
36   %b1 = add i32 %b, 1
37   %mul0 = mul i32 %a, %b
38 ; CHECK: mul i32
39 ; CHECK-NOT: mul i32
40   %mul1 = mul i32 %a1, %b
41   %mul2 = mul i32 %a, %b1
42   %mul3 = mul i32 %a1, %b1
43
44   %v0 = call i32 @foo(i32 %mul0)
45   %v1 = call i32 @foo(i32 %mul1)
46   %v2 = call i32 @foo(i32 %mul2)
47   %v3 = call i32 @foo(i32 %mul3)
48
49   %1 = add i32 %v0, %v1
50   %2 = add i32 %1, %v2
51   %3 = add i32 %2, %v3
52   ret i32 %3
53 }
54
55 ; The bump is a multiple of the stride.
56 ;
57 ; v0 = foo(b * s);
58 ; v1 = foo((b + 2) * s);
59 ; v2 = foo((b + 4) * s);
60 ; return v0 + v1 + v2;
61 ;
62 ; ==>
63 ;
64 ; mul0 = b * s;
65 ; v0 = foo(mul0);
66 ; bump = s * 2;
67 ; mul1 = mul0 + bump; // GVN ensures mul1 and mul2 use the same bump.
68 ; v1 = foo(mul1);
69 ; mul2 = mul1 + bump;
70 ; v2 = foo(mul2);
71 ; return v0 + v1 + v2;
72 define i32 @slsr3(i32 %b, i32 %s) {
73 ; CHECK-LABEL: @slsr3(
74   %mul0 = mul i32 %b, %s
75 ; CHECK: mul i32
76   %v0 = call i32 @foo(i32 %mul0)
77
78   %b1 = add i32 %b, 2
79   %mul1 = mul i32 %b1, %s
80 ; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = mul i32 %s, 2
81 ; CHECK: %mul1 = add i32 %mul0, [[BUMP]]
82   %v1 = call i32 @foo(i32 %mul1)
83
84   %b2 = add i32 %b, 4
85   %mul2 = mul i32 %b2, %s
86 ; CHECK: %mul2 = add i32 %mul1, [[BUMP]]
87   %v2 = call i32 @foo(i32 %mul2)
88
89   %1 = add i32 %v0, %v1
90   %2 = add i32 %1, %v2
91   ret i32 %2
92 }
93
94 ; Do not rewrite a candidate if its potential basis does not dominate it.
95 ; v0 = 0;
96 ; if (cond)
97 ;   v0 = foo(a * b);
98 ; v1 = foo((a + 1) * b);
99 ; return v0 + v1;
100 define i32 @not_dominate(i1 %cond, i32 %a, i32 %b) {
101 ; CHECK-LABEL: @not_dominate(
102 entry:
103   %a1 = add i32 %a, 1
104   br i1 %cond, label %then, label %merge
105
106 then:
107   %mul0 = mul i32 %a, %b
108 ; CHECK: %mul0 = mul i32 %a, %b
109   %v0 = call i32 @foo(i32 %mul0)
110   br label %merge
111
112 merge:
113   %v0.phi = phi i32 [ 0, %entry ], [ %mul0, %then ]
114   %mul1 = mul i32 %a1, %b
115 ; CHECK: %mul1 = mul i32 %a1, %b
116   %v1 = call i32 @foo(i32 %mul1)
117   %sum = add i32 %v0.phi, %v1
118   ret i32 %sum
119 }