xref: /aosp_15_r20/external/llvm/test/Transforms/StraightLineStrengthReduce/slsr-gep.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-p:64:64:64-p1:32:32:32"
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker; foo(input[0]);
6*9880d681SAndroid Build Coastguard Worker; foo(input[s]);
7*9880d681SAndroid Build Coastguard Worker; foo(input[s * 2]);
8*9880d681SAndroid Build Coastguard Worker;   =>
9*9880d681SAndroid Build Coastguard Worker; p0 = &input[0];
10*9880d681SAndroid Build Coastguard Worker; foo(*p);
11*9880d681SAndroid Build Coastguard Worker; p1 = p0 + s;
12*9880d681SAndroid Build Coastguard Worker; foo(*p1);
13*9880d681SAndroid Build Coastguard Worker; p2 = p1 + s;
14*9880d681SAndroid Build Coastguard Worker; foo(*p2);
15*9880d681SAndroid Build Coastguard Workerdefine void @slsr_gep(i32* %input, i64 %s) {
16*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @slsr_gep(
17*9880d681SAndroid Build Coastguard Worker  ; v0 = input[0];
18*9880d681SAndroid Build Coastguard Worker  %p0 = getelementptr inbounds i32, i32* %input, i64 0
19*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p0)
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker  ; v1 = input[s];
22*9880d681SAndroid Build Coastguard Worker  %p1 = getelementptr inbounds i32, i32* %input, i64 %s
23*9880d681SAndroid Build Coastguard Worker; CHECK: %p1 = getelementptr inbounds i32, i32* %input, i64 %s
24*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p1)
25*9880d681SAndroid Build Coastguard Worker
26*9880d681SAndroid Build Coastguard Worker  ; v2 = input[s * 2];
27*9880d681SAndroid Build Coastguard Worker  %s2 = shl nsw i64 %s, 1
28*9880d681SAndroid Build Coastguard Worker  %p2 = getelementptr inbounds i32, i32* %input, i64 %s2
29*9880d681SAndroid Build Coastguard Worker; CHECK: %p2 = getelementptr inbounds i32, i32* %p1, i64 %s
30*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p2)
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker  ret void
33*9880d681SAndroid Build Coastguard Worker}
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker; foo(input[0]);
36*9880d681SAndroid Build Coastguard Worker; foo(input[(long)s]);
37*9880d681SAndroid Build Coastguard Worker; foo(input[(long)(s * 2)]);
38*9880d681SAndroid Build Coastguard Worker;   =>
39*9880d681SAndroid Build Coastguard Worker; p0 = &input[0];
40*9880d681SAndroid Build Coastguard Worker; foo(*p);
41*9880d681SAndroid Build Coastguard Worker; p1 = p0 + (long)s;
42*9880d681SAndroid Build Coastguard Worker; foo(*p1);
43*9880d681SAndroid Build Coastguard Worker; p2 = p1 + (long)s;
44*9880d681SAndroid Build Coastguard Worker; foo(*p2);
45*9880d681SAndroid Build Coastguard Workerdefine void @slsr_gep_sext(i32* %input, i32 %s) {
46*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @slsr_gep_sext(
47*9880d681SAndroid Build Coastguard Worker  ; v0 = input[0];
48*9880d681SAndroid Build Coastguard Worker  %p0 = getelementptr inbounds i32, i32* %input, i64 0
49*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p0)
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Worker  ; v1 = input[s];
52*9880d681SAndroid Build Coastguard Worker  %t = sext i32 %s to i64
53*9880d681SAndroid Build Coastguard Worker  %p1 = getelementptr inbounds i32, i32* %input, i64 %t
54*9880d681SAndroid Build Coastguard Worker; CHECK: %p1 = getelementptr inbounds i32, i32* %input, i64 %t
55*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p1)
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker  ; v2 = input[s * 2];
58*9880d681SAndroid Build Coastguard Worker  %s2 = shl nsw i32 %s, 1
59*9880d681SAndroid Build Coastguard Worker  %t2 = sext i32 %s2 to i64
60*9880d681SAndroid Build Coastguard Worker  %p2 = getelementptr inbounds i32, i32* %input, i64 %t2
61*9880d681SAndroid Build Coastguard Worker; CHECK: %p2 = getelementptr inbounds i32, i32* %p1, i64 %t
62*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p2)
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard Worker  ret void
65*9880d681SAndroid Build Coastguard Worker}
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker; int input[10][5];
68*9880d681SAndroid Build Coastguard Worker; foo(input[s][t]);
69*9880d681SAndroid Build Coastguard Worker; foo(input[s * 2][t]);
70*9880d681SAndroid Build Coastguard Worker; foo(input[s * 3][t]);
71*9880d681SAndroid Build Coastguard Worker;   =>
72*9880d681SAndroid Build Coastguard Worker; p0 = &input[s][t];
73*9880d681SAndroid Build Coastguard Worker; foo(*p0);
74*9880d681SAndroid Build Coastguard Worker; p1 = p0 + 5s;
75*9880d681SAndroid Build Coastguard Worker; foo(*p1);
76*9880d681SAndroid Build Coastguard Worker; p2 = p1 + 5s;
77*9880d681SAndroid Build Coastguard Worker; foo(*p2);
78*9880d681SAndroid Build Coastguard Workerdefine void @slsr_gep_2d([10 x [5 x i32]]* %input, i64 %s, i64 %t) {
79*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @slsr_gep_2d(
80*9880d681SAndroid Build Coastguard Worker  ; v0 = input[s][t];
81*9880d681SAndroid Build Coastguard Worker  %p0 = getelementptr inbounds [10 x [5 x i32]], [10 x [5 x i32]]* %input, i64 0, i64 %s, i64 %t
82*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p0)
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker  ; v1 = input[s * 2][t];
85*9880d681SAndroid Build Coastguard Worker  %s2 = shl nsw i64 %s, 1
86*9880d681SAndroid Build Coastguard Worker; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = mul i64 %s, 5
87*9880d681SAndroid Build Coastguard Worker  %p1 = getelementptr inbounds [10 x [5 x i32]], [10 x [5 x i32]]* %input, i64 0, i64 %s2, i64 %t
88*9880d681SAndroid Build Coastguard Worker; CHECK: %p1 = getelementptr inbounds i32, i32* %p0, i64 [[BUMP]]
89*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p1)
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker  ; v3 = input[s * 3][t];
92*9880d681SAndroid Build Coastguard Worker  %s3 = mul nsw i64 %s, 3
93*9880d681SAndroid Build Coastguard Worker  %p2 = getelementptr inbounds [10 x [5 x i32]], [10 x [5 x i32]]* %input, i64 0, i64 %s3, i64 %t
94*9880d681SAndroid Build Coastguard Worker; CHECK: %p2 = getelementptr inbounds i32, i32* %p1, i64 [[BUMP]]
95*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p2)
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker  ret void
98*9880d681SAndroid Build Coastguard Worker}
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Worker%struct.S = type <{ i64, i32 }>
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker; In this case, the bump
103*9880d681SAndroid Build Coastguard Worker;     = (char *)&input[s * 2][t].f1 - (char *)&input[s][t].f1
104*9880d681SAndroid Build Coastguard Worker;     = 60 * s
105*9880d681SAndroid Build Coastguard Worker; which may not be divisible by typeof(input[s][t].f1) = 8. Therefore, we
106*9880d681SAndroid Build Coastguard Worker; rewrite the candidates using byte offset instead of index offset as in
107*9880d681SAndroid Build Coastguard Worker; @slsr_gep_2d.
108*9880d681SAndroid Build Coastguard Workerdefine void @slsr_gep_uglygep([10 x [5 x %struct.S]]* %input, i64 %s, i64 %t) {
109*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @slsr_gep_uglygep(
110*9880d681SAndroid Build Coastguard Worker  ; v0 = input[s][t].f1;
111*9880d681SAndroid Build Coastguard Worker  %p0 = getelementptr inbounds [10 x [5 x %struct.S]], [10 x [5 x %struct.S]]* %input, i64 0, i64 %s, i64 %t, i32 0
112*9880d681SAndroid Build Coastguard Worker  call void @bar(i64* %p0)
113*9880d681SAndroid Build Coastguard Worker
114*9880d681SAndroid Build Coastguard Worker  ; v1 = input[s * 2][t].f1;
115*9880d681SAndroid Build Coastguard Worker  %s2 = shl nsw i64 %s, 1
116*9880d681SAndroid Build Coastguard Worker; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = mul i64 %s, 60
117*9880d681SAndroid Build Coastguard Worker  %p1 = getelementptr inbounds [10 x [5 x %struct.S]], [10 x [5 x %struct.S]]* %input, i64 0, i64 %s2, i64 %t, i32 0
118*9880d681SAndroid Build Coastguard Worker; CHECK: getelementptr inbounds i8, i8* %{{[0-9]+}}, i64 [[BUMP]]
119*9880d681SAndroid Build Coastguard Worker  call void @bar(i64* %p1)
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Worker  ; v2 = input[s * 3][t].f1;
122*9880d681SAndroid Build Coastguard Worker  %s3 = mul nsw i64 %s, 3
123*9880d681SAndroid Build Coastguard Worker  %p2 = getelementptr inbounds [10 x [5 x %struct.S]], [10 x [5 x %struct.S]]* %input, i64 0, i64 %s3, i64 %t, i32 0
124*9880d681SAndroid Build Coastguard Worker; CHECK: getelementptr inbounds i8, i8* %{{[0-9]+}}, i64 [[BUMP]]
125*9880d681SAndroid Build Coastguard Worker  call void @bar(i64* %p2)
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker  ret void
128*9880d681SAndroid Build Coastguard Worker}
129*9880d681SAndroid Build Coastguard Worker
130*9880d681SAndroid Build Coastguard Workerdefine void @slsr_out_of_bounds_gep(i32* %input, i32 %s) {
131*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @slsr_out_of_bounds_gep(
132*9880d681SAndroid Build Coastguard Worker  ; v0 = input[0];
133*9880d681SAndroid Build Coastguard Worker  %p0 = getelementptr i32, i32* %input, i64 0
134*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p0)
135*9880d681SAndroid Build Coastguard Worker
136*9880d681SAndroid Build Coastguard Worker  ; v1 = input[(long)s];
137*9880d681SAndroid Build Coastguard Worker  %t = sext i32 %s to i64
138*9880d681SAndroid Build Coastguard Worker  %p1 = getelementptr i32, i32* %input, i64 %t
139*9880d681SAndroid Build Coastguard Worker; CHECK: %p1 = getelementptr i32, i32* %input, i64 %t
140*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p1)
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker  ; v2 = input[(long)(s * 2)];
143*9880d681SAndroid Build Coastguard Worker  %s2 = shl nsw i32 %s, 1
144*9880d681SAndroid Build Coastguard Worker  %t2 = sext i32 %s2 to i64
145*9880d681SAndroid Build Coastguard Worker  %p2 = getelementptr i32, i32* %input, i64 %t2
146*9880d681SAndroid Build Coastguard Worker; CHECK: %p2 = getelementptr i32, i32* %p1, i64 %t
147*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p2)
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker  ret void
150*9880d681SAndroid Build Coastguard Worker}
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Workerdefine void @slsr_gep_128bit_index(i32* %input, i128 %s) {
153*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @slsr_gep_128bit_index(
154*9880d681SAndroid Build Coastguard Worker  ; p0 = &input[0]
155*9880d681SAndroid Build Coastguard Worker  %p0 = getelementptr inbounds i32, i32* %input, i128 0
156*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p0)
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker  ; p1 = &input[s << 125]
159*9880d681SAndroid Build Coastguard Worker  %s125 = shl nsw i128 %s, 125
160*9880d681SAndroid Build Coastguard Worker  %p1 = getelementptr inbounds i32, i32* %input, i128 %s125
161*9880d681SAndroid Build Coastguard Worker; CHECK: %p1 = getelementptr inbounds i32, i32* %input, i128 %s125
162*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p1)
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker  ; p2 = &input[s << 126]
165*9880d681SAndroid Build Coastguard Worker  %s126 = shl nsw i128 %s, 126
166*9880d681SAndroid Build Coastguard Worker  %p2 = getelementptr inbounds i32, i32* %input, i128 %s126
167*9880d681SAndroid Build Coastguard Worker; CHECK: %p2 = getelementptr inbounds i32, i32* %input, i128 %s126
168*9880d681SAndroid Build Coastguard Worker  call void @foo(i32* %p2)
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard Worker  ret void
171*9880d681SAndroid Build Coastguard Worker}
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Workerdefine void @slsr_gep_32bit_pointer(i32 addrspace(1)* %input, i64 %s) {
174*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @slsr_gep_32bit_pointer(
175*9880d681SAndroid Build Coastguard Worker  ; p1 = &input[s]
176*9880d681SAndroid Build Coastguard Worker  %p1 = getelementptr inbounds i32, i32 addrspace(1)* %input, i64 %s
177*9880d681SAndroid Build Coastguard Worker  call void @baz(i32 addrspace(1)* %p1)
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker  ; p2 = &input[s * 2]
180*9880d681SAndroid Build Coastguard Worker  %s2 = mul nsw i64 %s, 2
181*9880d681SAndroid Build Coastguard Worker  %p2 = getelementptr inbounds i32, i32 addrspace(1)* %input, i64 %s2
182*9880d681SAndroid Build Coastguard Worker  ; %s2 is wider than the pointer size of addrspace(1), so do not factor it.
183*9880d681SAndroid Build Coastguard Worker; CHECK: %p2 = getelementptr inbounds i32, i32 addrspace(1)* %input, i64 %s2
184*9880d681SAndroid Build Coastguard Worker  call void @baz(i32 addrspace(1)* %p2)
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker  ret void
187*9880d681SAndroid Build Coastguard Worker}
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Workerdeclare void @foo(i32*)
190*9880d681SAndroid Build Coastguard Workerdeclare void @bar(i64*)
191*9880d681SAndroid Build Coastguard Workerdeclare void @baz(i32 addrspace(1)*)
192