1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -licm -S | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: opt -lcssa %s | opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,loop(licm)' -S | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker@X = global i32 0 ; <i32*> [#uses=1] 5*9880d681SAndroid Build Coastguard Worker 6*9880d681SAndroid Build Coastguard Workerdeclare void @foo() 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker; This testcase tests for a problem where LICM hoists 9*9880d681SAndroid Build Coastguard Worker; potentially trapping instructions when they are not guaranteed to execute. 10*9880d681SAndroid Build Coastguard Workerdefine i32 @test1(i1 %c) { 11*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test1( 12*9880d681SAndroid Build Coastguard Worker %A = load i32, i32* @X ; <i32> [#uses=2] 13*9880d681SAndroid Build Coastguard Worker br label %Loop 14*9880d681SAndroid Build Coastguard WorkerLoop: ; preds = %LoopTail, %0 15*9880d681SAndroid Build Coastguard Worker call void @foo( ) 16*9880d681SAndroid Build Coastguard Worker br i1 %c, label %LoopTail, label %IfUnEqual 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard WorkerIfUnEqual: ; preds = %Loop 19*9880d681SAndroid Build Coastguard Worker; CHECK: IfUnEqual: 20*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sdiv i32 4, %A 21*9880d681SAndroid Build Coastguard Worker %B1 = sdiv i32 4, %A ; <i32> [#uses=1] 22*9880d681SAndroid Build Coastguard Worker br label %LoopTail 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard WorkerLoopTail: ; preds = %IfUnEqual, %Loop 25*9880d681SAndroid Build Coastguard Worker %B = phi i32 [ 0, %Loop ], [ %B1, %IfUnEqual ] ; <i32> [#uses=1] 26*9880d681SAndroid Build Coastguard Worker br i1 %c, label %Loop, label %Out 27*9880d681SAndroid Build Coastguard WorkerOut: ; preds = %LoopTail 28*9880d681SAndroid Build Coastguard Worker %C = sub i32 %A, %B ; <i32> [#uses=1] 29*9880d681SAndroid Build Coastguard Worker ret i32 %C 30*9880d681SAndroid Build Coastguard Worker} 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Workerdeclare void @foo2(i32) nounwind 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker;; It is ok and desirable to hoist this potentially trapping instruction. 37*9880d681SAndroid Build Coastguard Workerdefine i32 @test2(i1 %c) { 38*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test2( 39*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: load i32, i32* @X 40*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %B = sdiv i32 4, %A 41*9880d681SAndroid Build Coastguard Worker %A = load i32, i32* @X 42*9880d681SAndroid Build Coastguard Worker br label %Loop 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard WorkerLoop: 45*9880d681SAndroid Build Coastguard Worker ;; Should have hoisted this div! 46*9880d681SAndroid Build Coastguard Worker %B = sdiv i32 4, %A 47*9880d681SAndroid Build Coastguard Worker br label %loop2 48*9880d681SAndroid Build Coastguard Worker 49*9880d681SAndroid Build Coastguard Workerloop2: 50*9880d681SAndroid Build Coastguard Worker call void @foo2( i32 %B ) 51*9880d681SAndroid Build Coastguard Worker br i1 %c, label %Loop, label %Out 52*9880d681SAndroid Build Coastguard Worker 53*9880d681SAndroid Build Coastguard WorkerOut: 54*9880d681SAndroid Build Coastguard Worker %C = sub i32 %A, %B 55*9880d681SAndroid Build Coastguard Worker ret i32 %C 56*9880d681SAndroid Build Coastguard Worker} 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker; This loop invariant instruction should be constant folded, not hoisted. 60*9880d681SAndroid Build Coastguard Workerdefine i32 @test3(i1 %c) { 61*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i32 @test3( 62*9880d681SAndroid Build Coastguard Worker; CHECK: call void @foo2(i32 6) 63*9880d681SAndroid Build Coastguard Worker %A = load i32, i32* @X ; <i32> [#uses=2] 64*9880d681SAndroid Build Coastguard Worker br label %Loop 65*9880d681SAndroid Build Coastguard WorkerLoop: 66*9880d681SAndroid Build Coastguard Worker %B = add i32 4, 2 ; <i32> [#uses=2] 67*9880d681SAndroid Build Coastguard Worker call void @foo2( i32 %B ) 68*9880d681SAndroid Build Coastguard Worker br i1 %c, label %Loop, label %Out 69*9880d681SAndroid Build Coastguard WorkerOut: ; preds = %Loop 70*9880d681SAndroid Build Coastguard Worker %C = sub i32 %A, %B ; <i32> [#uses=1] 71*9880d681SAndroid Build Coastguard Worker ret i32 %C 72*9880d681SAndroid Build Coastguard Worker} 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test4( 75*9880d681SAndroid Build Coastguard Worker; CHECK: call 76*9880d681SAndroid Build Coastguard Worker; CHECK: sdiv 77*9880d681SAndroid Build Coastguard Worker; CHECK: ret 78*9880d681SAndroid Build Coastguard Workerdefine i32 @test4(i32 %x, i32 %y) nounwind uwtable ssp { 79*9880d681SAndroid Build Coastguard Workerentry: 80*9880d681SAndroid Build Coastguard Worker br label %for.body 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Workerfor.body: ; preds = %entry, %for.body 83*9880d681SAndroid Build Coastguard Worker %i.02 = phi i32 [ 0, %entry ], [ %inc, %for.body ] 84*9880d681SAndroid Build Coastguard Worker %n.01 = phi i32 [ 0, %entry ], [ %add, %for.body ] 85*9880d681SAndroid Build Coastguard Worker call void @foo_may_call_exit(i32 0) 86*9880d681SAndroid Build Coastguard Worker %div = sdiv i32 %x, %y 87*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %n.01, %div 88*9880d681SAndroid Build Coastguard Worker %inc = add nsw i32 %i.02, 1 89*9880d681SAndroid Build Coastguard Worker %cmp = icmp slt i32 %inc, 10000 90*9880d681SAndroid Build Coastguard Worker br i1 %cmp, label %for.body, label %for.end 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Workerfor.end: ; preds = %for.body 93*9880d681SAndroid Build Coastguard Worker %n.0.lcssa = phi i32 [ %add, %for.body ] 94*9880d681SAndroid Build Coastguard Worker ret i32 %n.0.lcssa 95*9880d681SAndroid Build Coastguard Worker} 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Workerdeclare void @foo_may_call_exit(i32) 98*9880d681SAndroid Build Coastguard Worker 99*9880d681SAndroid Build Coastguard Worker; PR14854 100*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test5( 101*9880d681SAndroid Build Coastguard Worker; CHECK: extractvalue 102*9880d681SAndroid Build Coastguard Worker; CHECK: br label %tailrecurse 103*9880d681SAndroid Build Coastguard Worker; CHECK: tailrecurse: 104*9880d681SAndroid Build Coastguard Worker; CHECK: ifend: 105*9880d681SAndroid Build Coastguard Worker; CHECK: insertvalue 106*9880d681SAndroid Build Coastguard Workerdefine { i32*, i32 } @test5(i32 %i, { i32*, i32 } %e) { 107*9880d681SAndroid Build Coastguard Workerentry: 108*9880d681SAndroid Build Coastguard Worker br label %tailrecurse 109*9880d681SAndroid Build Coastguard Worker 110*9880d681SAndroid Build Coastguard Workertailrecurse: ; preds = %then, %entry 111*9880d681SAndroid Build Coastguard Worker %i.tr = phi i32 [ %i, %entry ], [ %cmp2, %then ] 112*9880d681SAndroid Build Coastguard Worker %out = extractvalue { i32*, i32 } %e, 1 113*9880d681SAndroid Build Coastguard Worker %d = insertvalue { i32*, i32 } %e, i32* null, 0 114*9880d681SAndroid Build Coastguard Worker %cmp1 = icmp sgt i32 %out, %i.tr 115*9880d681SAndroid Build Coastguard Worker br i1 %cmp1, label %then, label %ifend 116*9880d681SAndroid Build Coastguard Worker 117*9880d681SAndroid Build Coastguard Workerthen: ; preds = %tailrecurse 118*9880d681SAndroid Build Coastguard Worker call void @foo() 119*9880d681SAndroid Build Coastguard Worker %cmp2 = add i32 %i.tr, 1 120*9880d681SAndroid Build Coastguard Worker br label %tailrecurse 121*9880d681SAndroid Build Coastguard Worker 122*9880d681SAndroid Build Coastguard Workerifend: ; preds = %tailrecurse 123*9880d681SAndroid Build Coastguard Worker ret { i32*, i32 } %d 124*9880d681SAndroid Build Coastguard Worker} 125