[rtsan] Add fork/execve interceptors (#117198)
[llvm-project.git] / llvm / test / Transforms / Sink / basic.ll
blob3094d982d8377b1190d295fd125d3740b7ad4901
1 ; RUN: opt < %s -passes=sink -S | FileCheck %s
2 ; RUN: opt < %s -aa-pipeline='basic-aa' -passes='sink' -S | FileCheck %s
4 @A = external global i32
5 @B = external global i32
7 ; Sink should sink the load past the store (which doesn't overlap) into
8 ; the block that uses it.
10 ;      CHECK-LABEL: @foo(
11 ;      CHECK: true:
12 ; CHECK-NEXT: %l = load i32, ptr @A
13 ; CHECK-NEXT: ret i32 %l
15 define i32 @foo(i1 %z) {
16   %l = load i32, ptr @A
17   store i32 0, ptr @B
18   br i1 %z, label %true, label %false
19 true:
20   ret i32 %l
21 false:
22   ret i32 0
25 ; But don't sink load volatiles...
27 ;      CHECK-LABEL: @foo2(
28 ;      CHECK: load volatile
29 ; CHECK-NEXT: store i32
31 define i32 @foo2(i1 %z) {
32   %l = load volatile i32, ptr @A
33   store i32 0, ptr @B
34   br i1 %z, label %true, label %false
35 true:
36   ret i32 %l
37 false:
38   ret i32 0
41 ; Sink to the nearest post-dominator
43 ;      CHECK-LABEL: @diamond(
44 ;      CHECK: X:
45 ; CHECK-NEXT: phi
46 ; CHECK-NEXT: mul nsw
47 ; CHECK-NEXT: sub
49 define 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
54 B0:                                       ; preds = %0
55   br label %X
57 B1:                                      ; preds = %0
58   br label %X
60 X:                                     ; preds = %5, %3
61   %.01 = phi i32 [ %c, %B0 ], [ %a, %B1 ]
62   %R = sub i32 %1, %.01
63   ret i32 %R
66 ; 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.
69 ; CHECK-LABEL: @alloca_nosink
70 ; CHECK: entry:
71 ; CHECK-NEXT: alloca
72 define i32 @alloca_nosink(i32 %a, i32 %b) {
73 entry:
74   %0 = alloca i32
75   %1 = icmp ne i32 %a, 0
76   br i1 %1, label %if, label %endif
78 if:
79   %2 = getelementptr i32, ptr %0, i32 1
80   store i32 0, ptr %0
81   store i32 1, ptr %2
82   %3 = getelementptr i32, ptr %0, i32 %b
83   %4 = load i32, ptr %3
84   ret i32 %4
86 endif:
87   ret i32 0
90 ; Make sure we sink dynamic sized allocas
92 ; CHECK-LABEL: @alloca_sink_dynamic
93 ; CHECK: entry:
94 ; CHECK-NOT: alloca
95 ; CHECK: if:
96 ; CHECK-NEXT: alloca
97 define i32 @alloca_sink_dynamic(i32 %a, i32 %b, i32 %size) {
98 entry:
99   %0 = alloca i32, i32 %size
100   %1 = icmp ne i32 %a, 0
101   br i1 %1, label %if, label %endif
104   %2 = getelementptr i32, ptr %0, i32 1
105   store i32 0, ptr %0
106   store i32 1, ptr %2
107   %3 = getelementptr i32, ptr %0, i32 %b
108   %4 = load i32, ptr %3
109   ret i32 %4
111 endif:
112   ret i32 0
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.
119 ; CHECK-LABEL: @alloca_sink_nonentry
120 ; CHECK: if0:
121 ; CHECK-NOT: alloca
122 ; CHECK: if:
123 ; CHECK-NEXT: alloca
124 define i32 @alloca_sink_nonentry(i32 %a, i32 %b, i32 %c) {
125 entry:
126   %cmp = icmp ne i32 %c, 0
127   br i1 %cmp, label %endif, label %if0
129 if0:
130   %0 = alloca i32
131   %1 = icmp ne i32 %a, 0
132   br i1 %1, label %if, label %endif
135   %2 = getelementptr i32, ptr %0, i32 1
136   store i32 0, ptr %0
137   store i32 1, ptr %2
138   %3 = getelementptr i32, ptr %0, i32 %b
139   %4 = load i32, ptr %3
140   ret i32 %4
142 endif:
143   ret i32 0