diff options
Diffstat (limited to 'test/Transforms/JumpThreading')
| -rw-r--r-- | test/Transforms/JumpThreading/basic.ll | 30 | ||||
| -rw-r--r-- | test/Transforms/JumpThreading/indirectbr.ll | 2 | ||||
| -rw-r--r-- | test/Transforms/JumpThreading/landing-pad.ll | 203 | ||||
| -rw-r--r-- | test/Transforms/JumpThreading/lit.local.cfg | 1 | ||||
| -rw-r--r-- | test/Transforms/JumpThreading/select.ll | 71 | ||||
| -rw-r--r-- | test/Transforms/JumpThreading/thread-loads.ll | 8 |
6 files changed, 290 insertions, 25 deletions
diff --git a/test/Transforms/JumpThreading/basic.ll b/test/Transforms/JumpThreading/basic.ll index fe3dc77c9c13..32cc4de9285a 100644 --- a/test/Transforms/JumpThreading/basic.ll +++ b/test/Transforms/JumpThreading/basic.ll @@ -5,7 +5,7 @@ declare i32 @f2() declare void @f3() define i32 @test1(i1 %cond) { -; CHECK: @test1 +; CHECK-LABEL: @test1( br i1 %cond, label %T1, label %F1 @@ -37,7 +37,7 @@ F2: ;; cond is known false on Entry -> F1 edge! define i32 @test2(i1 %cond) { -; CHECK: @test2 +; CHECK-LABEL: @test2( Entry: br i1 %cond, label %T1, label %F1 @@ -62,7 +62,7 @@ F2: ; Undef handling. define i32 @test3(i1 %cond) { -; CHECK: @test3 +; CHECK-LABEL: @test3( ; CHECK-NEXT: T1: ; CHECK-NEXT: ret i32 42 br i1 undef, label %T1, label %F1 @@ -75,7 +75,7 @@ F1: } define i32 @test4(i1 %cond, i1 %cond2) { -; CHECK: @test4 +; CHECK-LABEL: @test4( br i1 %cond, label %T1, label %F1 @@ -108,7 +108,7 @@ F2: ;; This tests that the branch in 'merge' can be cloned up into T1. define i32 @test5(i1 %cond, i1 %cond2) { -; CHECK: @test5 +; CHECK-LABEL: @test5( br i1 %cond, label %T1, label %F1 @@ -144,7 +144,7 @@ F2: define i32 @test6(i32 %A) { -; CHECK: @test6 +; CHECK-LABEL: @test6( %tmp455 = icmp eq i32 %A, 42 br i1 %tmp455, label %BB1, label %BB2 @@ -180,7 +180,7 @@ BB4: ;; rdar://7367025 define i32 @test7(i1 %cond, i1 %cond2) { Entry: -; CHECK: @test7 +; CHECK-LABEL: @test7( %v1 = call i32 @f1() br i1 %cond, label %Merge, label %F1 @@ -213,7 +213,7 @@ F2: declare i1 @test8a() define i32 @test8b(i1 %cond, i1 %cond2) { -; CHECK: @test8b +; CHECK-LABEL: @test8b( T0: %A = call i1 @test8a() br i1 %A, label %T1, label %F1 @@ -255,7 +255,7 @@ Y: ;;; Verify that we can handle constraint propagation through "xor x, 1". define i32 @test9(i1 %cond, i1 %cond2) { Entry: -; CHECK: @test9 +; CHECK-LABEL: @test9( %v1 = call i32 @f1() br i1 %cond, label %Merge, label %F1 @@ -298,7 +298,7 @@ declare void @test10f3() ;; Non-local condition threading. define i32 @test10g(i1 %cond) { -; CHECK: @test10g +; CHECK-LABEL: @test10g( ; CHECK-NEXT: br i1 %cond, label %T2, label %F2 br i1 %cond, label %T1, label %F1 @@ -329,7 +329,7 @@ F2: ; Impossible conditional constraints should get threaded. BB3 is dead here. define i32 @test11(i32 %A) { -; CHECK: @test11 +; CHECK-LABEL: @test11( ; CHECK-NEXT: icmp ; CHECK-NEXT: br i1 %tmp455, label %BB4, label %BB2 %tmp455 = icmp eq i32 %A, 42 @@ -357,7 +357,7 @@ BB4: ;; Correlated value through boolean expression. GCC PR18046. define void @test12(i32 %A) { -; CHECK: @test12 +; CHECK-LABEL: @test12( entry: %cond = icmp eq i32 %A, 0 br i1 %cond, label %bb, label %bb1 @@ -393,7 +393,7 @@ return: ;; rdar://7391699 define i32 @test13(i1 %cond, i1 %cond2) { Entry: -; CHECK: @test13 +; CHECK-LABEL: @test13( %v1 = call i32 @f1() br i1 %cond, label %Merge, label %F1 @@ -421,7 +421,7 @@ F2: ; CHECK-NEXT: br i1 %N, label %T2, label %F2 } -; CHECK: @test14 +; CHECK-LABEL: @test14( define i32 @test14(i32 %in) { entry: %A = icmp eq i32 %in, 0 @@ -453,7 +453,7 @@ right_ret: } ; PR5652 -; CHECK: @test15 +; CHECK-LABEL: @test15( define i32 @test15(i32 %len) { entry: ; CHECK: icmp ult i32 %len, 13 diff --git a/test/Transforms/JumpThreading/indirectbr.ll b/test/Transforms/JumpThreading/indirectbr.ll index 141277fec626..b87fb6c22287 100644 --- a/test/Transforms/JumpThreading/indirectbr.ll +++ b/test/Transforms/JumpThreading/indirectbr.ll @@ -67,7 +67,7 @@ L2: ; preds = %indirectgoto ; Don't merge address-taken blocks. @.str = private unnamed_addr constant [4 x i8] c"%p\0A\00" -; CHECK: @test3 +; CHECK-LABEL: @test3( ; CHECK: __here: ; CHECK: blockaddress(@test3, %__here) ; CHECK: __here1: diff --git a/test/Transforms/JumpThreading/landing-pad.ll b/test/Transforms/JumpThreading/landing-pad.ll new file mode 100644 index 000000000000..9ee0526d0446 --- /dev/null +++ b/test/Transforms/JumpThreading/landing-pad.ll @@ -0,0 +1,203 @@ +; RUN: opt < %s -disable-output -jump-threading + +%class.E = type { i32 (...)**, %class.C } +%class.C = type { %class.A } +%class.A = type { i32 } +%class.D = type { %class.F } +%class.F = type { %class.E } +%class.B = type { %class.D* } + +@_ZTV1D = unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI1D to i8*), i8* bitcast (void (%class.D*)* @_ZN1D7doApplyEv to i8*)] +@_ZTI1D = external unnamed_addr constant { i8*, i8*, i8* } + +define void @_ZN15EditCommandImpl5applyEv(%class.E* %this) uwtable align 2 { +entry: + %0 = bitcast %class.E* %this to void (%class.E*)*** + %vtable = load void (%class.E*)*** %0, align 8 + %1 = load void (%class.E*)** %vtable, align 8 + call void %1(%class.E* %this) + ret void +} + +define void @_ZN1DC1Ev(%class.D* nocapture %this) unnamed_addr uwtable align 2 { +entry: + call void @_ZN24CompositeEditCommandImplC2Ev() + %0 = getelementptr inbounds %class.D* %this, i64 0, i32 0, i32 0, i32 0 + store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1D, i64 0, i64 2) to i32 (...)**), i32 (...)*** %0, align 8 + ret void +} + +define void @_ZN1DC2Ev(%class.D* nocapture %this) unnamed_addr uwtable align 2 { +entry: + call void @_ZN24CompositeEditCommandImplC2Ev() + %0 = getelementptr inbounds %class.D* %this, i64 0, i32 0, i32 0, i32 0 + store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1D, i64 0, i64 2) to i32 (...)**), i32 (...)*** %0, align 8 + ret void +} + +declare void @_ZN24CompositeEditCommandImplC2Ev() #1 + +define void @_ZN1D7doApplyEv(%class.D* nocapture %this) unnamed_addr nounwind readnone uwtable align 2 { +entry: + ret void +} + +define void @_Z3fn1v() uwtable { +entry: + %call = call noalias i8* @_Znwm() #8 + invoke void @_ZN24CompositeEditCommandImplC2Ev() + to label %_ZN1DC1Ev.exit unwind label %lpad + +_ZN1DC1Ev.exit: ; preds = %entry + %0 = bitcast i8* %call to i32 (...)*** + store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1D, i64 0, i64 2) to i32 (...)**), i32 (...)*** %0, align 8 + %_ref.i.i.i = getelementptr inbounds i8* %call, i64 8 + %1 = bitcast i8* %_ref.i.i.i to i32* + %2 = load i32* %1, align 4 + %inc.i.i.i = add nsw i32 %2, 1 + store i32 %inc.i.i.i, i32* %1, align 4 + %3 = bitcast i8* %call to %class.D* + invoke void @_ZN1D7doApplyEv(%class.D* %3) + 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 + %4 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + call void @_ZdlPv() #9 + unreachable + +lpad1: ; preds = %_ZN1DC1Ev.exit, %_ZN15EditCommandImpl5applyEv.exit + %5 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + cleanup + %6 = load i32* %1, align 4 + %tobool.i.i.i = icmp eq i32 %6, 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 undef, 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 { i8*, i32 } undef + +terminate.lpad: ; No predecessors! + %7 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* null + unreachable +} + +define void @_ZN1BI1DEC1EPS0_(%class.B* nocapture %this, %class.D* %p1) unnamed_addr uwtable align 2 { +entry: + %m_ptr.i = getelementptr inbounds %class.B* %this, i64 0, i32 0 + store %class.D* %p1, %class.D** %m_ptr.i, align 8 + %_ref.i.i = getelementptr inbounds %class.D* %p1, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 + %0 = load i32* %_ref.i.i, align 4 + %inc.i.i = add nsw i32 %0, 1 + store i32 %inc.i.i, i32* %_ref.i.i, align 4 + ret void +} + +declare noalias i8* @_Znwm() + +declare i32 @__gxx_personality_v0(...) + +declare void @_ZdlPv() + +define %class.D* @_ZN1BI1DEptEv(%class.B* nocapture readonly %this) nounwind readonly uwtable align 2 { +entry: + %m_ptr = getelementptr inbounds %class.B* %this, i64 0, i32 0 + %0 = load %class.D** %m_ptr, align 8 + ret %class.D* %0 +} + +declare void @_ZN1D16deleteKeyPressedEv() + +define void @_ZN1BI1DED1Ev(%class.B* nocapture readonly %this) unnamed_addr uwtable align 2 { +entry: + %m_ptr.i = getelementptr inbounds %class.B* %this, i64 0, i32 0 + %0 = load %class.D** %m_ptr.i, align 8 + %_ref.i.i = getelementptr inbounds %class.D* %0, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 + %1 = load i32* %_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 undef, 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(%class.B* nocapture readonly %this) unnamed_addr uwtable align 2 { +entry: + %m_ptr = getelementptr inbounds %class.B* %this, i64 0, i32 0 + %0 = load %class.D** %m_ptr, align 8 + %_ref.i = getelementptr inbounds %class.D* %0, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 + %1 = load i32* %_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 undef, 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(%class.A* nocapture readonly %this) nounwind uwtable align 2 { +entry: + %_ref = getelementptr inbounds %class.A* %this, i64 0, i32 0 + %0 = load i32* %_ref, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %if.end, label %if.then + +if.then: ; preds = %entry + br i1 undef, 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_(%class.B* nocapture %this, %class.D* %p1) unnamed_addr uwtable align 2 { +entry: + %m_ptr = getelementptr inbounds %class.B* %this, i64 0, i32 0 + store %class.D* %p1, %class.D** %m_ptr, align 8 + %_ref.i = getelementptr inbounds %class.D* %p1, i64 0, i32 0, i32 0, i32 1, i32 0, i32 0 + %0 = load i32* %_ref.i, align 4 + %inc.i = add nsw i32 %0, 1 + store i32 %inc.i, i32* %_ref.i, align 4 + ret void +} + +define void @_ZN1AI1CE3refEv(%class.A* nocapture %this) nounwind uwtable align 2 { +entry: + %_ref = getelementptr inbounds %class.A* %this, i64 0, i32 0 + %0 = load i32* %_ref, align 4 + %inc = add nsw i32 %0, 1 + store i32 %inc, i32* %_ref, align 4 + ret void +} diff --git a/test/Transforms/JumpThreading/lit.local.cfg b/test/Transforms/JumpThreading/lit.local.cfg deleted file mode 100644 index c6106e4746f2..000000000000 --- a/test/Transforms/JumpThreading/lit.local.cfg +++ /dev/null @@ -1 +0,0 @@ -config.suffixes = ['.ll'] diff --git a/test/Transforms/JumpThreading/select.ll b/test/Transforms/JumpThreading/select.ll index 9676efec9df2..201e604e0c5e 100644 --- a/test/Transforms/JumpThreading/select.ll +++ b/test/Transforms/JumpThreading/select.ll @@ -10,7 +10,7 @@ declare void @quux() ; Mostly theoretical since instruction combining simplifies all selects of ; booleans where at least one operand is true/false/undef. -; CHECK: @test_br +; CHECK-LABEL: @test_br( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 %cond, label %L1, define void @test_br(i1 %cond, i1 %value) nounwind { @@ -34,7 +34,7 @@ L3: ; Jump threading of switch with select as condition. -; CHECK: @test_switch +; CHECK-LABEL: @test_switch( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 %cond, label %L1, define void @test_switch(i1 %cond, i8 %value) nounwind { @@ -69,7 +69,7 @@ L4: ; Jump threading of indirectbr with select as address. -; CHECK: @test_indirectbr +; CHECK-LABEL: @test_indirectbr( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 %cond, label %L1, label %L3 define void @test_indirectbr(i1 %cond, i8* %address) nounwind { @@ -93,7 +93,7 @@ L3: ; A more complicated case: the condition is a select based on a comparison. -; CHECK: @test_switch_cmp +; CHECK-LABEL: @test_switch_cmp( ; CHECK-NEXT: entry: ; CHECK-NEXT: br i1 %cond, label %L0, label %[[THREADED:[A-Za-z.0-9]+]] ; CHECK: [[THREADED]]: @@ -157,3 +157,66 @@ L3: L4: ret void } + +define void @unfold1(double %x, double %y) nounwind { +entry: + %sub = fsub double %x, %y + %cmp = fcmp ogt double %sub, 1.000000e+01 + br i1 %cmp, label %cond.end4, label %cond.false + +cond.false: ; preds = %entry + %add = fadd double %x, %y + %cmp1 = fcmp ogt double %add, 1.000000e+01 + %add. = select i1 %cmp1, double %add, double 0.000000e+00 + br label %cond.end4 + +cond.end4: ; preds = %entry, %cond.false + %cond5 = phi double [ %add., %cond.false ], [ %sub, %entry ] + %cmp6 = fcmp oeq double %cond5, 0.000000e+00 + br i1 %cmp6, label %if.then, label %if.end + +if.then: ; preds = %cond.end4 + call void @foo() + br label %if.end + +if.end: ; preds = %if.then, %cond.end4 + ret void + +; CHECK-LABEL: @unfold1 +; CHECK: br i1 %cmp, label %cond.end4, label %cond.false +; CHECK: br i1 %cmp1, label %cond.end4, label %if.then +; CHECK: br i1 %cmp6, label %if.then, label %if.end +; CHECK: br label %if.end +} + + +define void @unfold2(i32 %x, i32 %y) nounwind { +entry: + %sub = sub nsw i32 %x, %y + %cmp = icmp sgt i32 %sub, 10 + br i1 %cmp, label %cond.end4, label %cond.false + +cond.false: ; preds = %entry + %add = add nsw i32 %x, %y + %cmp1 = icmp sgt i32 %add, 10 + %add. = select i1 %cmp1, i32 0, i32 %add + br label %cond.end4 + +cond.end4: ; preds = %entry, %cond.false + %cond5 = phi i32 [ %add., %cond.false ], [ %sub, %entry ] + %cmp6 = icmp eq i32 %cond5, 0 + br i1 %cmp6, label %if.then, label %if.end + +if.then: ; preds = %cond.end4 + call void @foo() + br label %if.end + +if.end: ; preds = %if.then, %cond.end4 + ret void + +; CHECK-LABEL: @unfold2 +; CHECK: br i1 %cmp, label %if.end, label %cond.false +; CHECK: br i1 %cmp1, label %if.then, label %cond.end4 +; CHECK: br i1 %cmp6, label %if.then, label %if.end +; CHECK: br label %if.end +} diff --git a/test/Transforms/JumpThreading/thread-loads.ll b/test/Transforms/JumpThreading/thread-loads.ll index 78d36e7053c9..e5bf64b9e256 100644 --- a/test/Transforms/JumpThreading/thread-loads.ll +++ b/test/Transforms/JumpThreading/thread-loads.ll @@ -6,7 +6,7 @@ target triple = "i386-apple-darwin7" ; Test that we can thread through the block with the partially redundant load (%2). ; rdar://6402033 define i32 @test1(i32* %P) nounwind { -; CHECK: @test1 +; CHECK-LABEL: @test1( entry: %0 = tail call i32 (...)* @f1() nounwind ; <i32> [#uses=1] %1 = icmp eq i32 %0, 0 ; <i1> [#uses=1] @@ -45,7 +45,7 @@ declare i32 @f2(...) ; rdar://11039258 define i32 @test2(i32* %P) nounwind { -; CHECK: @test2 +; CHECK-LABEL: @test2( entry: %0 = tail call i32 (...)* @f1() nounwind ; <i32> [#uses=1] %1 = icmp eq i32 %0, 0 ; <i1> [#uses=1] @@ -75,7 +75,7 @@ bb3: ; preds = %bb1 ret i32 %res.0 } -!0 = metadata !{metadata !"int", metadata !1} +!0 = metadata !{metadata !3, metadata !3, i64 0} !1 = metadata !{metadata !"omnipotent char", metadata !2} !2 = metadata !{metadata !"Simple C/C++ TBAA", null} - +!3 = metadata !{metadata !"int", metadata !1} |
