xref: /llvm-project/llvm/test/Transforms/CodeGenPrepare/X86/sink-addrmode-base.ll (revision 2d69827c5c754f0eca98e497ecf0e52ed54b4fd3)
1; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -disable-complex-addr-modes=false -addr-sink-new-phis=true -addr-sink-new-select=true -disable-cgp-delete-phis  %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-YES
2; RUN: opt -S -passes='require<profile-summary>,function(codegenprepare)' -disable-complex-addr-modes=false -addr-sink-new-phis=false -addr-sink-new-select=true -disable-cgp-delete-phis %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO
3target datalayout =
4"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
5target triple = "x86_64-unknown-linux-gnu"
6
7; Can we sink for different base if there is no phi for base?
8define i32 @test1(i1 %cond, ptr %b1, ptr %b2) {
9; CHECK-LABEL: @test1
10entry:
11  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
12  br i1 %cond, label %if.then, label %fallthrough
13
14if.then:
15  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
16  br label %fallthrough
17
18fallthrough:
19; CHECK-YES: sunk_phi
20; CHECK-NO-LABEL: fallthrough:
21; CHECK-NO: phi
22; CHECK-NO-NEXT: load
23  %c = phi ptr [%a1, %entry], [%a2, %if.then]
24  %v = load i32, ptr %c, align 4
25  ret i32 %v
26}
27
28; Can we sink for different base if there is phi for base?
29define i32 @test2(i1 %cond, ptr %b1, ptr %b2) {
30; CHECK-LABEL: @test2
31entry:
32  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
33  br i1 %cond, label %if.then, label %fallthrough
34
35if.then:
36  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
37  br label %fallthrough
38
39fallthrough:
40; CHECK: getelementptr inbounds i8, {{.+}} 40
41  %b = phi ptr [%b1, %entry], [%b2, %if.then]
42  %c = phi ptr [%a1, %entry], [%a2, %if.then]
43  %v = load i32, ptr %c, align 4
44  ret i32 %v
45}
46
47; Can we sink for different base if there is phi for base but not valid one?
48define i32 @test3(i1 %cond, ptr %b1, ptr %b2) {
49; CHECK-LABEL: @test3
50entry:
51  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
52  br i1 %cond, label %if.then, label %fallthrough
53
54if.then:
55  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
56  br label %fallthrough
57
58fallthrough:
59; CHECK-YES: sunk_phi
60; CHECK-NO-LABEL: fallthrough:
61; CHECK-NO: phi
62; CHECK-NO: phi
63; CHECK-NO-NEXT: load
64  %b = phi ptr [%b2, %entry], [%b1, %if.then]
65  %c = phi ptr [%a1, %entry], [%a2, %if.then]
66  %v = load i32, ptr %c, align 4
67  ret i32 %v
68}
69
70; Can we sink for different base if both addresses are in the same block?
71define i32 @test4(i1 %cond, ptr %b1, ptr %b2) {
72; CHECK-LABEL: @test4
73entry:
74  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
75  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
76  br i1 %cond, label %if.then, label %fallthrough
77
78if.then:
79  br label %fallthrough
80
81fallthrough:
82; CHECK-YES: sunk_phi
83; CHECK-NO-LABEL: fallthrough:
84; CHECK-NO: phi
85; CHECK-NO-NEXT: load
86  %c = phi ptr [%a1, %entry], [%a2, %if.then]
87  %v = load i32, ptr %c, align 4
88  ret i32 %v
89}
90
91; Can we sink for different base if there is phi for base?
92; Both addresses are in the same block.
93define i32 @test5(i1 %cond, ptr %b1, ptr %b2) {
94; CHECK-LABEL: @test5
95entry:
96  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
97  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
98  br i1 %cond, label %if.then, label %fallthrough
99
100if.then:
101  br label %fallthrough
102
103fallthrough:
104; CHECK: getelementptr inbounds i8, {{.+}} 40
105  %b = phi ptr [%b1, %entry], [%b2, %if.then]
106  %c = phi ptr [%a1, %entry], [%a2, %if.then]
107  %v = load i32, ptr %c, align 4
108  ret i32 %v
109}
110
111; Can we sink for different base if there is phi for base but not valid one?
112; Both addresses are in the same block.
113define i32 @test6(i1 %cond, ptr %b1, ptr %b2) {
114; CHECK-LABEL: @test6
115entry:
116  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
117  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
118  br i1 %cond, label %if.then, label %fallthrough
119
120if.then:
121  br label %fallthrough
122
123fallthrough:
124; CHECK-YES: sunk_phi
125; CHECK-NO-LABEL: fallthrough:
126; CHECK-NO: phi
127; CHECK-NO-NEXT: phi
128; CHECK-NO-NEXT: load
129  %b = phi ptr [%b2, %entry], [%b1, %if.then]
130  %c = phi ptr [%a1, %entry], [%a2, %if.then]
131  %v = load i32, ptr %c, align 4
132  ret i32 %v
133}
134
135; case with a loop. No phi node.
136define i32 @test7(i32 %N, i1 %cond, ptr %b1, ptr %b2) {
137; CHECK-LABEL: @test7
138entry:
139  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
140  br label %loop
141
142loop:
143; CHECK-LABEL: loop:
144; CHECK-YES: sunk_phi
145  %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough]
146  %c3 = phi ptr [%a1, %entry], [%c, %fallthrough]
147  br i1 %cond, label %if.then, label %fallthrough
148
149if.then:
150  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
151  br label %fallthrough
152
153fallthrough:
154; CHECK-YES: sunk_phi
155; CHECK-NO-LABEL: fallthrough:
156; CHECK-NO: phi
157; CHECK-NO-NEXT: load
158  %c = phi ptr [%c3, %loop], [%a2, %if.then]
159  %v = load volatile i32, ptr %c, align 4
160  %iv.inc = add i32 %iv, 1
161  %cmp = icmp slt i32 %iv.inc, %N
162  br i1 %cmp, label %loop, label %exit
163
164exit:
165  ret i32 %v
166}
167
168; case with a loop. There is phi node.
169define i32 @test8(i32 %N, i1 %cond, ptr %b1, ptr %b2) {
170; CHECK-LABEL: @test8
171entry:
172  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
173  br label %loop
174
175loop:
176  %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough]
177  %c3 = phi ptr [%a1, %entry], [%c, %fallthrough]
178  %b3 = phi ptr [%b1, %entry], [%b, %fallthrough]
179  br i1 %cond, label %if.then, label %fallthrough
180
181if.then:
182  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
183  br label %fallthrough
184
185fallthrough:
186; CHECK: getelementptr inbounds i8, {{.+}} 40
187  %c = phi ptr [%c3, %loop], [%a2, %if.then]
188  %b = phi ptr [%b3, %loop], [%b2, %if.then]
189  %v = load volatile i32, ptr %c, align 4
190  %iv.inc = add i32 %iv, 1
191  %cmp = icmp slt i32 %iv.inc, %N
192  br i1 %cmp, label %loop, label %exit
193
194exit:
195  ret i32 %v
196}
197
198; case with a loop. There is phi node but it does not fit.
199define i32 @test9(i32 %N, i1 %cond, ptr %b1, ptr %b2) {
200; CHECK-LABEL: @test9
201entry:
202  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
203  br label %loop
204
205loop:
206; CHECK-LABEL: loop:
207; CHECK-YES: sunk_phi
208  %iv = phi i32 [0, %entry], [%iv.inc, %fallthrough]
209  %c3 = phi ptr [%a1, %entry], [%c, %fallthrough]
210  %b3 = phi ptr [%b1, %entry], [%b2, %fallthrough]
211  br i1 %cond, label %if.then, label %fallthrough
212
213if.then:
214  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
215  br label %fallthrough
216
217fallthrough:
218; CHECK-YES: sunk_phi
219; CHECK-NO-LABEL: fallthrough:
220; CHECK-NO: phi
221; CHECK-NO-NEXT: phi
222; CHECK-NO-NEXT: load
223  %c = phi ptr [%c3, %loop], [%a2, %if.then]
224  %b = phi ptr [%b3, %loop], [%b2, %if.then]
225  %v = load volatile i32, ptr %c, align 4
226  %iv.inc = add i32 %iv, 1
227  %cmp = icmp slt i32 %iv.inc, %N
228  br i1 %cmp, label %loop, label %exit
229
230exit:
231  ret i32 %v
232}
233
234; Case through a loop. No phi node.
235define i32 @test10(i32 %N, i1 %cond, ptr %b1, ptr %b2) {
236; CHECK-LABEL: @test10
237entry:
238  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
239  br i1 %cond, label %if.then, label %fallthrough
240
241if.then:
242  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
243  br label %fallthrough
244
245fallthrough:
246; CHECK-YES: sunk_phi
247; CHECK-NO-LABEL: fallthrough:
248; CHECK-NO-NEXT: phi
249; CHECK-NO-NEXT: br
250  %c = phi ptr [%a1, %entry], [%a2, %if.then]
251  br label %loop
252
253loop:
254  %iv = phi i32 [0, %fallthrough], [%iv.inc, %loop]
255  %iv.inc = add i32 %iv, 1
256  %cmp = icmp slt i32 %iv.inc, %N
257  br i1 %cmp, label %loop, label %exit
258
259exit:
260; CHECK-YES: sunkaddr
261  %v = load volatile i32, ptr %c, align 4
262  ret i32 %v
263}
264
265; Case through a loop. There is a phi.
266define i32 @test11(i32 %N, i1 %cond, ptr %b1, ptr %b2) {
267; CHECK-LABEL: @test11
268entry:
269  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
270  br i1 %cond, label %if.then, label %fallthrough
271
272if.then:
273  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
274  br label %fallthrough
275
276fallthrough:
277; CHECK: phi
278; CHECK: phi
279; CHECK: br
280  %c = phi ptr [%a1, %entry], [%a2, %if.then]
281  %b = phi ptr [%b1, %entry], [%b2, %if.then]
282  br label %loop
283
284loop:
285  %iv = phi i32 [0, %fallthrough], [%iv.inc, %loop]
286  %iv.inc = add i32 %iv, 1
287  %cmp = icmp slt i32 %iv.inc, %N
288  br i1 %cmp, label %loop, label %exit
289
290exit:
291; CHECK: sunkaddr
292  %v = load volatile i32, ptr %c, align 4
293  ret i32 %v
294}
295
296; Complex case with address value from previous iteration.
297define i32 @test12(i32 %N, i1 %cond, ptr %b1, ptr %b2, ptr %b3) {
298; CHECK-LABEL: @test12
299entry:
300  %a1 = getelementptr inbounds i64, ptr %b1, i64 5
301  br label %loop
302
303loop:
304; CHECK-LABEL: loop:
305; CHECK-YES: sunk_phi
306; CHECK-NO: phi
307; CHECK-NO-NEXT: phi
308; CHECK-NO-NEXT: phi
309; CHECK-NO-NEXT: br
310  %iv = phi i32 [0, %entry], [%iv.inc, %backedge]
311  %c3 = phi ptr [%a1, %entry], [%c, %backedge]
312  %b4 = phi ptr [%b1, %entry], [%b5, %backedge]
313  br i1 %cond, label %if.then, label %fallthrough
314
315if.then:
316  %a2 = getelementptr inbounds i64, ptr %b2, i64 5
317  br label %fallthrough
318
319fallthrough:
320; CHECK-LABEL: fallthrough:
321; CHECK-YES: sunk_phi
322; CHECK-NO: phi
323; CHECK-NO-NEXT: phi
324; CHECK-NO-NEXT: load
325  %c = phi ptr [%c3, %loop], [%a2, %if.then]
326  %b6 = phi ptr [%b4, %loop], [%b2, %if.then]
327  %v = load volatile i32, ptr %c, align 4
328  %a4 = getelementptr inbounds i64, ptr %b4, i64 5
329  %cmp = icmp slt i32 %iv, 20
330  br i1 %cmp, label %backedge, label %if.then.2
331
332if.then.2:
333  br label %backedge
334
335backedge:
336  %b5 = phi ptr [%b4, %fallthrough], [%b6, %if.then.2]
337  %iv.inc = add i32 %iv, 1
338  %cmp2 = icmp slt i32 %iv.inc, %N
339  br i1 %cmp2, label %loop, label %exit
340
341exit:
342  ret i32 %v
343}
344
345%struct.S = type {i32, i32}
346; Case with index
347define i32 @test13(i1 %cond, ptr %b1, ptr %b2, i64 %Index) {
348; CHECK-LABEL: @test13
349entry:
350  %a1 = getelementptr inbounds %struct.S, ptr %b1, i64 %Index, i32 1
351  br i1 %cond, label %if.then, label %fallthrough
352
353if.then:
354  %i2 = mul i64 %Index, 2
355  %a2 = getelementptr inbounds %struct.S, ptr %b2, i64 %Index, i32 1
356  br label %fallthrough
357
358fallthrough:
359; CHECK-YES: sunk_phi
360; CHECK-NO-LABEL: fallthrough:
361; CHECK-NO-NEXT: phi
362; CHECK-NO-NEXT: load
363  %a = phi ptr [%a1, %entry], [%a2, %if.then]
364  %v = load i32, ptr %a, align 4
365  ret i32 %v
366}
367
368; Select of Select case.
369define i64 @test14(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) {
370; CHECK-LABEL: @test14
371entry:
372; CHECK-LABEL: entry:
373  %g1 = getelementptr inbounds i64, ptr %b1, i64 5
374  %g2 = getelementptr inbounds i64, ptr %b2, i64 5
375  %g3 = getelementptr inbounds i64, ptr %b3, i64 5
376  %s1 = select i1 %c1, ptr %g1, ptr %g2
377  %s2 = select i1 %c2, ptr %s1, ptr %g3
378; CHECK: sunkaddr
379  %v = load i64 , ptr %s2, align 8
380  ret i64 %v
381}
382
383; Select of Phi case.
384define i64 @test15(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) {
385; CHECK-LABEL: @test15
386entry:
387  %g1 = getelementptr inbounds i64, ptr %b1, i64 5
388  %g2 = getelementptr inbounds i64, ptr %b2, i64 5
389  %g3 = getelementptr inbounds i64, ptr %b3, i64 5
390  br i1 %c1, label %if.then, label %fallthrough
391
392if.then:
393  br label %fallthrough
394
395fallthrough:
396; CHECK-LABEL: fallthrough:
397  %p1 = phi ptr [%g1, %entry], [%g2, %if.then]
398  %s1 = select i1 %c2, ptr %p1, ptr %g3
399; CHECK-YES: sunkaddr
400; CHECK-NO: phi
401; CHECK-NO-NEXT: select
402; CHECK-NO-NEXT: load
403  %v = load i64 , ptr %s1, align 8
404  ret i64 %v
405}
406
407; Select of Phi case. Phi exists
408define i64 @test16(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) {
409; CHECK-LABEL: @test16
410entry:
411  %g1 = getelementptr inbounds i64, ptr %b1, i64 5
412  %g2 = getelementptr inbounds i64, ptr %b2, i64 5
413  %g3 = getelementptr inbounds i64, ptr %b3, i64 5
414  br i1 %c1, label %if.then, label %fallthrough
415
416if.then:
417  br label %fallthrough
418
419fallthrough:
420; CHECK-LABEL: fallthrough:
421  %p = phi ptr [%b1, %entry], [%b2, %if.then]
422  %p1 = phi ptr [%g1, %entry], [%g2, %if.then]
423  %s1 = select i1 %c2, ptr %p1, ptr %g3
424; CHECK: sunkaddr
425  %v = load i64 , ptr %s1, align 8
426  ret i64 %v
427}
428
429; Phi of Select case.
430define i64 @test17(i1 %c1, i1 %c2, ptr %b1, ptr %b2, ptr %b3) {
431; CHECK-LABEL: @test17
432entry:
433  %g1 = getelementptr inbounds i64, ptr %b1, i64 5
434  %g2 = getelementptr inbounds i64, ptr %b2, i64 5
435  %g3 = getelementptr inbounds i64, ptr %b3, i64 5
436  %s1 = select i1 %c2, ptr %g1, ptr %g2
437  br i1 %c1, label %if.then, label %fallthrough
438
439if.then:
440  br label %fallthrough
441
442fallthrough:
443; CHECK-LABEL: fallthrough:
444  %p1 = phi ptr [%s1, %entry], [%g3, %if.then]
445; CHECK-YES: sunkaddr
446; CHECK-NO: phi
447; CHECK-NO-NEXT: load
448  %v = load i64 , ptr %p1, align 8
449  ret i64 %v
450}
451
452; The same two addr modes by different paths
453define i32 @test18(i1 %cond1, i1 %cond2, ptr %b1, ptr %b2) {
454; CHECK-LABEL: @test18
455entry:
456  %g1 = getelementptr inbounds i64, ptr %b2, i64 5
457  br i1 %cond1, label %if.then1, label %if.then2
458
459if.then1:
460  %g2 = getelementptr inbounds i64, ptr %b1, i64 5
461  br label %fallthrough
462
463if.then2:
464  br i1 %cond2, label %fallthrough, label %if.then3
465
466if.then3:
467  br label %fallthrough
468
469fallthrough:
470; CHECK-YES: sunk_phi
471; CHECK-NO-LABEL: fallthrough:
472; CHECK-NO: phi
473; CHECK-NO-NEXT: load
474  %c = phi ptr [%g2, %if.then1], [%g1, %if.then2], [%g1, %if.then3]
475  %v1 = load i32, ptr %c, align 4
476  %g1_1 = getelementptr inbounds i64, ptr %b2, i64 5
477  %v2 = load i32, ptr %g1_1, align 4
478  %v = add i32 %v1, %v2
479  ret i32 %v
480}
481
482; Different types but null is the first?
483define i32 @test19(i1 %cond1, i1 %cond2, ptr %b2, ptr %b1) {
484; CHECK-LABEL: @test19
485entry:
486  %g1 = getelementptr inbounds i64, ptr %b2, i64 5
487  %bc1 = bitcast ptr %g1 to ptr
488  br i1 %cond1, label %if.then1, label %if.then2
489
490if.then1:
491  %g2 = getelementptr inbounds i8, ptr %b1, i64 40
492  %bc2 = bitcast ptr %g2 to ptr
493  br label %fallthrough
494
495if.then2:
496  %bc1_1 = bitcast ptr %g1 to ptr
497  br i1 %cond2, label %fallthrough, label %if.then3
498
499if.then3:
500  %g3 = getelementptr inbounds i64, ptr null, i64 5
501  %bc1_2 = bitcast ptr %g3 to ptr
502  br label %fallthrough
503
504fallthrough:
505; CHECK-NOT: sunk_phi
506  %c = phi ptr [%bc2, %if.then1], [%bc1_1, %if.then2], [%bc1_2, %if.then3]
507  %v1 = load i32, ptr %c, align 4
508  %g1_1 = getelementptr inbounds i64, ptr %b2, i64 5
509  %bc1_1_1 = bitcast ptr %g1_1 to ptr
510  %v2 = load i32, ptr %bc1_1_1, align 4
511  %v = add i32 %v1, %v2
512  ret i32 %v
513}
514