1; Tests to ensure that we are not placing backedge safepoints in 2; loops which are clearly finite. 3;; RUN: opt < %s -place-safepoints -spp-counted-loop-trip-width=32 -S | FileCheck %s 4;; RUN: opt < %s -place-safepoints -spp-counted-loop-trip-width=64 -S | FileCheck %s -check-prefix=COUNTED-64 5 6 7; A simple counted loop with trivially known range 8define void @test1(i32) gc "statepoint-example" { 9; CHECK-LABEL: test1 10; CHECK-LABEL: entry 11; CHECK: call void @do_safepoint 12; CHECK-LABEL: loop 13; CHECK-NOT: call void @do_safepoint 14; CHECK-LABEL: exit 15 16entry: 17 br label %loop 18 19loop: 20 %counter = phi i32 [ 0 , %entry ], [ %counter.inc , %loop ] 21 %counter.inc = add i32 %counter, 1 22 %counter.cmp = icmp slt i32 %counter.inc, 16 23 br i1 %counter.cmp, label %loop, label %exit 24 25exit: 26 ret void 27} 28 29; The same counted loop, but with an unknown early exit 30define void @test2(i32) gc "statepoint-example" { 31; CHECK-LABEL: test2 32; CHECK-LABEL: entry 33; CHECK: call void @do_safepoint 34; CHECK-LABEL: loop 35; CHECK-NOT: call void @do_safepoint 36; CHECK-LABEL: exit 37 38entry: 39 br label %loop 40 41loop: 42 %counter = phi i32 [ 0 , %entry ], [ %counter.inc , %continue ] 43 %counter.inc = add i32 %counter, 1 44 %counter.cmp = icmp slt i32 %counter.inc, 16 45 br i1 undef, label %continue, label %exit 46 47continue: 48 br i1 %counter.cmp, label %loop, label %exit 49 50exit: 51 ret void 52} 53 54; The range is a 8 bit value and we can't overflow 55define void @test3(i8 %upper) gc "statepoint-example" { 56; CHECK-LABEL: test3 57; CHECK-LABEL: entry 58; CHECK: call void @do_safepoint 59; CHECK-LABEL: loop 60; CHECK-NOT: call void @do_safepoint 61; CHECK-LABEL: exit 62 63entry: 64 br label %loop 65 66loop: 67 %counter = phi i8 [ 0 , %entry ], [ %counter.inc , %loop ] 68 %counter.inc = add nsw i8 %counter, 1 69 %counter.cmp = icmp slt i8 %counter.inc, %upper 70 br i1 %counter.cmp, label %loop, label %exit 71 72exit: 73 ret void 74} 75 76; The range is a 64 bit value 77define void @test4(i64 %upper) gc "statepoint-example" { 78; CHECK-LABEL: test4 79; CHECK-LABEL: entry 80; CHECK: call void @do_safepoint 81; CHECK-LABEL: loop 82; CHECK: call void @do_safepoint 83; CHECK-LABEL: exit 84 85; COUNTED-64-LABEL: test4 86; COUNTED-64-LABEL: entry 87; COUNTED-64: call void @do_safepoint 88; COUNTED-64-LABEL: loop 89; COUNTED-64-NOT: call void @do_safepoint 90; COUNTED-64-LABEL: exit 91 92entry: 93 br label %loop 94 95loop: 96 %counter = phi i64 [ 0 , %entry ], [ %counter.inc , %loop ] 97 %counter.inc = add i64 %counter, 1 98 %counter.cmp = icmp slt i64 %counter.inc, %upper 99 br i1 %counter.cmp, label %loop, label %exit 100 101exit: 102 ret void 103} 104 105; This loop can run infinitely (for %upper == INT64_MAX) so it needs a 106; safepoint. 107define void @test5(i64 %upper) gc "statepoint-example" { 108; CHECK-LABEL: test5 109; CHECK-LABEL: entry 110; CHECK: call void @do_safepoint 111; CHECK-LABEL: loop 112; CHECK: call void @do_safepoint 113; CHECK-LABEL: exit 114 115; COUNTED-64-LABEL: test5 116; COUNTED-64-LABEL: entry 117; COUNTED-64: call void @do_safepoint 118; COUNTED-64-LABEL: loop 119; COUNTED-64: call void @do_safepoint 120; COUNTED-64-LABEL: exit 121 122entry: 123 br label %loop 124 125loop: 126 %counter = phi i64 [ 0 , %entry ], [ %counter.inc , %loop ] 127 %counter.inc = add i64 %counter, 1 128 %counter.cmp = icmp sle i64 %counter.inc, %upper 129 br i1 %counter.cmp, label %loop, label %exit 130 131exit: 132 ret void 133} 134 135 136; This function is inlined when inserting a poll. 137declare void @do_safepoint() 138define void @gc.safepoint_poll() { 139; CHECK-LABEL: gc.safepoint_poll 140entry: 141 call void @do_safepoint() 142 ret void 143}