xref: /aosp_15_r20/external/llvm/test/Transforms/StraightLineStrengthReduce/slsr-mul.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -slsr -gvn -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Workerdefine void @slsr1(i32 %b, i32 %s) {
6*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @slsr1(
7*9880d681SAndroid Build Coastguard Worker  ; foo(b * s);
8*9880d681SAndroid Build Coastguard Worker  %mul0 = mul i32 %b, %s
9*9880d681SAndroid Build Coastguard Worker; CHECK: mul i32
10*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mul i32
11*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul0)
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker  ; foo((b + 1) * s);
14*9880d681SAndroid Build Coastguard Worker  %b1 = add i32 %b, 1
15*9880d681SAndroid Build Coastguard Worker  %mul1 = mul i32 %b1, %s
16*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul1)
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker  ; foo((b + 2) * s);
19*9880d681SAndroid Build Coastguard Worker  %b2 = add i32 %b, 2
20*9880d681SAndroid Build Coastguard Worker  %mul2 = mul i32 %b2, %s
21*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul2)
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker  ret void
24*9880d681SAndroid Build Coastguard Worker}
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Workerdefine void @non_canonicalized(i32 %b, i32 %s) {
27*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @non_canonicalized(
28*9880d681SAndroid Build Coastguard Worker  ; foo(b * s);
29*9880d681SAndroid Build Coastguard Worker  %mul0 = mul i32 %b, %s
30*9880d681SAndroid Build Coastguard Worker; CHECK: mul i32
31*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mul i32
32*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul0)
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker  ; foo((1 + b) * s);
35*9880d681SAndroid Build Coastguard Worker  %b1 = add i32 1, %b
36*9880d681SAndroid Build Coastguard Worker  %mul1 = mul i32 %b1, %s
37*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul1)
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker  ; foo((2 + b) * s);
40*9880d681SAndroid Build Coastguard Worker  %b2 = add i32 2, %b
41*9880d681SAndroid Build Coastguard Worker  %mul2 = mul i32 %b2, %s
42*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul2)
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker  ret void
45*9880d681SAndroid Build Coastguard Worker}
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Workerdefine void @or(i32 %a, i32 %s) {
48*9880d681SAndroid Build Coastguard Worker  %b = shl i32 %a, 1
49*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @or(
50*9880d681SAndroid Build Coastguard Worker  ; foo(b * s);
51*9880d681SAndroid Build Coastguard Worker  %mul0 = mul i32 %b, %s
52*9880d681SAndroid Build Coastguard Worker; CHECK: [[base:[^ ]+]] = mul i32
53*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul0)
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker  ; foo((b | 1) * s);
56*9880d681SAndroid Build Coastguard Worker  %b1 = or i32 %b, 1
57*9880d681SAndroid Build Coastguard Worker  %mul1 = mul i32 %b1, %s
58*9880d681SAndroid Build Coastguard Worker; CHECK: add i32 [[base]], %s
59*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul1)
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker  ; foo((b | 2) * s);
62*9880d681SAndroid Build Coastguard Worker  %b2 = or i32 %b, 2
63*9880d681SAndroid Build Coastguard Worker  %mul2 = mul i32 %b2, %s
64*9880d681SAndroid Build Coastguard Worker; CHECK: mul i32 %b2, %s
65*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul2)
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker  ret void
68*9880d681SAndroid Build Coastguard Worker}
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker; foo(a * b)
71*9880d681SAndroid Build Coastguard Worker; foo((a + 1) * b)
72*9880d681SAndroid Build Coastguard Worker; foo(a * (b + 1))
73*9880d681SAndroid Build Coastguard Worker; foo((a + 1) * (b + 1))
74*9880d681SAndroid Build Coastguard Workerdefine void @slsr2(i32 %a, i32 %b) {
75*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @slsr2(
76*9880d681SAndroid Build Coastguard Worker  %a1 = add i32 %a, 1
77*9880d681SAndroid Build Coastguard Worker  %b1 = add i32 %b, 1
78*9880d681SAndroid Build Coastguard Worker  %mul0 = mul i32 %a, %b
79*9880d681SAndroid Build Coastguard Worker; CHECK: mul i32
80*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: mul i32
81*9880d681SAndroid Build Coastguard Worker  %mul1 = mul i32 %a1, %b
82*9880d681SAndroid Build Coastguard Worker  %mul2 = mul i32 %a, %b1
83*9880d681SAndroid Build Coastguard Worker  %mul3 = mul i32 %a1, %b1
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul0)
86*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul1)
87*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul2)
88*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul3)
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker  ret void
91*9880d681SAndroid Build Coastguard Worker}
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker; The bump is a multiple of the stride.
94*9880d681SAndroid Build Coastguard Worker;
95*9880d681SAndroid Build Coastguard Worker; foo(b * s);
96*9880d681SAndroid Build Coastguard Worker; foo((b + 2) * s);
97*9880d681SAndroid Build Coastguard Worker; foo((b + 4) * s);
98*9880d681SAndroid Build Coastguard Worker;   =>
99*9880d681SAndroid Build Coastguard Worker; mul0 = b * s;
100*9880d681SAndroid Build Coastguard Worker; bump = s * 2;
101*9880d681SAndroid Build Coastguard Worker; mul1 = mul0 + bump; // GVN ensures mul1 and mul2 use the same bump.
102*9880d681SAndroid Build Coastguard Worker; mul2 = mul1 + bump;
103*9880d681SAndroid Build Coastguard Workerdefine void @slsr3(i32 %b, i32 %s) {
104*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @slsr3(
105*9880d681SAndroid Build Coastguard Worker  %mul0 = mul i32 %b, %s
106*9880d681SAndroid Build Coastguard Worker; CHECK: mul i32
107*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul0)
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker  %b1 = add i32 %b, 2
110*9880d681SAndroid Build Coastguard Worker  %mul1 = mul i32 %b1, %s
111*9880d681SAndroid Build Coastguard Worker; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = shl i32 %s, 1
112*9880d681SAndroid Build Coastguard Worker; CHECK: %mul1 = add i32 %mul0, [[BUMP]]
113*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul1)
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker  %b2 = add i32 %b, 4
116*9880d681SAndroid Build Coastguard Worker  %mul2 = mul i32 %b2, %s
117*9880d681SAndroid Build Coastguard Worker; CHECK: %mul2 = add i32 %mul1, [[BUMP]]
118*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul2)
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Worker  ret void
121*9880d681SAndroid Build Coastguard Worker}
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker; Do not rewrite a candidate if its potential basis does not dominate it.
124*9880d681SAndroid Build Coastguard Worker;
125*9880d681SAndroid Build Coastguard Worker; if (cond)
126*9880d681SAndroid Build Coastguard Worker;   foo(a * b);
127*9880d681SAndroid Build Coastguard Worker; foo((a + 1) * b);
128*9880d681SAndroid Build Coastguard Workerdefine void @not_dominate(i1 %cond, i32 %a, i32 %b) {
129*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @not_dominate(
130*9880d681SAndroid Build Coastguard Workerentry:
131*9880d681SAndroid Build Coastguard Worker  %a1 = add i32 %a, 1
132*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %then, label %merge
133*9880d681SAndroid Build Coastguard Worker
134*9880d681SAndroid Build Coastguard Workerthen:
135*9880d681SAndroid Build Coastguard Worker  %mul0 = mul i32 %a, %b
136*9880d681SAndroid Build Coastguard Worker; CHECK: %mul0 = mul i32 %a, %b
137*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul0)
138*9880d681SAndroid Build Coastguard Worker  br label %merge
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Workermerge:
141*9880d681SAndroid Build Coastguard Worker  %mul1 = mul i32 %a1, %b
142*9880d681SAndroid Build Coastguard Worker; CHECK: %mul1 = mul i32 %a1, %b
143*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 %mul1)
144*9880d681SAndroid Build Coastguard Worker  ret void
145*9880d681SAndroid Build Coastguard Worker}
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Workerdeclare void @foo(i32)
148