blob: 8ff41262014d9aca96e43f02567761de9672353f [file] [log] [blame]
Dan Gohman02538ac2010-10-18 18:04:47 +00001; RUN: opt < %s -basicaa -sink -S | FileCheck %s
Justin Bognerb9394902016-04-22 19:54:10 +00002; RUN: opt < %s -aa-pipeline='basic-aa' -passes='sink' -S | FileCheck %s
Dan Gohman5d5b8b12010-05-07 15:40:13 +00003
4@A = external global i32
5@B = external global i32
6
7; Sink should sink the load past the store (which doesn't overlap) into
8; the block that uses it.
9
Stephen Linc1c7a132013-07-14 01:42:54 +000010; CHECK-LABEL: @foo(
Dan Gohman5d5b8b12010-05-07 15:40:13 +000011; CHECK: true:
David Blaikiea79ac142015-02-27 21:17:42 +000012; CHECK-NEXT: %l = load i32, i32* @A
Dan Gohman5d5b8b12010-05-07 15:40:13 +000013; CHECK-NEXT: ret i32 %l
14
15define i32 @foo(i1 %z) {
David Blaikiea79ac142015-02-27 21:17:42 +000016 %l = load i32, i32* @A
Dan Gohman5d5b8b12010-05-07 15:40:13 +000017 store i32 0, i32* @B
18 br i1 %z, label %true, label %false
19true:
20 ret i32 %l
21false:
22 ret i32 0
23}
Eli Friedman71f5c2f2011-09-01 21:21:24 +000024
Chris Lattner6a144a22011-11-27 06:54:59 +000025; But don't sink load volatiles...
Eli Friedman71f5c2f2011-09-01 21:21:24 +000026
Stephen Linc1c7a132013-07-14 01:42:54 +000027; CHECK-LABEL: @foo2(
Eli Friedman4028a512011-09-01 21:25:42 +000028; CHECK: load volatile
Eli Friedman71f5c2f2011-09-01 21:21:24 +000029; CHECK-NEXT: store i32
30
31define i32 @foo2(i1 %z) {
David Blaikiea79ac142015-02-27 21:17:42 +000032 %l = load volatile i32, i32* @A
Eli Friedman71f5c2f2011-09-01 21:21:24 +000033 store i32 0, i32* @B
34 br i1 %z, label %true, label %false
35true:
36 ret i32 %l
37false:
38 ret i32 0
39}
Duncan Sands339bb612012-05-31 08:09:49 +000040
41; Sink to the nearest post-dominator
42
Stephen Linc1c7a132013-07-14 01:42:54 +000043; CHECK-LABEL: @diamond(
Duncan Sands339bb612012-05-31 08:09:49 +000044; CHECK: X:
45; CHECK-NEXT: phi
46; CHECK-NEXT: mul nsw
47; CHECK-NEXT: sub
48
49define i32 @diamond(i32 %a, i32 %b, i32 %c) {
50 %1 = mul nsw i32 %c, %b
51 %2 = icmp sgt i32 %a, 0
52 br i1 %2, label %B0, label %B1
53
54B0: ; preds = %0
55 br label %X
56
57B1: ; preds = %0
58 br label %X
59
60X: ; preds = %5, %3
61 %.01 = phi i32 [ %c, %B0 ], [ %a, %B1 ]
62 %R = sub i32 %1, %.01
63 ret i32 %R
64}
65
Tom Stellardedfd81d2014-03-21 15:51:51 +000066; We shouldn't sink constant sized allocas from the entry block, since CodeGen
67; interprets allocas outside the entry block as dynamically sized stack objects.
68
69; CHECK-LABEL: @alloca_nosink
70; CHECK: entry:
71; CHECK-NEXT: alloca
72define i32 @alloca_nosink(i32 %a, i32 %b) {
73entry:
74 %0 = alloca i32
75 %1 = icmp ne i32 %a, 0
76 br i1 %1, label %if, label %endif
77
78if:
David Blaikie79e6c742015-02-27 19:29:02 +000079 %2 = getelementptr i32, i32* %0, i32 1
Tom Stellardedfd81d2014-03-21 15:51:51 +000080 store i32 0, i32* %0
81 store i32 1, i32* %2
David Blaikie79e6c742015-02-27 19:29:02 +000082 %3 = getelementptr i32, i32* %0, i32 %b
David Blaikiea79ac142015-02-27 21:17:42 +000083 %4 = load i32, i32* %3
Tom Stellardedfd81d2014-03-21 15:51:51 +000084 ret i32 %4
85
86endif:
87 ret i32 0
88}
89
90; Make sure we sink dynamic sized allocas
91
92; CHECK-LABEL: @alloca_sink_dynamic
93; CHECK: entry:
94; CHECK-NOT: alloca
95; CHECK: if:
96; CHECK-NEXT: alloca
97define i32 @alloca_sink_dynamic(i32 %a, i32 %b, i32 %size) {
98entry:
99 %0 = alloca i32, i32 %size
100 %1 = icmp ne i32 %a, 0
101 br i1 %1, label %if, label %endif
102
103if:
David Blaikie79e6c742015-02-27 19:29:02 +0000104 %2 = getelementptr i32, i32* %0, i32 1
Tom Stellardedfd81d2014-03-21 15:51:51 +0000105 store i32 0, i32* %0
106 store i32 1, i32* %2
David Blaikie79e6c742015-02-27 19:29:02 +0000107 %3 = getelementptr i32, i32* %0, i32 %b
David Blaikiea79ac142015-02-27 21:17:42 +0000108 %4 = load i32, i32* %3
Tom Stellardedfd81d2014-03-21 15:51:51 +0000109 ret i32 %4
110
111endif:
112 ret i32 0
113}
114
115; We also want to sink allocas that are not in the entry block. These
116; will already be considered as dynamically sized stack objects, so sinking
117; them does no further damage.
118
119; CHECK-LABEL: @alloca_sink_nonentry
120; CHECK: if0:
121; CHECK-NOT: alloca
122; CHECK: if:
123; CHECK-NEXT: alloca
124define i32 @alloca_sink_nonentry(i32 %a, i32 %b, i32 %c) {
125entry:
126 %cmp = icmp ne i32 %c, 0
127 br i1 %cmp, label %endif, label %if0
128
129if0:
130 %0 = alloca i32
131 %1 = icmp ne i32 %a, 0
132 br i1 %1, label %if, label %endif
133
134if:
David Blaikie79e6c742015-02-27 19:29:02 +0000135 %2 = getelementptr i32, i32* %0, i32 1
Tom Stellardedfd81d2014-03-21 15:51:51 +0000136 store i32 0, i32* %0
137 store i32 1, i32* %2
David Blaikie79e6c742015-02-27 19:29:02 +0000138 %3 = getelementptr i32, i32* %0, i32 %b
David Blaikiea79ac142015-02-27 21:17:42 +0000139 %4 = load i32, i32* %3
Tom Stellardedfd81d2014-03-21 15:51:51 +0000140 ret i32 %4
141
142endif:
143 ret i32 0
144}