1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -S -passes=jump-threading < %s | FileCheck %s
4 %class.E = type { ptr, %class.C }
5 %class.C = type { %class.A }
6 %class.A = type { i32 }
7 %class.D = type { %class.F }
8 %class.F = type { %class.E }
9 %class.B = type { ptr }
11 @_ZTV1D = unnamed_addr constant [3 x ptr] [ptr null, ptr @_ZTI1D, ptr @_ZN1D7doApplyEv]
12 @_ZTI1D = external unnamed_addr constant { ptr, ptr, ptr }
14 define void @_ZN15EditCommandImpl5applyEv(ptr %this) uwtable align 2 {
15 ; CHECK-LABEL: @_ZN15EditCommandImpl5applyEv(
17 ; CHECK-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[THIS:%.*]], align 8
18 ; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VTABLE]], align 8
19 ; CHECK-NEXT: call void [[TMP0]](ptr [[THIS]])
20 ; CHECK-NEXT: ret void
23 %vtable = load ptr, ptr %this, align 8
24 %0 = load ptr, ptr %vtable, align 8
25 call void %0(ptr %this)
29 define void @_ZN1DC1Ev(ptr nocapture %this) unnamed_addr uwtable align 2 {
30 ; CHECK-LABEL: @_ZN1DC1Ev(
32 ; CHECK-NEXT: call void @_ZN24CompositeEditCommandImplC2Ev()
33 ; CHECK-NEXT: store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr [[THIS:%.*]], align 8
34 ; CHECK-NEXT: ret void
37 call void @_ZN24CompositeEditCommandImplC2Ev()
38 store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr %this, align 8
42 define void @_ZN1DC2Ev(ptr nocapture %this) unnamed_addr uwtable align 2 {
43 ; CHECK-LABEL: @_ZN1DC2Ev(
45 ; CHECK-NEXT: call void @_ZN24CompositeEditCommandImplC2Ev()
46 ; CHECK-NEXT: store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr [[THIS:%.*]], align 8
47 ; CHECK-NEXT: ret void
50 call void @_ZN24CompositeEditCommandImplC2Ev()
51 store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr %this, align 8
55 declare void @_ZN24CompositeEditCommandImplC2Ev() #1
57 define void @_ZN1D7doApplyEv(ptr nocapture %this) unnamed_addr nounwind readnone uwtable align 2 {
58 ; CHECK-LABEL: @_ZN1D7doApplyEv(
60 ; CHECK-NEXT: ret void
66 define void @_Z3fn1v() uwtable personality ptr @__gxx_personality_v0 {
67 ; CHECK-LABEL: @_Z3fn1v(
69 ; CHECK-NEXT: [[CALL:%.*]] = call noalias ptr @_Znwm()
70 ; CHECK-NEXT: invoke void @_ZN24CompositeEditCommandImplC2Ev()
71 ; CHECK-NEXT: to label [[_ZN1DC1EV_EXIT:%.*]] unwind label [[LPAD:%.*]]
72 ; CHECK: _ZN1DC1Ev.exit:
73 ; CHECK-NEXT: store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr [[CALL]], align 8
74 ; CHECK-NEXT: [[_REF_I_I_I:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8
75 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[_REF_I_I_I]], align 4
76 ; CHECK-NEXT: [[INC_I_I_I:%.*]] = add nsw i32 [[TMP0]], 1
77 ; CHECK-NEXT: store i32 [[INC_I_I_I]], ptr [[_REF_I_I_I]], align 4
78 ; CHECK-NEXT: invoke void @_ZN1D7doApplyEv(ptr [[CALL]])
79 ; CHECK-NEXT: to label [[_ZN15EDITCOMMANDIMPL5APPLYEV_EXIT:%.*]] unwind label [[LPAD1:%.*]]
80 ; CHECK: _ZN15EditCommandImpl5applyEv.exit:
81 ; CHECK-NEXT: invoke void @_ZN1D16deleteKeyPressedEv()
82 ; CHECK-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD1]]
83 ; CHECK: invoke.cont7:
84 ; CHECK-NEXT: ret void
86 ; CHECK-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 }
88 ; CHECK-NEXT: call void @_ZdlPv()
89 ; CHECK-NEXT: unreachable
91 ; CHECK-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 }
93 ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[_REF_I_I_I]], align 4
94 ; CHECK-NEXT: [[TOBOOL_I_I_I:%.*]] = icmp eq i32 [[TMP3]], 0
95 ; CHECK-NEXT: br i1 [[TOBOOL_I_I_I]], label [[_ZN1BI1DED1EV_EXIT:%.*]], label [[DELETE_NOTNULL_I_I_I:%.*]]
96 ; CHECK: delete.notnull.i.i.i:
97 ; CHECK-NEXT: call void @_ZdlPv()
98 ; CHECK-NEXT: unreachable
99 ; CHECK: _ZN1BI1DED1Ev.exit:
100 ; CHECK-NEXT: resume { ptr, i32 } undef
101 ; CHECK: terminate.lpad:
102 ; CHECK-NEXT: [[TMP4:%.*]] = landingpad { ptr, i32 }
103 ; CHECK-NEXT: catch ptr null
104 ; CHECK-NEXT: unreachable
107 %call = call noalias ptr @_Znwm() #8
108 invoke void @_ZN24CompositeEditCommandImplC2Ev()
109 to label %_ZN1DC1Ev.exit unwind label %lpad
111 _ZN1DC1Ev.exit: ; preds = %entry
112 store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr %call, align 8
113 %_ref.i.i.i = getelementptr inbounds i8, ptr %call, i64 8
114 %0 = load i32, ptr %_ref.i.i.i, align 4
115 %inc.i.i.i = add nsw i32 %0, 1
116 store i32 %inc.i.i.i, ptr %_ref.i.i.i, align 4
117 invoke void @_ZN1D7doApplyEv(ptr %call)
118 to label %_ZN15EditCommandImpl5applyEv.exit unwind label %lpad1
120 _ZN15EditCommandImpl5applyEv.exit: ; preds = %_ZN1DC1Ev.exit
121 invoke void @_ZN1D16deleteKeyPressedEv()
122 to label %invoke.cont7 unwind label %lpad1
124 invoke.cont7: ; preds = %_ZN15EditCommandImpl5applyEv.exit
127 lpad: ; preds = %entry
128 %1 = landingpad { ptr, i32 }
130 call void @_ZdlPv() #9
133 lpad1: ; preds = %_ZN1DC1Ev.exit, %_ZN15EditCommandImpl5applyEv.exit
134 %2 = landingpad { ptr, i32 }
136 %3 = load i32, ptr %_ref.i.i.i, align 4
137 %tobool.i.i.i = icmp eq i32 %3, 0
138 br i1 %tobool.i.i.i, label %_ZN1BI1DED1Ev.exit, label %if.then.i.i.i
140 if.then.i.i.i: ; preds = %lpad1
141 br i1 undef, label %_ZN1BI1DED1Ev.exit, label %delete.notnull.i.i.i
143 delete.notnull.i.i.i: ; preds = %if.then.i.i.i
144 call void @_ZdlPv() #9
147 _ZN1BI1DED1Ev.exit: ; preds = %lpad1, %if.then.i.i.i
148 resume { ptr, i32 } undef
150 terminate.lpad: ; No predecessors!
151 %4 = landingpad { ptr, i32 }
156 define void @_ZN1BI1DEC1EPS0_(ptr nocapture %this, ptr %p1) unnamed_addr uwtable align 2 {
157 ; CHECK-LABEL: @_ZN1BI1DEC1EPS0_(
159 ; CHECK-NEXT: store ptr [[P1:%.*]], ptr [[THIS:%.*]], align 8
160 ; CHECK-NEXT: [[_REF_I_I:%.*]] = getelementptr inbounds [[CLASS_D:%.*]], ptr [[P1]], i64 0, i32 0, i32 0, i32 1, i32 0, i32 0
161 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[_REF_I_I]], align 4
162 ; CHECK-NEXT: [[INC_I_I:%.*]] = add nsw i32 [[TMP0]], 1
163 ; CHECK-NEXT: store i32 [[INC_I_I]], ptr [[_REF_I_I]], align 4
164 ; CHECK-NEXT: ret void
167 store ptr %p1, ptr %this, align 8
168 %_ref.i.i = getelementptr inbounds %class.D, ptr %p1, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0
169 %0 = load i32, ptr %_ref.i.i, align 4
170 %inc.i.i = add nsw i32 %0, 1
171 store i32 %inc.i.i, ptr %_ref.i.i, align 4
175 declare noalias ptr @_Znwm()
177 declare i32 @__gxx_personality_v0(...)
179 declare void @_ZdlPv()
181 define ptr @_ZN1BI1DEptEv(ptr nocapture readonly %this) nounwind readonly uwtable align 2 {
182 ; CHECK-LABEL: @_ZN1BI1DEptEv(
184 ; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS:%.*]], align 8
185 ; CHECK-NEXT: ret ptr [[TMP0]]
188 %0 = load ptr, ptr %this, align 8
192 declare void @_ZN1D16deleteKeyPressedEv()
194 define void @_ZN1BI1DED1Ev(ptr nocapture readonly %this) unnamed_addr uwtable align 2 {
195 ; CHECK-LABEL: @_ZN1BI1DED1Ev(
197 ; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS:%.*]], align 8
198 ; CHECK-NEXT: [[_REF_I_I:%.*]] = getelementptr inbounds [[CLASS_D:%.*]], ptr [[TMP0]], i64 0, i32 0, i32 0, i32 1, i32 0, i32 0
199 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[_REF_I_I]], align 4
200 ; CHECK-NEXT: [[TOBOOL_I_I:%.*]] = icmp eq i32 [[TMP1]], 0
201 ; CHECK-NEXT: br i1 [[TOBOOL_I_I]], label [[_ZN1BI1DED2EV_EXIT:%.*]], label [[DELETE_NOTNULL_I_I:%.*]]
202 ; CHECK: delete.notnull.i.i:
203 ; CHECK-NEXT: call void @_ZdlPv()
204 ; CHECK-NEXT: unreachable
205 ; CHECK: _ZN1BI1DED2Ev.exit:
206 ; CHECK-NEXT: ret void
209 %0 = load ptr, ptr %this, align 8
210 %_ref.i.i = getelementptr inbounds %class.D, ptr %0, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0
211 %1 = load i32, ptr %_ref.i.i, align 4
212 %tobool.i.i = icmp eq i32 %1, 0
213 br i1 %tobool.i.i, label %_ZN1BI1DED2Ev.exit, label %if.then.i.i
215 if.then.i.i: ; preds = %entry
216 br i1 undef, label %_ZN1BI1DED2Ev.exit, label %delete.notnull.i.i
218 delete.notnull.i.i: ; preds = %if.then.i.i
219 call void @_ZdlPv() #9
222 _ZN1BI1DED2Ev.exit: ; preds = %entry, %if.then.i.i
226 declare hidden void @__clang_call_terminate()
228 define void @_ZN1BI1DED2Ev(ptr nocapture readonly %this) unnamed_addr uwtable align 2 {
229 ; CHECK-LABEL: @_ZN1BI1DED2Ev(
231 ; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS:%.*]], align 8
232 ; CHECK-NEXT: [[_REF_I:%.*]] = getelementptr inbounds [[CLASS_D:%.*]], ptr [[TMP0]], i64 0, i32 0, i32 0, i32 1, i32 0, i32 0
233 ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[_REF_I]], align 4
234 ; CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp eq i32 [[TMP1]], 0
235 ; CHECK-NEXT: br i1 [[TOBOOL_I]], label [[_ZN1AI1CE5DEREFEV_EXIT:%.*]], label [[DELETE_NOTNULL_I:%.*]]
236 ; CHECK: delete.notnull.i:
237 ; CHECK-NEXT: call void @_ZdlPv()
238 ; CHECK-NEXT: unreachable
239 ; CHECK: _ZN1AI1CE5derefEv.exit:
240 ; CHECK-NEXT: ret void
243 %0 = load ptr, ptr %this, align 8
244 %_ref.i = getelementptr inbounds %class.D, ptr %0, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0
245 %1 = load i32, ptr %_ref.i, align 4
246 %tobool.i = icmp eq i32 %1, 0
247 br i1 %tobool.i, label %_ZN1AI1CE5derefEv.exit, label %if.then.i
249 if.then.i: ; preds = %entry
250 br i1 undef, label %_ZN1AI1CE5derefEv.exit, label %delete.notnull.i
252 delete.notnull.i: ; preds = %if.then.i
253 call void @_ZdlPv() #9
256 _ZN1AI1CE5derefEv.exit: ; preds = %entry, %if.then.i
260 define void @_ZN1AI1CE5derefEv(ptr nocapture readonly %this) nounwind uwtable align 2 {
261 ; CHECK-LABEL: @_ZN1AI1CE5derefEv(
263 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[THIS:%.*]], align 4
264 ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
265 ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[DELETE_NOTNULL:%.*]]
266 ; CHECK: delete.notnull:
267 ; CHECK-NEXT: call void @_ZdlPv()
268 ; CHECK-NEXT: unreachable
270 ; CHECK-NEXT: ret void
273 %0 = load i32, ptr %this, align 4
274 %tobool = icmp eq i32 %0, 0
275 br i1 %tobool, label %if.end, label %if.then
277 if.then: ; preds = %entry
278 br i1 undef, label %if.end, label %delete.notnull
280 delete.notnull: ; preds = %if.then
281 call void @_ZdlPv() #9
284 if.end: ; preds = %entry, %if.then
288 define void @_ZN1BI1DEC2EPS0_(ptr nocapture %this, ptr %p1) unnamed_addr uwtable align 2 {
289 ; CHECK-LABEL: @_ZN1BI1DEC2EPS0_(
291 ; CHECK-NEXT: store ptr [[P1:%.*]], ptr [[THIS:%.*]], align 8
292 ; CHECK-NEXT: [[_REF_I:%.*]] = getelementptr inbounds [[CLASS_D:%.*]], ptr [[P1]], i64 0, i32 0, i32 0, i32 1, i32 0, i32 0
293 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[_REF_I]], align 4
294 ; CHECK-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP0]], 1
295 ; CHECK-NEXT: store i32 [[INC_I]], ptr [[_REF_I]], align 4
296 ; CHECK-NEXT: ret void
299 store ptr %p1, ptr %this, align 8
300 %_ref.i = getelementptr inbounds %class.D, ptr %p1, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0
301 %0 = load i32, ptr %_ref.i, align 4
302 %inc.i = add nsw i32 %0, 1
303 store i32 %inc.i, ptr %_ref.i, align 4
307 define void @_ZN1AI1CE3refEv(ptr nocapture %this) nounwind uwtable align 2 {
308 ; CHECK-LABEL: @_ZN1AI1CE3refEv(
310 ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[THIS:%.*]], align 4
311 ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 1
312 ; CHECK-NEXT: store i32 [[INC]], ptr [[THIS]], align 4
313 ; CHECK-NEXT: ret void
316 %0 = load i32, ptr %this, align 4
317 %inc = add nsw i32 %0, 1
318 store i32 %inc, ptr %this, align 4