; RUN: opt < %s -basicaa -licm -S | FileCheck %s declare i32 @strlen(i8*) readonly declare void @foo() ; Sink readonly function. define i32 @test1(i8* %P) { br label %Loop Loop: ; preds = %Loop, %0 %A = call i32 @strlen( i8* %P ) readonly br i1 false, label %Loop, label %Out Out: ; preds = %Loop ret i32 %A ; CHECK-LABEL: @test1( ; CHECK: Out: ; CHECK-NEXT: call i32 @strlen ; CHECK-NEXT: ret i32 %A } declare double @sin(double) readnone ; Sink readnone function out of loop with unknown memory behavior. define double @test2(double %X) { br label %Loop Loop: ; preds = %Loop, %0 call void @foo( ) %A = call double @sin( double %X ) readnone br i1 true, label %Loop, label %Out Out: ; preds = %Loop ret double %A ; CHECK-LABEL: @test2( ; CHECK: Out: ; CHECK-NEXT: call double @sin ; CHECK-NEXT: ret double %A } ; This testcase checks to make sure the sinker does not cause problems with ; critical edges. define void @test3() { Entry: br i1 false, label %Loop, label %Exit Loop: %X = add i32 0, 1 br i1 false, label %Loop, label %Exit Exit: %Y = phi i32 [ 0, %Entry ], [ %X, %Loop ] ret void ; CHECK-LABEL: @test3( ; CHECK: Exit.loopexit: ; CHECK-NEXT: %X.le = add i32 0, 1 ; CHECK-NEXT: br label %Exit } ; If the result of an instruction is only used outside of the loop, sink ; the instruction to the exit blocks instead of executing it on every ; iteration of the loop. ; define i32 @test4(i32 %N) { Entry: br label %Loop Loop: ; preds = %Loop, %Entry %N_addr.0.pn = phi i32 [ %dec, %Loop ], [ %N, %Entry ] %tmp.6 = mul i32 %N, %N_addr.0.pn ; [#uses=1] %tmp.7 = sub i32 %tmp.6, %N ; [#uses=1] %dec = add i32 %N_addr.0.pn, -1 ; [#uses=1] %tmp.1 = icmp ne i32 %N_addr.0.pn, 1 ; [#uses=1] br i1 %tmp.1, label %Loop, label %Out Out: ; preds = %Loop ret i32 %tmp.7 ; CHECK-LABEL: @test4( ; CHECK: Out: ; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn ; CHECK-NEXT: mul i32 %N, %[[LCSSAPHI]] ; CHECK-NEXT: sub i32 %tmp.6.le, %N ; CHECK-NEXT: ret i32 } ; To reduce register pressure, if a load is hoistable out of the loop, and the ; result of the load is only used outside of the loop, sink the load instead of ; hoisting it! ; @X = global i32 5 ; [#uses=1] define i32 @test5(i32 %N) { Entry: br label %Loop Loop: ; preds = %Loop, %Entry %N_addr.0.pn = phi i32 [ %dec, %Loop ], [ %N, %Entry ] %tmp.6 = load i32* @X ; [#uses=1] %dec = add i32 %N_addr.0.pn, -1 ; [#uses=1] %tmp.1 = icmp ne i32 %N_addr.0.pn, 1 ; [#uses=1] br i1 %tmp.1, label %Loop, label %Out Out: ; preds = %Loop ret i32 %tmp.6 ; CHECK-LABEL: @test5( ; CHECK: Out: ; CHECK-NEXT: %tmp.6.le = load i32* @X ; CHECK-NEXT: ret i32 %tmp.6.le } ; The loop sinker was running from the bottom of the loop to the top, causing ; it to miss opportunities to sink instructions that depended on sinking other ; instructions from the loop. Instead they got hoisted, which is better than ; leaving them in the loop, but increases register pressure pointlessly. %Ty = type { i32, i32 } @X2 = external global %Ty define i32 @test6() { br label %Loop Loop: %dead = getelementptr %Ty* @X2, i64 0, i32 0 %sunk2 = load i32* %dead br i1 false, label %Loop, label %Out Out: ; preds = %Loop ret i32 %sunk2 ; CHECK-LABEL: @test6( ; CHECK: Out: ; CHECK-NEXT: %dead.le = getelementptr %Ty* @X2, i64 0, i32 0 ; CHECK-NEXT: %sunk2.le = load i32* %dead.le ; CHECK-NEXT: ret i32 %sunk2.le } ; This testcase ensures that we can sink instructions from loops with ; multiple exits. ; define i32 @test7(i32 %N, i1 %C) { Entry: br label %Loop Loop: ; preds = %ContLoop, %Entry %N_addr.0.pn = phi i32 [ %dec, %ContLoop ], [ %N, %Entry ] %tmp.6 = mul i32 %N, %N_addr.0.pn %tmp.7 = sub i32 %tmp.6, %N ; [#uses=2] %dec = add i32 %N_addr.0.pn, -1 ; [#uses=1] br i1 %C, label %ContLoop, label %Out1 ContLoop: %tmp.1 = icmp ne i32 %N_addr.0.pn, 1 br i1 %tmp.1, label %Loop, label %Out2 Out1: ; preds = %Loop ret i32 %tmp.7 Out2: ; preds = %ContLoop ret i32 %tmp.7 ; CHECK-LABEL: @test7( ; CHECK: Out1: ; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn ; CHECK-NEXT: mul i32 %N, %[[LCSSAPHI]] ; CHECK-NEXT: sub i32 %tmp.6.le, %N ; CHECK-NEXT: ret ; CHECK: Out2: ; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn ; CHECK-NEXT: mul i32 %N, %[[LCSSAPHI]] ; CHECK-NEXT: sub i32 %tmp.6.le4, %N ; CHECK-NEXT: ret } ; This testcase checks to make sure we can sink values which are only live on ; some exits out of the loop, and that we can do so without breaking dominator ; info. define i32 @test8(i1 %C1, i1 %C2, i32* %P, i32* %Q) { Entry: br label %Loop Loop: ; preds = %Cont, %Entry br i1 %C1, label %Cont, label %exit1 Cont: ; preds = %Loop %X = load i32* %P ; [#uses=2] store i32 %X, i32* %Q %V = add i32 %X, 1 ; [#uses=1] br i1 %C2, label %Loop, label %exit2 exit1: ; preds = %Loop ret i32 0 exit2: ; preds = %Cont ret i32 %V ; CHECK-LABEL: @test8( ; CHECK: exit1: ; CHECK-NEXT: ret i32 0 ; CHECK: exit2: ; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %X ; CHECK-NEXT: %V.le = add i32 %[[LCSSAPHI]], 1 ; CHECK-NEXT: ret i32 %V.le } define void @test9() { loopentry.2.i: br i1 false, label %no_exit.1.i.preheader, label %loopentry.3.i.preheader no_exit.1.i.preheader: ; preds = %loopentry.2.i br label %no_exit.1.i no_exit.1.i: ; preds = %endif.8.i, %no_exit.1.i.preheader br i1 false, label %return.i, label %endif.8.i endif.8.i: ; preds = %no_exit.1.i %inc.1.i = add i32 0, 1 ; [#uses=1] br i1 false, label %no_exit.1.i, label %loopentry.3.i.preheader.loopexit loopentry.3.i.preheader.loopexit: ; preds = %endif.8.i br label %loopentry.3.i.preheader loopentry.3.i.preheader: ; preds = %loopentry.3.i.preheader.loopexit, %loopentry.2.i %arg_num.0.i.ph13000 = phi i32 [ 0, %loopentry.2.i ], [ %inc.1.i, %loopentry.3.i.preheader.loopexit ] ; [#uses=0] ret void return.i: ; preds = %no_exit.1.i ret void ; CHECK-LABEL: @test9( ; CHECK: loopentry.3.i.preheader.loopexit: ; CHECK-NEXT: %inc.1.i.le = add i32 0, 1 ; CHECK-NEXT: br label %loopentry.3.i.preheader } ; Potentially trapping instructions may be sunk as long as they are guaranteed ; to be executed. define i32 @test10(i32 %N) { Entry: br label %Loop Loop: ; preds = %Loop, %Entry %N_addr.0.pn = phi i32 [ %dec, %Loop ], [ %N, %Entry ] ; [#uses=3] %tmp.6 = sdiv i32 %N, %N_addr.0.pn ; [#uses=1] %dec = add i32 %N_addr.0.pn, -1 ; [#uses=1] %tmp.1 = icmp ne i32 %N_addr.0.pn, 0 ; [#uses=1] br i1 %tmp.1, label %Loop, label %Out Out: ; preds = %Loop ret i32 %tmp.6 ; CHECK-LABEL: @test10( ; CHECK: Out: ; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn ; CHECK-NEXT: %tmp.6.le = sdiv i32 %N, %[[LCSSAPHI]] ; CHECK-NEXT: ret i32 %tmp.6.le } ; Should delete, not sink, dead instructions. define void @test11() { br label %Loop Loop: %dead = getelementptr %Ty* @X2, i64 0, i32 0 br i1 false, label %Loop, label %Out Out: ret void ; CHECK-LABEL: @test11( ; CHECK: Out: ; CHECK-NEXT: ret void } @c = common global [1 x i32] zeroinitializer, align 4 ; Test a *many* way nested loop with multiple exit blocks both of which exit ; multiple loop nests. This exercises LCSSA corner cases. define i32 @PR18753(i1* %a, i1* %b, i1* %c, i1* %d) { entry: br label %l1.header l1.header: %iv = phi i64 [ %iv.next, %l1.latch ], [ 0, %entry ] %arrayidx.i = getelementptr inbounds [1 x i32]* @c, i64 0, i64 %iv br label %l2.header l2.header: %x0 = load i1* %c, align 4 br i1 %x0, label %l1.latch, label %l3.preheader l3.preheader: br label %l3.header l3.header: %x1 = load i1* %d, align 4 br i1 %x1, label %l2.latch, label %l4.preheader l4.preheader: br label %l4.header l4.header: %x2 = load i1* %a br i1 %x2, label %l3.latch, label %l4.body l4.body: call void @f(i32* %arrayidx.i) %x3 = load i1* %b %l = trunc i64 %iv to i32 br i1 %x3, label %l4.latch, label %exit l4.latch: call void @g() %x4 = load i1* %b, align 4 br i1 %x4, label %l4.header, label %exit l3.latch: br label %l3.header l2.latch: br label %l2.header l1.latch: %iv.next = add nsw i64 %iv, 1 br label %l1.header exit: %lcssa = phi i32 [ %l, %l4.latch ], [ %l, %l4.body ] ; CHECK-LABEL: @PR18753( ; CHECK: exit: ; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i64 [ %iv, %l4.latch ], [ %iv, %l4.body ] ; CHECK-NEXT: %l.le = trunc i64 %[[LCSSAPHI]] to i32 ; CHECK-NEXT: ret i32 %l.le ret i32 %lcssa } declare void @f(i32*) declare void @g()