1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -disable-output -print-mustexecute %s 2>&1 | FileCheck %s
3
4define i1 @header_with_icf(i32* noalias %p, i32 %high) {
5; CHECK-LABEL: @header_with_icf(
6; CHECK-LABEL:       loop:
7; CHECK:         %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] ; (mustexec in: loop)
8; CHECK:          %v = load i32, i32* %p ; (mustexec in: loop)
9; CHECK:          call void @maythrow_and_use(i32 %v)	; (mustexec in: loop)
10; CHECK-NOT: mustexec
11
12entry:
13  br label %loop
14
15loop:
16  %iv = phi i32 [0, %entry], [%iv.next, %loop]
17  %v = load i32, i32* %p
18  call void @maythrow_and_use(i32 %v)
19  %iv.next = add nsw nuw i32 %iv, 1
20  %exit.test = icmp slt i32 %iv, %high
21  br i1 %exit.test, label %exit, label %loop
22
23exit:
24  ret i1 false
25}
26
27define i1 @split_header(i32* noalias %p, i32 %high) {
28; CHECK-LABEL: @split_header(
29; CHECK-LABEL:       loop:
30; CHECK:          %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ]	; (mustexec in: loop)
31; CHECK:          %v = load i32, i32* %p ; (mustexec in: loop)
32; CHECK:          br label %next ; (mustexec in: loop)
33; CHECK-NOT: mustexec
34entry:
35  br label %loop
36
37loop:
38  %iv = phi i32 [0, %entry], [%iv.next, %next]
39  %v = load i32, i32* %p
40  br label %next
41next:
42  call void @maythrow_and_use(i32 %v)
43  %iv.next = add nsw nuw i32 %iv, 1
44  %exit.test = icmp slt i32 %iv, %high
45  br i1 %exit.test, label %exit, label %loop
46
47exit:
48  ret i1 false
49}
50
51; FIXME: everything in inner loop header should be must execute
52; for outer as well
53define i1 @nested(i32* noalias %p, i32 %high) {
54; CHECK-LABEL: @nested
55; CHECK-LABEL: loop:                                             ; preds = %next
56; CHECK:         %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ]	; (mustexec in: loop)
57; CHECK:         br label %inner_loop	; (mustexec in: loop)
58; CHECK-LABEL: inner_loop:
59; CHECK:         %v = load i32, i32* %p	; (mustexec in: inner_loop)
60; CHECK:         %inner.test = icmp eq i32 %v, 0	; (mustexec in: inner_loop)
61; CHECK:         br i1 %inner.test, label %inner_loop, label %next	; (mustexec in: inner_loop)
62; CHECK-NOT: mustexec
63
64entry:
65  br label %loop
66
67loop:
68  %iv = phi i32 [0, %entry], [%iv.next, %next]
69  br label %inner_loop
70
71inner_loop:
72  %v = load i32, i32* %p
73  %inner.test = icmp eq i32 %v, 0
74  br i1 %inner.test, label %inner_loop, label %next
75
76next:
77  call void @maythrow_and_use(i32 %v)
78  %iv.next = add nsw nuw i32 %iv, 1
79  %exit.test = icmp slt i32 %iv, %high
80  br i1 %exit.test, label %exit, label %loop
81
82exit:
83  ret i1 false
84}
85
86; FIXME: everything in inner loop header should be must execute
87; for outer as well
88define i1 @nested_no_throw(i32* noalias %p, i32 %high) {
89; CHECK-LABEL: @nested_no_throw
90; CHECK-LABEL: loop:                                             ; preds = %next
91; CHECK:         %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ]	; (mustexec in: loop)
92; CHECK:         br label %inner_loop	; (mustexec in: loop)
93; CHECK-LABEL: inner_loop:
94; CHECK:         %v = load i32, i32* %p	; (mustexec in: inner_loop)
95; CHECK:         %inner.test = icmp eq i32 %v, 0	; (mustexec in: inner_loop)
96; CHECK:         br i1 %inner.test, label %inner_loop, label %next	; (mustexec in: inner_loop)
97; CHECK-LABEL: next:
98; CHECK:         %iv.next = add nuw nsw i32 %iv, 1 ; (mustexec in: loop)
99; CHECK:         %exit.test = icmp slt i32 %iv, %high ; (mustexec in: loop)
100; CHECK:         br i1 %exit.test, label %exit, label %loop ; (mustexec in: loop)
101
102entry:
103  br label %loop
104
105loop:
106  %iv = phi i32 [0, %entry], [%iv.next, %next]
107  br label %inner_loop
108
109inner_loop:
110  %v = load i32, i32* %p
111  %inner.test = icmp eq i32 %v, 0
112  br i1 %inner.test, label %inner_loop, label %next
113
114next:
115  %iv.next = add nsw nuw i32 %iv, 1
116  %exit.test = icmp slt i32 %iv, %high
117  br i1 %exit.test, label %exit, label %loop
118
119exit:
120  ret i1 false
121}
122
123; Since all the instructions in the loop dominate the only exit
124; and there's no implicit control flow in the loop, all must execute
125; FIXME: handled by loop safety info, test it
126define i1 @nothrow_loop(i32* noalias %p, i32 %high) {
127; CHECK-LABEL: @nothrow_loop(
128; CHECK-LABEL:  loop:
129; CHECK:         %iv = phi i32 [ 0, %entry ], [ %iv.next, %next ] ; (mustexec in: loop)
130; CHECK:          br label %next ; (mustexec in: loop)
131; CHECK-LABEL: next:
132; CHECK:          %v = load i32, i32* %p ; (mustexec in: loop)
133; CHECK:          %iv.next = add nuw nsw i32 %iv, 1 ; (mustexec in: loop)
134; CHECK:          %exit.test = icmp slt i32 %iv, %high ; (mustexec in: loop)
135; CHECK:          br i1 %exit.test, label %exit, label %loop ; (mustexec in: loop)
136; CHECK-NOT: mustexec
137
138entry:
139  br label %loop
140
141loop:
142  %iv = phi i32 [0, %entry], [%iv.next, %next]
143  br label %next
144next:
145  %v = load i32, i32* %p
146  %iv.next = add nsw nuw i32 %iv, 1
147  %exit.test = icmp slt i32 %iv, %high
148  br i1 %exit.test, label %exit, label %loop
149
150exit:
151  ret i1 false
152}
153
154
155declare void @maythrow_and_use(i32)
156