• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}