1 ; RUN: opt < %s -slsr -gvn -dce -S | FileCheck %s
3 declare i32 @foo(i32 %a)
5 define i32 @slsr1(i32 %b, i32 %s) {
11 %v0 = call i32 @foo(i32 %mul0)
13 ; v1 = foo((b + 1) * s);
15 %mul1 = mul i32 %b1, %s
16 %v1 = call i32 @foo(i32 %mul1)
18 ; v2 = foo((b + 2) * s);
20 %mul2 = mul i32 %b2, %s
21 %v2 = call i32 @foo(i32 %mul2)
23 ; return v0 + v1 + v2;
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(
37 %mul0 = mul i32 %a, %b
40 %mul1 = mul i32 %a1, %b
41 %mul2 = mul i32 %a, %b1
42 %mul3 = mul i32 %a1, %b1
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)
55 ; The bump is a multiple of the stride.
58 ; v1 = foo((b + 2) * s);
59 ; v2 = foo((b + 4) * s);
60 ; return v0 + v1 + v2;
67 ; mul1 = mul0 + bump; // GVN ensures mul1 and mul2 use the same bump.
71 ; return v0 + v1 + v2;
72 define i32 @slsr3(i32 %b, i32 %s) {
73 ; CHECK-LABEL: @slsr3(
74 %mul0 = mul i32 %b, %s
76 %v0 = call i32 @foo(i32 %mul0)
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)
85 %mul2 = mul i32 %b2, %s
86 ; CHECK: %mul2 = add i32 %mul1, [[BUMP]]
87 %v2 = call i32 @foo(i32 %mul2)
94 ; Do not rewrite a candidate if its potential basis does not dominate it.
98 ; v1 = foo((a + 1) * b);
100 define i32 @not_dominate(i1 %cond, i32 %a, i32 %b) {
101 ; CHECK-LABEL: @not_dominate(
104 br i1 %cond, label %then, label %merge
107 %mul0 = mul i32 %a, %b
108 ; CHECK: %mul0 = mul i32 %a, %b
109 %v0 = call i32 @foo(i32 %mul0)
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