1 ; RUN: opt -S -gvn-hoist < %s | FileCheck %s
3 ; Checking gvn-hoist in case of indirect branches.
5 ; Check that the bitcast is not hoisted because it is after an indirect call
7 ; CHECK-LABEL: l1.preheader:
12 %class.bar = type { i8*, %class.base* }
13 %class.base = type { i32 (...)** }
15 @bar = local_unnamed_addr global i32 ()* null, align 8
16 @bar1 = local_unnamed_addr global i32 ()* null, align 8
18 define i32 @foo(i32* nocapture readonly %i) {
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
28 l1.preheader: ; preds = %sw.default, %entry
29 %b1 = bitcast %class.base* %y to void (%class.base*)***
32 l1: ; 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*)***
38 sw.default: ; preds = %entry
39 %2 = load i32 ()*, i32 ()** @bar1, align 8
40 %call2 = tail call i32 %2()
41 br label %l1.preheader
45 ; Any instruction inside an infinite loop will not be hoisted because
46 ; there is no path to exit of the function.
49 ; CHECK-LABEL: l1.preheader:
54 define i32 @foo1(i32* nocapture readonly %i) {
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
64 l1.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
69 l1: ; 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()
76 sw.default: ; preds = %entry
77 %2 = load i32 ()*, i32 ()** @bar1, align 8
78 %call2 = tail call i32 %2()
79 br label %l1.preheader
82 ; Check that bitcast is hoisted even when one of them is partially redundant.
83 ; CHECK-LABEL: @test13
87 define i32 @test13(i32* %P, i8* %Ptr, i32* nocapture readonly %i) {
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]
95 %b1 = bitcast %class.base* %y to void (%class.base*)***
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
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.
115 ; CHECK-LABEL: @test14
117 ; CHECK-NEXT: bitcast
118 ; CHECK-LABEL: BrBlock:
119 ; CHECK-NEXT: bitcast
121 define i32 @test14(i32* %P, i8* %Ptr, i32* nocapture readonly %i) {
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]
129 %b1 = bitcast %class.base* %y to void (%class.base*)***
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
140 %pi = load i32, i32* %i, align 4
143 %pl = load i32, i32* %P
148 ; Check that the bitcast is not hoisted because of a cycle
149 ; due to indirect branches
150 ; CHECK-LABEL: @test16
152 ; CHECK-NEXT: bitcast
153 ; CHECK-LABEL: BrBlock:
154 ; CHECK-NEXT: bitcast
156 define i32 @test16(i32* %P, i8* %Ptr, i32* nocapture readonly %i) {
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]
164 %b1 = bitcast %class.base* %y to void (%class.base*)***
165 %0 = load i32, i32* %i, align 4
166 store i32 %0, i32 *%P
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
176 indirectbr i32* %P, [label %BrBlock, label %B2]
179 indirectbr i8* %Ptr, [label %BrBlock, label %B2]
183 @_ZTIi = external constant i8*
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)
192 ; Check that nothing gets hoisted out of %lpad
194 ; CHECK: %bc1 = add i32 %0, 10
195 ; CHECK: %bc7 = add i32 %0, 10
197 ; Check that the add is hoisted
198 ; CHECK-LABEL: catch1:
201 ; Check that the add is hoisted
202 ; CHECK-LABEL: catch:
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
211 ; Function Attrs: noinline uwtable
212 define i32 @foo2(i32* nocapture readonly %i) local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
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
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
226 %2 = landingpad { i8*, i32 }
227 catch i8* bitcast (i8** @_ZTIi to i8*)
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
239 %bc3 = add i32 %0, 10
240 invoke void @__cxa_rethrow() #3
241 to label %unreachable unwind label %lpad4
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()
251 %8 = landingpad { i8*, i32 }
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
259 %k.0 = phi i32 [ %add, %catch ], [ 0, %entry ]
260 %bc6 = add i32 %0, 10
264 %bc2 = add i32 %0, 10
268 declare i8* @__cxa_allocate_exception(i64) local_unnamed_addr
270 declare void @__cxa_throw(i8*, i8*, i8*) local_unnamed_addr
272 declare i32 @__gxx_personality_v0(...)
274 ; Function Attrs: nounwind readnone
275 declare i32 @llvm.eh.typeid.for(i8*) #1
277 declare i8* @__cxa_begin_catch(i8*) local_unnamed_addr
279 declare void @__cxa_end_catch() local_unnamed_addr
281 declare void @__cxa_rethrow() local_unnamed_addr
283 attributes #1 = { nounwind readnone }
284 attributes #2 = { nounwind }
285 attributes #3 = { noreturn }