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 8 define 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 16 entry: 17 br label %loop 18 19 loop: 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 25 exit: 26 ret void 27 } 28 29 ; The same counted loop, but with an unknown early exit 30 define 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 38 entry: 39 br label %loop 40 41 loop: 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 47 continue: 48 br i1 %counter.cmp, label %loop, label %exit 49 50 exit: 51 ret void 52 } 53 54 ; The range is a 8 bit value and we can't overflow 55 define 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 63 entry: 64 br label %loop 65 66 loop: 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 72 exit: 73 ret void 74 } 75 76 ; The range is a 64 bit value 77 define 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 92 entry: 93 br label %loop 94 95 loop: 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 101 exit: 102 ret void 103 } 104 105 ; This loop can run infinitely (for %upper == INT64_MAX) so it needs a 106 ; safepoint. 107 define 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 122 entry: 123 br label %loop 124 125 loop: 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 131 exit: 132 ret void 133 } 134 135 136 ; This function is inlined when inserting a poll. 137 declare void @do_safepoint() 138 define void @gc.safepoint_poll() { 139 ; CHECK-LABEL: gc.safepoint_poll 140 entry: 141 call void @do_safepoint() 142 ret void 143 }