1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -indvars < %s | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; Check that SCEV is able to recognize and use guards to prove 4*9880d681SAndroid Build Coastguard Worker; conditions gaurding loop entries and backedges. This isn't intended 5*9880d681SAndroid Build Coastguard Worker; to be a comprehensive test of SCEV's simplification capabilities, 6*9880d681SAndroid Build Coastguard Worker; tests directly testing e.g. if SCEV can elide a sext should go 7*9880d681SAndroid Build Coastguard Worker; elsewhere. 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Workertarget datalayout = "n8:16:32:64" 10*9880d681SAndroid Build Coastguard Worker 11*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.experimental.guard(i1, ...) 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Workerdefine void @test_1(i1* %cond_buf, i32* %len_buf) { 14*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_1( 15*9880d681SAndroid Build Coastguard Workerentry: 16*9880d681SAndroid Build Coastguard Worker %len = load i32, i32* %len_buf, !range !{i32 1, i32 2147483648} 17*9880d681SAndroid Build Coastguard Worker br label %loop 18*9880d681SAndroid Build Coastguard Worker 19*9880d681SAndroid Build Coastguard Workerloop: 20*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 21*9880d681SAndroid Build Coastguard Worker; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] 22*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.inc.cmp = icmp slt i32 %iv.inc, %len 23*9880d681SAndroid Build Coastguard Worker; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] 24*9880d681SAndroid Build Coastguard Worker; CHECK: leave: 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] 27*9880d681SAndroid Build Coastguard Worker %iv.inc = add i32 %iv, 1 28*9880d681SAndroid Build Coastguard Worker 29*9880d681SAndroid Build Coastguard Worker %iv.cmp = icmp slt i32 %iv, %len 30*9880d681SAndroid Build Coastguard Worker call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ] 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker %iv.inc.cmp = icmp slt i32 %iv.inc, %len 33*9880d681SAndroid Build Coastguard Worker call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] 34*9880d681SAndroid Build Coastguard Worker 35*9880d681SAndroid Build Coastguard Worker %becond = load volatile i1, i1* %cond_buf 36*9880d681SAndroid Build Coastguard Worker br i1 %becond, label %loop, label %leave 37*9880d681SAndroid Build Coastguard Worker 38*9880d681SAndroid Build Coastguard Workerleave: 39*9880d681SAndroid Build Coastguard Worker ret void 40*9880d681SAndroid Build Coastguard Worker} 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Workerdefine void @test_2(i32 %n, i32* %len_buf) { 43*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_2( 44*9880d681SAndroid Build Coastguard Worker; CHECK: [[LEN_SEXT:%[^ ]+]] = sext i32 %len to i64 45*9880d681SAndroid Build Coastguard Worker; CHECK: br label %loop 46*9880d681SAndroid Build Coastguard Worker 47*9880d681SAndroid Build Coastguard Workerentry: 48*9880d681SAndroid Build Coastguard Worker %len = load i32, i32* %len_buf, !range !{i32 0, i32 2147483648} 49*9880d681SAndroid Build Coastguard Worker br label %loop 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Workerloop: 52*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 53*9880d681SAndroid Build Coastguard Worker; CHECK: %indvars.iv = phi i64 [ %indvars.iv.next, %loop ], [ 0, %entry ] 54*9880d681SAndroid Build Coastguard Worker; CHECK: %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 55*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.inc.cmp = icmp slt i64 %indvars.iv.next, [[LEN_SEXT]] 56*9880d681SAndroid Build Coastguard Worker; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] 57*9880d681SAndroid Build Coastguard Worker; CHECK: leave: 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] 60*9880d681SAndroid Build Coastguard Worker %iv.inc = add i32 %iv, 1 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Worker %iv.sext = sext i32 %iv to i64 63*9880d681SAndroid Build Coastguard Worker 64*9880d681SAndroid Build Coastguard Worker %iv.inc.cmp = icmp slt i32 %iv.inc, %len 65*9880d681SAndroid Build Coastguard Worker call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] 66*9880d681SAndroid Build Coastguard Worker 67*9880d681SAndroid Build Coastguard Worker %becond = icmp ne i32 %iv, %n 68*9880d681SAndroid Build Coastguard Worker br i1 %becond, label %loop, label %leave 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Workerleave: 71*9880d681SAndroid Build Coastguard Worker ret void 72*9880d681SAndroid Build Coastguard Worker} 73*9880d681SAndroid Build Coastguard Worker 74*9880d681SAndroid Build Coastguard Workerdefine void @test_3(i1* %cond_buf, i32* %len_buf) { 75*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_3( 76*9880d681SAndroid Build Coastguard Worker 77*9880d681SAndroid Build Coastguard Workerentry: 78*9880d681SAndroid Build Coastguard Worker %len = load i32, i32* %len_buf 79*9880d681SAndroid Build Coastguard Worker %entry.cond = icmp sgt i32 %len, 0 80*9880d681SAndroid Build Coastguard Worker call void(i1, ...) @llvm.experimental.guard(i1 %entry.cond) [ "deopt"() ] 81*9880d681SAndroid Build Coastguard Worker br label %loop 82*9880d681SAndroid Build Coastguard Worker 83*9880d681SAndroid Build Coastguard Workerloop: 84*9880d681SAndroid Build Coastguard Worker; CHECK: loop: 85*9880d681SAndroid Build Coastguard Worker; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 true) [ "deopt"() ] 86*9880d681SAndroid Build Coastguard Worker; CHECK: %iv.inc.cmp = icmp slt i32 %iv.inc, %len 87*9880d681SAndroid Build Coastguard Worker; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] 88*9880d681SAndroid Build Coastguard Worker; CHECK: leave: 89*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ 0, %entry ], [ %iv.inc, %loop ] 90*9880d681SAndroid Build Coastguard Worker %iv.inc = add i32 %iv, 1 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker %iv.cmp = icmp slt i32 %iv, %len 93*9880d681SAndroid Build Coastguard Worker call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ] 94*9880d681SAndroid Build Coastguard Worker 95*9880d681SAndroid Build Coastguard Worker %iv.inc.cmp = icmp slt i32 %iv.inc, %len 96*9880d681SAndroid Build Coastguard Worker call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] 97*9880d681SAndroid Build Coastguard Worker 98*9880d681SAndroid Build Coastguard Worker %becond = load volatile i1, i1* %cond_buf 99*9880d681SAndroid Build Coastguard Worker br i1 %becond, label %loop, label %leave 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Workerleave: 102*9880d681SAndroid Build Coastguard Worker ret void 103*9880d681SAndroid Build Coastguard Worker} 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Workerdefine void @test_4(i1* %cond_buf, i32* %len_buf) { 106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_4( 107*9880d681SAndroid Build Coastguard Worker 108*9880d681SAndroid Build Coastguard Workerentry: 109*9880d681SAndroid Build Coastguard Worker %len = load i32, i32* %len_buf 110*9880d681SAndroid Build Coastguard Worker %entry.cond = icmp sgt i32 %len, 0 111*9880d681SAndroid Build Coastguard Worker call void(i1, ...) @llvm.experimental.guard(i1 %entry.cond) [ "deopt"() ] 112*9880d681SAndroid Build Coastguard Worker br label %loop 113*9880d681SAndroid Build Coastguard Worker 114*9880d681SAndroid Build Coastguard Workerloop: 115*9880d681SAndroid Build Coastguard Worker %iv = phi i32 [ 0, %entry ], [ %iv.inc, %be ] 116*9880d681SAndroid Build Coastguard Worker %iv.inc = add i32 %iv, 1 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker %cond = load volatile i1, i1* %cond_buf 119*9880d681SAndroid Build Coastguard Worker br i1 %cond, label %left, label %be 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Workerleft: 122*9880d681SAndroid Build Coastguard Worker ; Does not dominate the backedge, so cannot be used in the inductive proof 123*9880d681SAndroid Build Coastguard Worker %iv.inc.cmp = icmp slt i32 %iv.inc, %len 124*9880d681SAndroid Build Coastguard Worker call void(i1, ...) @llvm.experimental.guard(i1 %iv.inc.cmp) [ "deopt"() ] 125*9880d681SAndroid Build Coastguard Worker br label %be 126*9880d681SAndroid Build Coastguard Worker 127*9880d681SAndroid Build Coastguard Workerbe: 128*9880d681SAndroid Build Coastguard Worker; CHECK: be: 129*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: %iv.cmp = icmp slt i32 %iv, %len 130*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ] 131*9880d681SAndroid Build Coastguard Worker; CHECK: leave: 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker %iv.cmp = icmp slt i32 %iv, %len 134*9880d681SAndroid Build Coastguard Worker call void(i1, ...) @llvm.experimental.guard(i1 %iv.cmp) [ "deopt"() ] 135*9880d681SAndroid Build Coastguard Worker 136*9880d681SAndroid Build Coastguard Worker %becond = load volatile i1, i1* %cond_buf 137*9880d681SAndroid Build Coastguard Worker br i1 %becond, label %loop, label %leave 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Workerleave: 140*9880d681SAndroid Build Coastguard Worker ret void 141*9880d681SAndroid Build Coastguard Worker} 142