1; RUN: opt -S -gvn-hoist < %s | FileCheck %s
2
3; Checking gvn-hoist in case of indirect branches.
4
5; Check that the bitcast is not hoisted because it is after an indirect call
6; CHECK-LABEL: @foo
7; CHECK-LABEL: l1.preheader:
8; CHECK-NEXT: bitcast
9; CHECK-LABEL: l1
10; CHECK: bitcast
11
12%class.bar = type { i8*, %class.base* }
13%class.base = type { i32 (...)** }
14
15@bar = local_unnamed_addr global i32 ()* null, align 8
16@bar1 = local_unnamed_addr global i32 ()* null, align 8
17
18define i32 @foo(i32* nocapture readonly %i) {
19entry:
20  %agg.tmp = alloca %class.bar, align 8
21  %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1
22  %y = load %class.base*, %class.base** %x, align 8
23  %0 = load i32, i32* %i, align 4
24  %.off = add i32 %0, -1
25  %switch = icmp ult i32 %.off, 2
26  br i1 %switch, label %l1.preheader, label %sw.default
27
28l1.preheader:                                     ; preds = %sw.default, %entry
29  %b1 = bitcast %class.base* %y to void (%class.base*)***
30  br label %l1
31
32l1:                                               ; preds = %l1.preheader, %l1
33  %1 = load i32 ()*, i32 ()** @bar, align 8
34  %call = tail call i32 %1()
35  %b2 = bitcast %class.base* %y to void (%class.base*)***
36  br label %l1
37
38sw.default:                                       ; preds = %entry
39  %2 = load i32 ()*, i32 ()** @bar1, align 8
40  %call2 = tail call i32 %2()
41  br label %l1.preheader
42}
43
44
45; Any instruction inside an infinite loop will not be hoisted because
46; there is no path to exit of the function.
47
48; CHECK-LABEL: @foo1
49; CHECK-LABEL: l1.preheader:
50; CHECK-NEXT: bitcast
51; CHECK-LABEL: l1:
52; CHECK: bitcast
53
54define i32 @foo1(i32* nocapture readonly %i) {
55entry:
56  %agg.tmp = alloca %class.bar, align 8
57  %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1
58  %y = load %class.base*, %class.base** %x, align 8
59  %0 = load i32, i32* %i, align 4
60  %.off = add i32 %0, -1
61  %switch = icmp ult i32 %.off, 2
62  br i1 %switch, label %l1.preheader, label %sw.default
63
64l1.preheader:                                     ; preds = %sw.default, %entry
65  %b1 = bitcast %class.base* %y to void (%class.base*)***
66  %y1 = load %class.base*, %class.base** %x, align 8
67  br label %l1
68
69l1:                                               ; preds = %l1.preheader, %l1
70  %b2 = bitcast %class.base* %y to void (%class.base*)***
71  %1 = load i32 ()*, i32 ()** @bar, align 8
72  %y2 = load %class.base*, %class.base** %x, align 8
73  %call = tail call i32 %1()
74  br label %l1
75
76sw.default:                                       ; preds = %entry
77  %2 = load i32 ()*, i32 ()** @bar1, align 8
78  %call2 = tail call i32 %2()
79  br label %l1.preheader
80}
81
82; Check that bitcast is hoisted even when one of them is partially redundant.
83; CHECK-LABEL: @test13
84; CHECK: bitcast
85; CHECK-NOT: bitcast
86
87define i32 @test13(i32* %P, i8* %Ptr, i32* nocapture readonly %i) {
88entry:
89  %agg.tmp = alloca %class.bar, align 8
90  %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1
91  %y = load %class.base*, %class.base** %x, align 8
92  indirectbr i8* %Ptr, [label %BrBlock, label %B2]
93
94B2:
95  %b1 = bitcast %class.base* %y to void (%class.base*)***
96  store i32 4, i32 *%P
97  br label %BrBlock
98
99BrBlock:
100  %b2 = bitcast %class.base* %y to void (%class.base*)***
101  %L = load i32, i32* %P
102  %C = icmp eq i32 %L, 42
103  br i1 %C, label %T, label %F
104
105T:
106  ret i32 123
107F:
108  ret i32 1422
109}
110
111; Check that the bitcast is not hoisted because anticipability
112; cannot be guaranteed here as one of the indirect branch targets
113; do not have the bitcast instruction.
114
115; CHECK-LABEL: @test14
116; CHECK-LABEL: B2:
117; CHECK-NEXT: bitcast
118; CHECK-LABEL: BrBlock:
119; CHECK-NEXT: bitcast
120
121define i32 @test14(i32* %P, i8* %Ptr, i32* nocapture readonly %i) {
122entry:
123  %agg.tmp = alloca %class.bar, align 8
124  %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1
125  %y = load %class.base*, %class.base** %x, align 8
126  indirectbr i8* %Ptr, [label %BrBlock, label %B2, label %T]
127
128B2:
129  %b1 = bitcast %class.base* %y to void (%class.base*)***
130  store i32 4, i32 *%P
131  br label %BrBlock
132
133BrBlock:
134  %b2 = bitcast %class.base* %y to void (%class.base*)***
135  %L = load i32, i32* %P
136  %C = icmp eq i32 %L, 42
137  br i1 %C, label %T, label %F
138
139T:
140  %pi = load i32, i32* %i, align 4
141  ret i32 %pi
142F:
143  %pl = load i32, i32* %P
144  ret i32 %pl
145}
146
147
148; Check that the bitcast is not hoisted because of a cycle
149; due to indirect branches
150; CHECK-LABEL: @test16
151; CHECK-LABEL: B2:
152; CHECK-NEXT: bitcast
153; CHECK-LABEL: BrBlock:
154; CHECK-NEXT: bitcast
155
156define i32 @test16(i32* %P, i8* %Ptr, i32* nocapture readonly %i) {
157entry:
158  %agg.tmp = alloca %class.bar, align 8
159  %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1
160  %y = load %class.base*, %class.base** %x, align 8
161  indirectbr i8* %Ptr, [label %BrBlock, label %B2]
162
163B2:
164  %b1 = bitcast %class.base* %y to void (%class.base*)***
165  %0 = load i32, i32* %i, align 4
166  store i32 %0, i32 *%P
167  br label %BrBlock
168
169BrBlock:
170  %b2 = bitcast %class.base* %y to void (%class.base*)***
171  %L = load i32, i32* %P
172  %C = icmp eq i32 %L, 42
173  br i1 %C, label %T, label %F
174
175T:
176  indirectbr i32* %P, [label %BrBlock, label %B2]
177
178F:
179  indirectbr i8* %Ptr, [label %BrBlock, label %B2]
180}
181
182
183@_ZTIi = external constant i8*
184
185; Check that an instruction is not hoisted out of landing pad (%lpad4)
186; Also within a landing pad no redundancies are removed by gvn-hoist,
187; however an instruction may be hoisted into a landing pad if
188; landing pad has direct branches (e.g., %lpad to %catch1, %catch)
189; This CFG has a cycle (%lpad -> %catch1 -> %lpad4 -> %lpad)
190
191; CHECK-LABEL: @foo2
192; Check that nothing gets hoisted out of %lpad
193; CHECK-LABEL: lpad:
194; CHECK: %bc1 = add i32 %0, 10
195; CHECK: %bc7 = add i32 %0, 10
196
197; Check that the add is hoisted
198; CHECK-LABEL: catch1:
199; CHECK-NEXT: invoke
200
201; Check that the add is hoisted
202; CHECK-LABEL: catch:
203; CHECK-NEXT: load
204
205; Check that other adds are not hoisted
206; CHECK-LABEL: lpad4:
207; CHECK: %bc5 = add i32 %0, 10
208; CHECK-LABEL: unreachable:
209; CHECK: %bc2 = add i32 %0, 10
210
211; Function Attrs: noinline uwtable
212define i32 @foo2(i32* nocapture readonly %i) local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
213entry:
214  %0 = load i32, i32* %i, align 4
215  %cmp = icmp eq i32 %0, 0
216  br i1 %cmp, label %try.cont, label %if.then
217
218if.then:
219  %exception = tail call i8* @__cxa_allocate_exception(i64 4) #2
220  %1 = bitcast i8* %exception to i32*
221  store i32 %0, i32* %1, align 16
222  invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3
223          to label %unreachable unwind label %lpad
224
225lpad:
226  %2 = landingpad { i8*, i32 }
227          catch i8* bitcast (i8** @_ZTIi to i8*)
228          catch i8* null
229  %bc1 = add i32 %0, 10
230  %3 = extractvalue { i8*, i32 } %2, 0
231  %4 = extractvalue { i8*, i32 } %2, 1
232  %5 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2
233  %matches = icmp eq i32 %4, %5
234  %bc7 = add i32 %0, 10
235  %6 = tail call i8* @__cxa_begin_catch(i8* %3) #2
236  br i1 %matches, label %catch1, label %catch
237
238catch1:
239  %bc3 = add i32 %0, 10
240  invoke void @__cxa_rethrow() #3
241          to label %unreachable unwind label %lpad4
242
243catch:
244  %bc4 = add i32 %0, 10
245  %7 = load i32, i32* %i, align 4
246  %add = add nsw i32 %7, 1
247  tail call void @__cxa_end_catch()
248  br label %try.cont
249
250lpad4:
251  %8 = landingpad { i8*, i32 }
252          cleanup
253  %bc5 = add i32 %0, 10
254  tail call void @__cxa_end_catch() #2
255  invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3
256          to label %unreachable unwind label %lpad
257
258try.cont:
259  %k.0 = phi i32 [ %add, %catch ], [ 0, %entry ]
260  %bc6 = add i32 %0, 10
261  ret i32 %k.0
262
263unreachable:
264  %bc2 = add i32 %0, 10
265  ret i32 %bc2
266}
267
268declare i8* @__cxa_allocate_exception(i64) local_unnamed_addr
269
270declare void @__cxa_throw(i8*, i8*, i8*) local_unnamed_addr
271
272declare i32 @__gxx_personality_v0(...)
273
274; Function Attrs: nounwind readnone
275declare i32 @llvm.eh.typeid.for(i8*) #1
276
277declare i8* @__cxa_begin_catch(i8*) local_unnamed_addr
278
279declare void @__cxa_end_catch() local_unnamed_addr
280
281declare void @__cxa_rethrow() local_unnamed_addr
282
283attributes #1 = { nounwind readnone }
284attributes #2 = { nounwind }
285attributes #3 = { noreturn }
286