• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -basicaa -sink -S | FileCheck %s
2
3@A = external global i32
4@B = external global i32
5
6; Sink should sink the load past the store (which doesn't overlap) into
7; the block that uses it.
8
9;      CHECK-LABEL: @foo(
10;      CHECK: true:
11; CHECK-NEXT: %l = load i32* @A
12; CHECK-NEXT: ret i32 %l
13
14define i32 @foo(i1 %z) {
15  %l = load i32* @A
16  store i32 0, i32* @B
17  br i1 %z, label %true, label %false
18true:
19  ret i32 %l
20false:
21  ret i32 0
22}
23
24; But don't sink load volatiles...
25
26;      CHECK-LABEL: @foo2(
27;      CHECK: load volatile
28; CHECK-NEXT: store i32
29
30define i32 @foo2(i1 %z) {
31  %l = load volatile i32* @A
32  store i32 0, i32* @B
33  br i1 %z, label %true, label %false
34true:
35  ret i32 %l
36false:
37  ret i32 0
38}
39
40; Sink to the nearest post-dominator
41
42;      CHECK-LABEL: @diamond(
43;      CHECK: X:
44; CHECK-NEXT: phi
45; CHECK-NEXT: mul nsw
46; CHECK-NEXT: sub
47
48define i32 @diamond(i32 %a, i32 %b, i32 %c) {
49  %1 = mul nsw i32 %c, %b
50  %2 = icmp sgt i32 %a, 0
51  br i1 %2, label %B0, label %B1
52
53B0:                                       ; preds = %0
54  br label %X
55
56B1:                                      ; preds = %0
57  br label %X
58
59X:                                     ; preds = %5, %3
60  %.01 = phi i32 [ %c, %B0 ], [ %a, %B1 ]
61  %R = sub i32 %1, %.01
62  ret i32 %R
63}
64
65; We shouldn't sink constant sized allocas from the entry block, since CodeGen
66; interprets allocas outside the entry block as dynamically sized stack objects.
67
68; CHECK-LABEL: @alloca_nosink
69; CHECK: entry:
70; CHECK-NEXT: alloca
71define i32 @alloca_nosink(i32 %a, i32 %b) {
72entry:
73  %0 = alloca i32
74  %1 = icmp ne i32 %a, 0
75  br i1 %1, label %if, label %endif
76
77if:
78  %2 = getelementptr i32* %0, i32 1
79  store i32 0, i32* %0
80  store i32 1, i32* %2
81  %3 = getelementptr i32* %0, i32 %b
82  %4 = load i32* %3
83  ret i32 %4
84
85endif:
86  ret i32 0
87}
88
89; Make sure we sink dynamic sized allocas
90
91; CHECK-LABEL: @alloca_sink_dynamic
92; CHECK: entry:
93; CHECK-NOT: alloca
94; CHECK: if:
95; CHECK-NEXT: alloca
96define i32 @alloca_sink_dynamic(i32 %a, i32 %b, i32 %size) {
97entry:
98  %0 = alloca i32, i32 %size
99  %1 = icmp ne i32 %a, 0
100  br i1 %1, label %if, label %endif
101
102if:
103  %2 = getelementptr i32* %0, i32 1
104  store i32 0, i32* %0
105  store i32 1, i32* %2
106  %3 = getelementptr i32* %0, i32 %b
107  %4 = load i32* %3
108  ret i32 %4
109
110endif:
111  ret i32 0
112}
113
114; We also want to sink allocas that are not in the entry block.  These
115; will already be considered as dynamically sized stack objects, so sinking
116; them does no further damage.
117
118; CHECK-LABEL: @alloca_sink_nonentry
119; CHECK: if0:
120; CHECK-NOT: alloca
121; CHECK: if:
122; CHECK-NEXT: alloca
123define i32 @alloca_sink_nonentry(i32 %a, i32 %b, i32 %c) {
124entry:
125  %cmp = icmp ne i32 %c, 0
126  br i1 %cmp, label %endif, label %if0
127
128if0:
129  %0 = alloca i32
130  %1 = icmp ne i32 %a, 0
131  br i1 %1, label %if, label %endif
132
133if:
134  %2 = getelementptr i32* %0, i32 1
135  store i32 0, i32* %0
136  store i32 1, i32* %2
137  %3 = getelementptr i32* %0, i32 %b
138  %4 = load i32* %3
139  ret i32 %4
140
141endif:
142  ret i32 0
143}
144