blob: 1bbf161921d1ed0cb577f6e8e67a498ba4fbbfed [file] [log] [blame]
Dan Gohman02538ac2010-10-18 18:04:47 +00001; RUN: opt < %s -basicaa -sink -S | FileCheck %s
Dan Gohman5d5b8b12010-05-07 15:40:13 +00002
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
Stephen Linc1c7a132013-07-14 01:42:54 +00009; CHECK-LABEL: @foo(
Dan Gohman5d5b8b12010-05-07 15:40:13 +000010; CHECK: true:
David Blaikiea79ac142015-02-27 21:17:42 +000011; CHECK-NEXT: %l = load i32, i32* @A
Dan Gohman5d5b8b12010-05-07 15:40:13 +000012; CHECK-NEXT: ret i32 %l
13
14define i32 @foo(i1 %z) {
David Blaikiea79ac142015-02-27 21:17:42 +000015 %l = load i32, i32* @A
Dan Gohman5d5b8b12010-05-07 15:40:13 +000016 store i32 0, i32* @B
17 br i1 %z, label %true, label %false
18true:
19 ret i32 %l
20false:
21 ret i32 0
22}
Eli Friedman71f5c2f2011-09-01 21:21:24 +000023
Chris Lattner6a144a22011-11-27 06:54:59 +000024; But don't sink load volatiles...
Eli Friedman71f5c2f2011-09-01 21:21:24 +000025
Stephen Linc1c7a132013-07-14 01:42:54 +000026; CHECK-LABEL: @foo2(
Eli Friedman4028a512011-09-01 21:25:42 +000027; CHECK: load volatile
Eli Friedman71f5c2f2011-09-01 21:21:24 +000028; CHECK-NEXT: store i32
29
30define i32 @foo2(i1 %z) {
David Blaikiea79ac142015-02-27 21:17:42 +000031 %l = load volatile i32, i32* @A
Eli Friedman71f5c2f2011-09-01 21:21:24 +000032 store i32 0, i32* @B
33 br i1 %z, label %true, label %false
34true:
35 ret i32 %l
36false:
37 ret i32 0
38}
Duncan Sands339bb612012-05-31 08:09:49 +000039
40; Sink to the nearest post-dominator
41
Stephen Linc1c7a132013-07-14 01:42:54 +000042; CHECK-LABEL: @diamond(
Duncan Sands339bb612012-05-31 08:09:49 +000043; 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
Tom Stellardedfd81d2014-03-21 15:51:51 +000065; 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:
David Blaikie79e6c742015-02-27 19:29:02 +000078 %2 = getelementptr i32, i32* %0, i32 1
Tom Stellardedfd81d2014-03-21 15:51:51 +000079 store i32 0, i32* %0
80 store i32 1, i32* %2
David Blaikie79e6c742015-02-27 19:29:02 +000081 %3 = getelementptr i32, i32* %0, i32 %b
David Blaikiea79ac142015-02-27 21:17:42 +000082 %4 = load i32, i32* %3
Tom Stellardedfd81d2014-03-21 15:51:51 +000083 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:
David Blaikie79e6c742015-02-27 19:29:02 +0000103 %2 = getelementptr i32, i32* %0, i32 1
Tom Stellardedfd81d2014-03-21 15:51:51 +0000104 store i32 0, i32* %0
105 store i32 1, i32* %2
David Blaikie79e6c742015-02-27 19:29:02 +0000106 %3 = getelementptr i32, i32* %0, i32 %b
David Blaikiea79ac142015-02-27 21:17:42 +0000107 %4 = load i32, i32* %3
Tom Stellardedfd81d2014-03-21 15:51:51 +0000108 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:
David Blaikie79e6c742015-02-27 19:29:02 +0000134 %2 = getelementptr i32, i32* %0, i32 1
Tom Stellardedfd81d2014-03-21 15:51:51 +0000135 store i32 0, i32* %0
136 store i32 1, i32* %2
David Blaikie79e6c742015-02-27 19:29:02 +0000137 %3 = getelementptr i32, i32* %0, i32 %b
David Blaikiea79ac142015-02-27 21:17:42 +0000138 %4 = load i32, i32* %3
Tom Stellardedfd81d2014-03-21 15:51:51 +0000139 ret i32 %4
140
141endif:
142 ret i32 0
143}