Home | History | Annotate | Download | only in PlaceSafepoints
      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 }