| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py | |
| ; RUN: opt -S -passes=jump-threading < %s | FileCheck %s | |
| %class.E = type { ptr, %class.C } | |
| %class.C = type { %class.A } | |
| %class.A = type { i32 } | |
| %class.D = type { %class.F } | |
| %class.F = type { %class.E } | |
| %class.B = type { ptr } | |
| @_ZTV1D = unnamed_addr constant [3 x ptr] [ptr null, ptr @_ZTI1D, ptr @_ZN1D7doApplyEv] | |
| @_ZTI1D = external unnamed_addr constant { ptr, ptr, ptr } | |
| define void @_ZN15EditCommandImpl5applyEv(ptr %this) uwtable align 2 { | |
| ; CHECK-LABEL: @_ZN15EditCommandImpl5applyEv( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[THIS:%.*]], align 8 | |
| ; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VTABLE]], align 8 | |
| ; CHECK-NEXT: call void [[TMP0]](ptr [[THIS]]) | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %vtable = load ptr, ptr %this, align 8 | |
| %0 = load ptr, ptr %vtable, align 8 | |
| call void %0(ptr %this) | |
| ret void | |
| } | |
| define void @_ZN1DC1Ev(ptr nocapture %this) unnamed_addr uwtable align 2 { | |
| ; CHECK-LABEL: @_ZN1DC1Ev( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: call void @_ZN24CompositeEditCommandImplC2Ev() | |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr [[THIS:%.*]], align 8 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| call void @_ZN24CompositeEditCommandImplC2Ev() | |
| store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr %this, align 8 | |
| ret void | |
| } | |
| define void @_ZN1DC2Ev(ptr nocapture %this) unnamed_addr uwtable align 2 { | |
| ; CHECK-LABEL: @_ZN1DC2Ev( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: call void @_ZN24CompositeEditCommandImplC2Ev() | |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr [[THIS:%.*]], align 8 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| call void @_ZN24CompositeEditCommandImplC2Ev() | |
| store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr %this, align 8 | |
| ret void | |
| } | |
| declare void @_ZN24CompositeEditCommandImplC2Ev() #1 | |
| define void @_ZN1D7doApplyEv(ptr nocapture %this) unnamed_addr nounwind readnone uwtable align 2 { | |
| ; CHECK-LABEL: @_ZN1D7doApplyEv( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| ret void | |
| } | |
| define void @_Z3fn1v(i1 %arg) uwtable personality ptr @__gxx_personality_v0 { | |
| ; CHECK-LABEL: @_Z3fn1v( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[CALL:%.*]] = call noalias ptr @_Znwm() | |
| ; CHECK-NEXT: invoke void @_ZN24CompositeEditCommandImplC2Ev() | |
| ; CHECK-NEXT: to label [[_ZN1DC1EV_EXIT:%.*]] unwind label [[LPAD:%.*]] | |
| ; CHECK: _ZN1DC1Ev.exit: | |
| ; CHECK-NEXT: store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr [[CALL]], align 8 | |
| ; CHECK-NEXT: [[_REF_I_I_I:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i64 8 | |
| ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[_REF_I_I_I]], align 4 | |
| ; CHECK-NEXT: [[INC_I_I_I:%.*]] = add nsw i32 [[TMP0]], 1 | |
| ; CHECK-NEXT: store i32 [[INC_I_I_I]], ptr [[_REF_I_I_I]], align 4 | |
| ; CHECK-NEXT: invoke void @_ZN1D7doApplyEv(ptr [[CALL]]) | |
| ; CHECK-NEXT: to label [[_ZN15EDITCOMMANDIMPL5APPLYEV_EXIT:%.*]] unwind label [[LPAD1:%.*]] | |
| ; CHECK: _ZN15EditCommandImpl5applyEv.exit: | |
| ; CHECK-NEXT: invoke void @_ZN1D16deleteKeyPressedEv() | |
| ; CHECK-NEXT: to label [[INVOKE_CONT7:%.*]] unwind label [[LPAD1]] | |
| ; CHECK: invoke.cont7: | |
| ; CHECK-NEXT: ret void | |
| ; CHECK: lpad: | |
| ; CHECK-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 } | |
| ; CHECK-NEXT: cleanup | |
| ; CHECK-NEXT: call void @_ZdlPv() | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: lpad1: | |
| ; CHECK-NEXT: [[TMP2:%.*]] = landingpad { ptr, i32 } | |
| ; CHECK-NEXT: cleanup | |
| ; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[_REF_I_I_I]], align 4 | |
| ; CHECK-NEXT: [[TOBOOL_I_I_I:%.*]] = icmp eq i32 [[TMP3]], 0 | |
| ; CHECK-NEXT: br i1 [[TOBOOL_I_I_I]], label [[_ZN1BI1DED1EV_EXIT:%.*]], label [[DELETE_NOTNULL_I_I_I:%.*]] | |
| ; CHECK: if.then.i.i.i: | |
| ; CHECK-NEXT: br i1 [[ARG:%.*]], label [[_ZN1BI1DED1EV_EXIT]], label [[DELETE_NOTNULL_I_I_I1:%.*]] | |
| ; CHECK: delete.notnull.i.i.i: | |
| ; CHECK-NEXT: call void @_ZdlPv() | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: _ZN1BI1DED1Ev.exit: | |
| ; CHECK-NEXT: resume { ptr, i32 } undef | |
| ; CHECK: terminate.lpad: | |
| ; CHECK-NEXT: [[TMP4:%.*]] = landingpad { ptr, i32 } | |
| ; CHECK-NEXT: catch ptr null | |
| ; CHECK-NEXT: unreachable | |
| ; | |
| entry: | |
| %call = call noalias ptr @_Znwm() #8 | |
| invoke void @_ZN24CompositeEditCommandImplC2Ev() | |
| to label %_ZN1DC1Ev.exit unwind label %lpad | |
| _ZN1DC1Ev.exit: ; preds = %entry | |
| store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1D, i64 0, i64 2), ptr %call, align 8 | |
| %_ref.i.i.i = getelementptr inbounds i8, ptr %call, i64 8 | |
| %0 = load i32, ptr %_ref.i.i.i, align 4 | |
| %inc.i.i.i = add nsw i32 %0, 1 | |
| store i32 %inc.i.i.i, ptr %_ref.i.i.i, align 4 | |
| invoke void @_ZN1D7doApplyEv(ptr %call) | |
| to label %_ZN15EditCommandImpl5applyEv.exit unwind label %lpad1 | |
| _ZN15EditCommandImpl5applyEv.exit: ; preds = %_ZN1DC1Ev.exit | |
| invoke void @_ZN1D16deleteKeyPressedEv() | |
| to label %invoke.cont7 unwind label %lpad1 | |
| invoke.cont7: ; preds = %_ZN15EditCommandImpl5applyEv.exit | |
| ret void | |
| lpad: ; preds = %entry | |
| %1 = landingpad { ptr, i32 } | |
| cleanup | |
| call void @_ZdlPv() #9 | |
| unreachable | |
| lpad1: ; preds = %_ZN1DC1Ev.exit, %_ZN15EditCommandImpl5applyEv.exit | |
| %2 = landingpad { ptr, i32 } | |
| cleanup | |
| %3 = load i32, ptr %_ref.i.i.i, align 4 | |
| %tobool.i.i.i = icmp eq i32 %3, 0 | |
| br i1 %tobool.i.i.i, label %_ZN1BI1DED1Ev.exit, label %if.then.i.i.i | |
| if.then.i.i.i: ; preds = %lpad1 | |
| br i1 %arg, label %_ZN1BI1DED1Ev.exit, label %delete.notnull.i.i.i | |
| delete.notnull.i.i.i: ; preds = %if.then.i.i.i | |
| call void @_ZdlPv() #9 | |
| unreachable | |
| _ZN1BI1DED1Ev.exit: ; preds = %lpad1, %if.then.i.i.i | |
| resume { ptr, i32 } undef | |
| terminate.lpad: ; No predecessors! | |
| %4 = landingpad { ptr, i32 } | |
| catch ptr null | |
| unreachable | |
| } | |
| define void @_ZN1BI1DEC1EPS0_(ptr nocapture %this, ptr %p1) unnamed_addr uwtable align 2 { | |
| ; CHECK-LABEL: @_ZN1BI1DEC1EPS0_( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: store ptr [[P1:%.*]], ptr [[THIS:%.*]], align 8 | |
| ; CHECK-NEXT: [[_REF_I_I:%.*]] = getelementptr inbounds [[CLASS_D:%.*]], ptr [[P1]], i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 | |
| ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[_REF_I_I]], align 4 | |
| ; CHECK-NEXT: [[INC_I_I:%.*]] = add nsw i32 [[TMP0]], 1 | |
| ; CHECK-NEXT: store i32 [[INC_I_I]], ptr [[_REF_I_I]], align 4 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| store ptr %p1, ptr %this, align 8 | |
| %_ref.i.i = getelementptr inbounds %class.D, ptr %p1, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 | |
| %0 = load i32, ptr %_ref.i.i, align 4 | |
| %inc.i.i = add nsw i32 %0, 1 | |
| store i32 %inc.i.i, ptr %_ref.i.i, align 4 | |
| ret void | |
| } | |
| declare noalias ptr @_Znwm() | |
| declare i32 @__gxx_personality_v0(...) | |
| declare void @_ZdlPv() | |
| define ptr @_ZN1BI1DEptEv(ptr nocapture readonly %this) nounwind readonly uwtable align 2 { | |
| ; CHECK-LABEL: @_ZN1BI1DEptEv( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS:%.*]], align 8 | |
| ; CHECK-NEXT: ret ptr [[TMP0]] | |
| ; | |
| entry: | |
| %0 = load ptr, ptr %this, align 8 | |
| ret ptr %0 | |
| } | |
| declare void @_ZN1D16deleteKeyPressedEv() | |
| define void @_ZN1BI1DED1Ev(ptr nocapture readonly %this, i1 %arg) unnamed_addr uwtable align 2 { | |
| ; CHECK-LABEL: @_ZN1BI1DED1Ev( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS:%.*]], align 8 | |
| ; CHECK-NEXT: [[_REF_I_I:%.*]] = getelementptr inbounds [[CLASS_D:%.*]], ptr [[TMP0]], i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 | |
| ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[_REF_I_I]], align 4 | |
| ; CHECK-NEXT: [[TOBOOL_I_I:%.*]] = icmp eq i32 [[TMP1]], 0 | |
| ; CHECK-NEXT: br i1 [[TOBOOL_I_I]], label [[_ZN1BI1DED2EV_EXIT:%.*]], label [[DELETE_NOTNULL_I_I:%.*]] | |
| ; CHECK: if.then.i.i: | |
| ; CHECK-NEXT: br i1 [[ARG:%.*]], label [[_ZN1BI1DED2EV_EXIT]], label [[DELETE_NOTNULL_I_I1:%.*]] | |
| ; CHECK: delete.notnull.i.i: | |
| ; CHECK-NEXT: call void @_ZdlPv() | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: _ZN1BI1DED2Ev.exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %0 = load ptr, ptr %this, align 8 | |
| %_ref.i.i = getelementptr inbounds %class.D, ptr %0, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 | |
| %1 = load i32, ptr %_ref.i.i, align 4 | |
| %tobool.i.i = icmp eq i32 %1, 0 | |
| br i1 %tobool.i.i, label %_ZN1BI1DED2Ev.exit, label %if.then.i.i | |
| if.then.i.i: ; preds = %entry | |
| br i1 %arg, label %_ZN1BI1DED2Ev.exit, label %delete.notnull.i.i | |
| delete.notnull.i.i: ; preds = %if.then.i.i | |
| call void @_ZdlPv() #9 | |
| unreachable | |
| _ZN1BI1DED2Ev.exit: ; preds = %entry, %if.then.i.i | |
| ret void | |
| } | |
| declare hidden void @__clang_call_terminate() | |
| define void @_ZN1BI1DED2Ev(ptr nocapture readonly %this, i1 %arg) unnamed_addr uwtable align 2 { | |
| ; CHECK-LABEL: @_ZN1BI1DED2Ev( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[THIS:%.*]], align 8 | |
| ; CHECK-NEXT: [[_REF_I:%.*]] = getelementptr inbounds [[CLASS_D:%.*]], ptr [[TMP0]], i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 | |
| ; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[_REF_I]], align 4 | |
| ; CHECK-NEXT: [[TOBOOL_I:%.*]] = icmp eq i32 [[TMP1]], 0 | |
| ; CHECK-NEXT: br i1 [[TOBOOL_I]], label [[_ZN1AI1CE5DEREFEV_EXIT:%.*]], label [[DELETE_NOTNULL_I:%.*]] | |
| ; CHECK: if.then.i: | |
| ; CHECK-NEXT: br i1 [[ARG:%.*]], label [[_ZN1AI1CE5DEREFEV_EXIT]], label [[DELETE_NOTNULL_I1:%.*]] | |
| ; CHECK: delete.notnull.i: | |
| ; CHECK-NEXT: call void @_ZdlPv() | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: _ZN1AI1CE5derefEv.exit: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %0 = load ptr, ptr %this, align 8 | |
| %_ref.i = getelementptr inbounds %class.D, ptr %0, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 | |
| %1 = load i32, ptr %_ref.i, align 4 | |
| %tobool.i = icmp eq i32 %1, 0 | |
| br i1 %tobool.i, label %_ZN1AI1CE5derefEv.exit, label %if.then.i | |
| if.then.i: ; preds = %entry | |
| br i1 %arg, label %_ZN1AI1CE5derefEv.exit, label %delete.notnull.i | |
| delete.notnull.i: ; preds = %if.then.i | |
| call void @_ZdlPv() #9 | |
| unreachable | |
| _ZN1AI1CE5derefEv.exit: ; preds = %entry, %if.then.i | |
| ret void | |
| } | |
| define void @_ZN1AI1CE5derefEv(ptr nocapture readonly %this, i1 %arg) nounwind uwtable align 2 { | |
| ; CHECK-LABEL: @_ZN1AI1CE5derefEv( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[THIS:%.*]], align 4 | |
| ; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 | |
| ; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[DELETE_NOTNULL:%.*]] | |
| ; CHECK: if.then: | |
| ; CHECK-NEXT: br i1 [[ARG:%.*]], label [[IF_END]], label [[DELETE_NOTNULL1:%.*]] | |
| ; CHECK: delete.notnull: | |
| ; CHECK-NEXT: call void @_ZdlPv() | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: if.end: | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %0 = load i32, ptr %this, align 4 | |
| %tobool = icmp eq i32 %0, 0 | |
| br i1 %tobool, label %if.end, label %if.then | |
| if.then: ; preds = %entry | |
| br i1 %arg, label %if.end, label %delete.notnull | |
| delete.notnull: ; preds = %if.then | |
| call void @_ZdlPv() #9 | |
| unreachable | |
| if.end: ; preds = %entry, %if.then | |
| ret void | |
| } | |
| define void @_ZN1BI1DEC2EPS0_(ptr nocapture %this, ptr %p1) unnamed_addr uwtable align 2 { | |
| ; CHECK-LABEL: @_ZN1BI1DEC2EPS0_( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: store ptr [[P1:%.*]], ptr [[THIS:%.*]], align 8 | |
| ; CHECK-NEXT: [[_REF_I:%.*]] = getelementptr inbounds [[CLASS_D:%.*]], ptr [[P1]], i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 | |
| ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[_REF_I]], align 4 | |
| ; CHECK-NEXT: [[INC_I:%.*]] = add nsw i32 [[TMP0]], 1 | |
| ; CHECK-NEXT: store i32 [[INC_I]], ptr [[_REF_I]], align 4 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| store ptr %p1, ptr %this, align 8 | |
| %_ref.i = getelementptr inbounds %class.D, ptr %p1, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 | |
| %0 = load i32, ptr %_ref.i, align 4 | |
| %inc.i = add nsw i32 %0, 1 | |
| store i32 %inc.i, ptr %_ref.i, align 4 | |
| ret void | |
| } | |
| define void @_ZN1AI1CE3refEv(ptr nocapture %this) nounwind uwtable align 2 { | |
| ; CHECK-LABEL: @_ZN1AI1CE3refEv( | |
| ; CHECK-NEXT: entry: | |
| ; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[THIS:%.*]], align 4 | |
| ; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 1 | |
| ; CHECK-NEXT: store i32 [[INC]], ptr [[THIS]], align 4 | |
| ; CHECK-NEXT: ret void | |
| ; | |
| entry: | |
| %0 = load i32, ptr %this, align 4 | |
| %inc = add nsw i32 %0, 1 | |
| store i32 %inc, ptr %this, align 4 | |
| ret void | |
| } |