• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -jump-threading -S | FileCheck %s
2; RUN: opt < %s -passes=jump-threading -S | FileCheck %s
3
4target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
5target triple = "i386-apple-darwin7"
6
7; Test that we can thread through the block with the partially redundant load (%2).
8; rdar://6402033
9define i32 @test1(i32* %P) nounwind {
10; CHECK-LABEL: @test1(
11entry:
12	%0 = tail call i32 (...) @f1() nounwind		; <i32> [#uses=1]
13	%1 = icmp eq i32 %0, 0		; <i1> [#uses=1]
14	br i1 %1, label %bb1, label %bb
15
16bb:		; preds = %entry
17; CHECK: bb1.thread:
18; CHECK: store
19; CHECK: br label %bb3
20	store i32 42, i32* %P, align 4
21	br label %bb1
22
23bb1:		; preds = %entry, %bb
24	%res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]		; <i32> [#uses=2]
25	%2 = load i32, i32* %P, align 4		; <i32> [#uses=1]
26	%3 = icmp sgt i32 %2, 36		; <i1> [#uses=1]
27	br i1 %3, label %bb3, label %bb2
28
29bb2:		; preds = %bb1
30	%4 = tail call i32 (...) @f2() nounwind		; <i32> [#uses=0]
31	ret i32 %res.0
32
33bb3:		; preds = %bb1
34; CHECK: bb3:
35; CHECK: %res.01 = phi i32 [ 1, %bb1.thread ], [ 0, %bb1 ]
36; CHECK: ret i32 %res.01
37	ret i32 %res.0
38}
39
40declare i32 @f1(...)
41
42declare i32 @f2(...)
43
44
45;; Check that we preserve TBAA information.
46; rdar://11039258
47
48define i32 @test2(i32* %P) nounwind {
49; CHECK-LABEL: @test2(
50entry:
51	%0 = tail call i32 (...) @f1() nounwind		; <i32> [#uses=1]
52	%1 = icmp eq i32 %0, 0		; <i1> [#uses=1]
53	br i1 %1, label %bb1, label %bb
54
55bb:		; preds = %entry
56; CHECK: bb1.thread:
57; CHECK: store{{.*}}, !tbaa !0
58; CHECK: br label %bb3
59	store i32 42, i32* %P, align 4, !tbaa !0
60	br label %bb1
61
62bb1:		; preds = %entry, %bb
63	%res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
64	%2 = load i32, i32* %P, align 4, !tbaa !0
65	%3 = icmp sgt i32 %2, 36
66	br i1 %3, label %bb3, label %bb2
67
68bb2:		; preds = %bb1
69	%4 = tail call i32 (...) @f2() nounwind
70	ret i32 %res.0
71
72bb3:		; preds = %bb1
73; CHECK: bb3:
74; CHECK: %res.01 = phi i32 [ 1, %bb1.thread ], [ 0, %bb1 ]
75; CHECK: ret i32 %res.01
76	ret i32 %res.0
77}
78
79define i32 @test3(i8** %x, i1 %f) {
80; Correctly thread loads of different (but compatible) types, placing bitcasts
81; as necessary in the predecessors. This is especially tricky because the same
82; predecessor ends up with two entries in the PHI node and they must share
83; a single cast.
84; CHECK-LABEL: @test3(
85entry:
86  %0 = bitcast i8** %x to i32**
87  %1 = load i32*, i32** %0, align 8
88  br i1 %f, label %if.end57, label %if.then56
89; CHECK: %[[LOAD:.*]] = load i32*, i32**
90; CHECK: %[[CAST:.*]] = bitcast i32* %[[LOAD]] to i8*
91
92if.then56:
93  br label %if.end57
94
95if.end57:
96  %2 = load i8*, i8** %x, align 8
97  %tobool59 = icmp eq i8* %2, null
98  br i1 %tobool59, label %return, label %if.then60
99; CHECK: %[[PHI:.*]] = phi i8* [ %[[CAST]], %[[PRED:[^ ]+]] ], [ %[[CAST]], %[[PRED]] ]
100; CHECK-NEXT: %[[CMP:.*]] = icmp eq i8* %[[PHI]], null
101; CHECK-NEXT: br i1 %[[CMP]]
102
103if.then60:
104  ret i32 42
105
106return:
107  ret i32 13
108}
109
110define i32 @test4(i32* %P) {
111; CHECK-LABEL: @test4(
112entry:
113  %v0 = tail call i32 (...) @f1()
114  %v1 = icmp eq i32 %v0, 0
115  br i1 %v1, label %bb1, label %bb
116
117bb:
118; CHECK: bb1.thread:
119; CHECK: store atomic
120; CHECK: br label %bb3
121  store atomic i32 42, i32* %P unordered, align 4
122  br label %bb1
123
124bb1:
125; CHECK: bb1:
126; CHECK-NOT: phi
127; CHECK: load atomic
128  %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
129  %v2 = load atomic i32, i32* %P unordered, align 4
130  %v3 = icmp sgt i32 %v2, 36
131  br i1 %v3, label %bb3, label %bb2
132
133bb2:
134  %v4 = tail call i32 (...) @f2()
135  ret i32 %res.0
136
137bb3:
138  ret i32 %res.0
139}
140
141define i32 @test5(i32* %P) {
142; Negative test
143
144; CHECK-LABEL: @test5(
145entry:
146  %v0 = tail call i32 (...) @f1()
147  %v1 = icmp eq i32 %v0, 0
148  br i1 %v1, label %bb1, label %bb
149
150bb:
151; CHECK: bb:
152; CHECK-NEXT:   store atomic i32 42, i32* %P release, align 4
153; CHECK-NEXT:   br label %bb1
154  store atomic i32 42, i32* %P release, align 4
155  br label %bb1
156
157bb1:
158; CHECK: bb1:
159; CHECK-NEXT:  %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
160; CHECK-NEXT:  %v2 = load atomic i32, i32* %P acquire, align 4
161; CHECK-NEXT:  %v3 = icmp sgt i32 %v2, 36
162; CHECK-NEXT:  br i1 %v3, label %bb3, label %bb2
163
164  %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
165  %v2 = load atomic i32, i32* %P acquire, align 4
166  %v3 = icmp sgt i32 %v2, 36
167  br i1 %v3, label %bb3, label %bb2
168
169bb2:
170  %v4 = tail call i32 (...) @f2()
171  ret i32 %res.0
172
173bb3:
174  ret i32 %res.0
175}
176
177define i32 @test6(i32* %P) {
178; Negative test
179
180; CHECK-LABEL: @test6(
181entry:
182  %v0 = tail call i32 (...) @f1()
183  %v1 = icmp eq i32 %v0, 0
184  br i1 %v1, label %bb1, label %bb
185
186bb:
187; CHECK: bb:
188; CHECK-NEXT:   store i32 42, i32* %P
189; CHECK-NEXT:   br label %bb1
190  store i32 42, i32* %P
191  br label %bb1
192
193bb1:
194; CHECK: bb1:
195; CHECK-NEXT:  %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
196; CHECK-NEXT:  %v2 = load atomic i32, i32* %P acquire, align 4
197; CHECK-NEXT:  %v3 = icmp sgt i32 %v2, 36
198; CHECK-NEXT:  br i1 %v3, label %bb3, label %bb2
199
200  %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
201  %v2 = load atomic i32, i32* %P acquire, align 4
202  %v3 = icmp sgt i32 %v2, 36
203  br i1 %v3, label %bb3, label %bb2
204
205bb2:
206  %v4 = tail call i32 (...) @f2()
207  ret i32 %res.0
208
209bb3:
210  ret i32 %res.0
211}
212
213define i32 @test7(i32* %P) {
214; Negative test
215
216; CHECK-LABEL: @test7(
217entry:
218  %v0 = tail call i32 (...) @f1()
219  %v1 = icmp eq i32 %v0, 0
220  br i1 %v1, label %bb1, label %bb
221
222bb:
223; CHECK: bb:
224; CHECK-NEXT:   %val = load i32, i32* %P
225; CHECK-NEXT:   br label %bb1
226  %val = load i32, i32* %P
227  br label %bb1
228
229bb1:
230; CHECK: bb1:
231; CHECK-NEXT:  %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
232; CHECK-NEXT:  %v2 = load atomic i32, i32* %P acquire, align 4
233; CHECK-NEXT:  %v3 = icmp sgt i32 %v2, 36
234; CHECK-NEXT:  br i1 %v3, label %bb3, label %bb2
235
236  %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ]
237  %v2 = load atomic i32, i32* %P acquire, align 4
238  %v3 = icmp sgt i32 %v2, 36
239  br i1 %v3, label %bb3, label %bb2
240
241bb2:
242  %v4 = tail call i32 (...) @f2()
243  ret i32 %res.0
244
245bb3:
246  ret i32 %res.0
247}
248
249!0 = !{!3, !3, i64 0}
250!1 = !{!"omnipotent char", !2}
251!2 = !{!"Simple C/C++ TBAA", null}
252!3 = !{!"int", !1}
253