xref: /llvm-project/llvm/test/Transforms/InstCombine/memrchr-5.ll (revision 90ba33099cbb17e7c159e9ebc5a512037db99d6d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; Verify that calls to memrchr with arrays of elements larger than char
3; are folded correctly.
4; RUN: opt < %s -passes=instcombine -S -data-layout="E" | FileCheck %s --check-prefixes=BE
5; RUN: opt < %s -passes=instcombine -S -data-layout="e" | FileCheck %s --check-prefixes=LE
6
7declare ptr @memrchr(ptr, i32, i64)
8
9; BE representation: { 'a', 'b', 'c', 'd', 'e', ..., 'p', 'a', 'b', 'c', 'd' }
10; LE representation: { 'd', 'c', 'b', 'a', 'h', ..., 'm', 'd', 'c', 'b', 'a' }
11@a = constant [5 x i32] [i32 1633837924, i32 1701209960, i32 1768581996, i32 1835954032, i32 1633837924]
12
13
14; Fold memrchr(a, C, 16) for C in ['a', 'd'] U ['o', 'q'].
15
16define void @fold_memrchr_a_16(ptr %pcmp) {
17; BE-LABEL: @fold_memrchr_a_16(
18; BE-NEXT:    store i64 0, ptr [[PCMP:%.*]], align 4
19; BE-NEXT:    [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8
20; BE-NEXT:    store i64 1, ptr [[PSTOR1]], align 4
21; BE-NEXT:    [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16
22; BE-NEXT:    store i64 2, ptr [[PSTOR2]], align 4
23; BE-NEXT:    [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24
24; BE-NEXT:    store i64 3, ptr [[PSTOR3]], align 4
25; BE-NEXT:    [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32
26; BE-NEXT:    store i64 13, ptr [[PSTOR4]], align 4
27; BE-NEXT:    [[PSTOR6:%.*]] = getelementptr i8, ptr [[PCMP]], i64 48
28; BE-NEXT:    store i64 14, ptr [[PSTOR6]], align 4
29; BE-NEXT:    [[PSTOR7:%.*]] = getelementptr i8, ptr [[PCMP]], i64 56
30; BE-NEXT:    store i64 15, ptr [[PSTOR7]], align 4
31; BE-NEXT:    [[PSTOR8:%.*]] = getelementptr i8, ptr [[PCMP]], i64 64
32; BE-NEXT:    store i64 0, ptr [[PSTOR8]], align 4
33; BE-NEXT:    ret void
34;
35; LE-LABEL: @fold_memrchr_a_16(
36; LE-NEXT:    store i64 3, ptr [[PCMP:%.*]], align 4
37; LE-NEXT:    [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8
38; LE-NEXT:    store i64 2, ptr [[PSTOR1]], align 4
39; LE-NEXT:    [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16
40; LE-NEXT:    store i64 1, ptr [[PSTOR2]], align 4
41; LE-NEXT:    [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24
42; LE-NEXT:    store i64 0, ptr [[PSTOR3]], align 4
43; LE-NEXT:    [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32
44; LE-NEXT:    store i64 14, ptr [[PSTOR4]], align 4
45; LE-NEXT:    [[PSTOR6:%.*]] = getelementptr i8, ptr [[PCMP]], i64 48
46; LE-NEXT:    store i64 13, ptr [[PSTOR6]], align 4
47; LE-NEXT:    [[PSTOR7:%.*]] = getelementptr i8, ptr [[PCMP]], i64 56
48; LE-NEXT:    store i64 12, ptr [[PSTOR7]], align 4
49; LE-NEXT:    [[PSTOR8:%.*]] = getelementptr i8, ptr [[PCMP]], i64 64
50; LE-NEXT:    store i64 0, ptr [[PSTOR8]], align 4
51; LE-NEXT:    ret void
52;
53  %ip0 = ptrtoint ptr @a to i64
54
55; Fold memrchr(a, 'a', 16) - a to 0 (3 in LE).
56
57  %pa = call ptr @memrchr(ptr @a, i32 97, i64 16)
58  %ipa = ptrtoint ptr %pa to i64
59  %offa = sub i64 %ipa, %ip0
60  store i64 %offa, ptr %pcmp
61
62; Fold memrchr(a, 'b', 16) - a to 1 (2 in LE)
63
64  %pb = call ptr @memrchr(ptr @a, i32 98, i64 16)
65  %ipb = ptrtoint ptr %pb to i64
66  %offb = sub i64 %ipb, %ip0
67  %pstor1 = getelementptr i64, ptr %pcmp, i64 1
68  store i64 %offb, ptr %pstor1
69
70; Fold memrchr(a, 'c', 16) - a to 2 (1 in LE)
71
72  %pc = call ptr @memrchr(ptr @a, i32 99, i64 16)
73  %ipc = ptrtoint ptr %pc to i64
74  %offc = sub i64 %ipc, %ip0
75  %pstor2 = getelementptr i64, ptr %pcmp, i64 2
76  store i64 %offc, ptr %pstor2
77
78; Fold memrchr(a, 'd', 16) - a to 3 (0 in LE)
79
80  %pd = call ptr @memrchr(ptr @a, i32 100, i64 16)
81  %ipd = ptrtoint ptr %pd to i64
82  %offd = sub i64 %ipd, %ip0
83  %pstor3 = getelementptr i64, ptr %pcmp, i64 3
84  store i64 %offd, ptr %pstor3
85
86; Fold memrchr(a, 'n', 16) - a to 13 (14 in LE)
87
88  %pn = call ptr @memrchr(ptr @a, i32 110, i64 16)
89  %ipn = ptrtoint ptr %pn to i64
90  %offn = sub i64 %ipn, %ip0
91  %pstor4 = getelementptr i64, ptr %pcmp, i64 4
92  store i64 %offn, ptr %pstor4
93
94; Fold memrchr(a, 'o', 16) - a to 14 (13 in LE)
95
96  %po = call ptr @memrchr(ptr @a, i32 111, i64 16)
97  %ipo = ptrtoint ptr %po to i64
98  %offo = sub i64 %ipo, %ip0
99  %pstor6 = getelementptr i64, ptr %pcmp, i64 6
100  store i64 %offo, ptr %pstor6
101
102; Fold memrchr(a, 'p', 16) - a to 15 (12 in LE)
103
104  %pp = call ptr @memrchr(ptr @a, i32 112, i64 16)
105  %ipp = ptrtoint ptr %pp to i64
106  %offp = sub i64 %ipp, %ip0
107  %pstor7 = getelementptr i64, ptr %pcmp, i64 7
108  store i64 %offp, ptr %pstor7
109
110; Fold memrchr(a, 'q', 16) to null in both BE and LE.
111
112  %pq = call ptr @memrchr(ptr @a, i32 113, i64 16)
113  %ipq = ptrtoint ptr %pq to i64
114  %pstor8 = getelementptr i64, ptr %pcmp, i64 8
115  store i64 %ipq, ptr %pstor8
116
117  ret void
118}
119
120
121; Fold memrchr(a + 1, C, 12) for C in ['e', 'h'] U ['a', 'd'].
122
123define void @fold_memrchr_a_p1_16(ptr %pcmp) {
124; BE-LABEL: @fold_memrchr_a_p1_16(
125; BE-NEXT:    store i64 0, ptr [[PCMP:%.*]], align 4
126; BE-NEXT:    [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8
127; BE-NEXT:    store i64 1, ptr [[PSTOR1]], align 4
128; BE-NEXT:    [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16
129; BE-NEXT:    store i64 2, ptr [[PSTOR2]], align 4
130; BE-NEXT:    [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24
131; BE-NEXT:    store i64 3, ptr [[PSTOR3]], align 4
132; BE-NEXT:    [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32
133; BE-NEXT:    store i64 0, ptr [[PSTOR4]], align 4
134; BE-NEXT:    [[PSTOR5:%.*]] = getelementptr i8, ptr [[PCMP]], i64 40
135; BE-NEXT:    store i64 0, ptr [[PSTOR5]], align 4
136; BE-NEXT:    ret void
137;
138; LE-LABEL: @fold_memrchr_a_p1_16(
139; LE-NEXT:    store i64 3, ptr [[PCMP:%.*]], align 4
140; LE-NEXT:    [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8
141; LE-NEXT:    store i64 2, ptr [[PSTOR1]], align 4
142; LE-NEXT:    [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16
143; LE-NEXT:    store i64 1, ptr [[PSTOR2]], align 4
144; LE-NEXT:    [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24
145; LE-NEXT:    store i64 0, ptr [[PSTOR3]], align 4
146; LE-NEXT:    [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32
147; LE-NEXT:    store i64 0, ptr [[PSTOR4]], align 4
148; LE-NEXT:    [[PSTOR5:%.*]] = getelementptr i8, ptr [[PCMP]], i64 40
149; LE-NEXT:    store i64 0, ptr [[PSTOR5]], align 4
150; LE-NEXT:    ret void
151;
152  %p0 = getelementptr [5 x i32], ptr @a, i64 0, i64 1
153  %ip0 = ptrtoint ptr %p0 to i64
154
155; Fold memrchr(a + 1, 'e', 12) - a to 0 (3 in LE).
156
157  %pe = call ptr @memrchr(ptr %p0, i32 101, i64 12)
158  %ipe = ptrtoint ptr %pe to i64
159  %offe = sub i64 %ipe, %ip0
160  store i64 %offe, ptr %pcmp
161
162; Fold memrchr(a + 1, 'f', 12) - a to 1 (2 in LE).
163
164  %pf = call ptr @memrchr(ptr %p0, i32 102, i64 12)
165  %ipf = ptrtoint ptr %pf to i64
166  %offf = sub i64 %ipf, %ip0
167  %pstor1 = getelementptr i64, ptr %pcmp, i64 1
168  store i64 %offf, ptr %pstor1
169
170; Fold memrchr(a + 1, 'g', 12) - a to 2 (1 in LE).
171
172  %pg = call ptr @memrchr(ptr %p0, i32 103, i64 12)
173  %ipg = ptrtoint ptr %pg to i64
174  %offg = sub i64 %ipg, %ip0
175  %pstor2 = getelementptr i64, ptr %pcmp, i64 2
176  store i64 %offg, ptr %pstor2
177
178; Fold memrchr(a + 1, 'h', 12) - a to 3 (0 in LE).
179
180  %ph = call ptr @memrchr(ptr %p0, i32 104, i64 12)
181  %iph = ptrtoint ptr %ph to i64
182  %offh = sub i64 %iph, %ip0
183  %pstor3 = getelementptr i64, ptr %pcmp, i64 3
184  store i64 %offh, ptr %pstor3
185
186; Fold memrchr(a + 1, 'a', 12) to null in both BE and LE.
187
188  %pa = call ptr @memrchr(ptr %p0, i32 97, i64 12)
189  %ipa = ptrtoint ptr %pa to i64
190  %pstor4 = getelementptr i64, ptr %pcmp, i64 4
191  store i64 %ipa, ptr %pstor4
192
193; Fold memrchr(a + 1, 'd', 12) to null in both BE and LE.
194
195  %pd = call ptr @memrchr(ptr %p0, i32 100, i64 12)
196  %ipd = ptrtoint ptr %pd to i64
197  %pstor5 = getelementptr i64, ptr %pcmp, i64 5
198  store i64 %ipd, ptr %pstor5
199
200  ret void
201}
202
203
204; Fold memrchr(a, C, 20) for C in ['a', 'e'].
205
206define void @fold_memrchr_a_20(ptr %pcmp) {
207; BE-LABEL: @fold_memrchr_a_20(
208; BE-NEXT:    store i64 16, ptr [[PCMP:%.*]], align 4
209; BE-NEXT:    [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8
210; BE-NEXT:    store i64 17, ptr [[PSTOR1]], align 4
211; BE-NEXT:    [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16
212; BE-NEXT:    store i64 18, ptr [[PSTOR2]], align 4
213; BE-NEXT:    [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24
214; BE-NEXT:    store i64 19, ptr [[PSTOR3]], align 4
215; BE-NEXT:    [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32
216; BE-NEXT:    store i64 4, ptr [[PSTOR4]], align 4
217; BE-NEXT:    ret void
218;
219; LE-LABEL: @fold_memrchr_a_20(
220; LE-NEXT:    store i64 19, ptr [[PCMP:%.*]], align 4
221; LE-NEXT:    [[PSTOR1:%.*]] = getelementptr i8, ptr [[PCMP]], i64 8
222; LE-NEXT:    store i64 18, ptr [[PSTOR1]], align 4
223; LE-NEXT:    [[PSTOR2:%.*]] = getelementptr i8, ptr [[PCMP]], i64 16
224; LE-NEXT:    store i64 17, ptr [[PSTOR2]], align 4
225; LE-NEXT:    [[PSTOR3:%.*]] = getelementptr i8, ptr [[PCMP]], i64 24
226; LE-NEXT:    store i64 16, ptr [[PSTOR3]], align 4
227; LE-NEXT:    [[PSTOR4:%.*]] = getelementptr i8, ptr [[PCMP]], i64 32
228; LE-NEXT:    store i64 7, ptr [[PSTOR4]], align 4
229; LE-NEXT:    ret void
230;
231  %ip0 = ptrtoint ptr @a to i64
232
233; Fold memrchr(a, 'a', 20) - a to 16 (19 in LE).
234
235  %pa = call ptr @memrchr(ptr @a, i32 97, i64 20)
236  %ipa = ptrtoint ptr %pa to i64
237  %offa = sub i64 %ipa, %ip0
238  store i64 %offa, ptr %pcmp
239
240; Fold memrchr(a, 'b', 16) - a to 17 (18 in LE)
241
242  %pb = call ptr @memrchr(ptr @a, i32 98, i64 20)
243  %ipb = ptrtoint ptr %pb to i64
244  %offb = sub i64 %ipb, %ip0
245  %pstor1 = getelementptr i64, ptr %pcmp, i64 1
246  store i64 %offb, ptr %pstor1
247
248; Fold memrchr(a, 'c', 16) - a to 18 (17 in LE)
249
250  %pc = call ptr @memrchr(ptr @a, i32 99, i64 20)
251  %ipc = ptrtoint ptr %pc to i64
252  %offc = sub i64 %ipc, %ip0
253  %pstor2 = getelementptr i64, ptr %pcmp, i64 2
254  store i64 %offc, ptr %pstor2
255
256; Fold memrchr(a, 'd', 16) - a to 19 (16 in LE)
257
258  %pd = call ptr @memrchr(ptr @a, i32 100, i64 20)
259  %ipd = ptrtoint ptr %pd to i64
260  %offd = sub i64 %ipd, %ip0
261  %pstor3 = getelementptr i64, ptr %pcmp, i64 3
262  store i64 %offd, ptr %pstor3
263
264; Fold memrchr(a, 'e', 16) - a to 4 (7 in LE)
265
266  %pe = call ptr @memrchr(ptr @a, i32 101, i64 20)
267  %ipe = ptrtoint ptr %pe to i64
268  %offe = sub i64 %ipe, %ip0
269  %pstor4 = getelementptr i64, ptr %pcmp, i64 4
270  store i64 %offe, ptr %pstor4
271
272  ret void
273}
274