annotate llvm/test/Transforms/CodeGenPrepare/X86/computedgoto.ll @ 173:0572611fdcc8 llvm10 llvm12

reorgnization done
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 11:55:54 +0900
parents 1d019706d866
children 1f2b6ac9f198
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
anatofuz
parents:
diff changeset
2 ; RUN: opt -codegenprepare -S < %s | FileCheck %s
anatofuz
parents:
diff changeset
3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
anatofuz
parents:
diff changeset
4 target triple = "x86_64-unknown-linux-gnu"
anatofuz
parents:
diff changeset
5
anatofuz
parents:
diff changeset
6 declare void @use(i32) local_unnamed_addr
anatofuz
parents:
diff changeset
7 declare void @useptr([2 x i8*]*) local_unnamed_addr
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 ; CHECK: @simple.targets = constant [2 x i8*] [i8* blockaddress(@simple, %bb0), i8* blockaddress(@simple, %bb1)], align 16
anatofuz
parents:
diff changeset
10 @simple.targets = constant [2 x i8*] [i8* blockaddress(@simple, %bb0), i8* blockaddress(@simple, %bb1)], align 16
anatofuz
parents:
diff changeset
11
anatofuz
parents:
diff changeset
12 ; CHECK: @multi.targets = constant [2 x i8*] [i8* blockaddress(@multi, %bb0), i8* blockaddress(@multi, %bb1)], align 16
anatofuz
parents:
diff changeset
13 @multi.targets = constant [2 x i8*] [i8* blockaddress(@multi, %bb0), i8* blockaddress(@multi, %bb1)], align 16
anatofuz
parents:
diff changeset
14
anatofuz
parents:
diff changeset
15 ; CHECK: @loop.targets = constant [2 x i8*] [i8* blockaddress(@loop, %bb0), i8* blockaddress(@loop, %bb1)], align 16
anatofuz
parents:
diff changeset
16 @loop.targets = constant [2 x i8*] [i8* blockaddress(@loop, %bb0), i8* blockaddress(@loop, %bb1)], align 16
anatofuz
parents:
diff changeset
17
anatofuz
parents:
diff changeset
18 ; CHECK: @nophi.targets = constant [2 x i8*] [i8* blockaddress(@nophi, %bb0), i8* blockaddress(@nophi, %bb1)], align 16
anatofuz
parents:
diff changeset
19 @nophi.targets = constant [2 x i8*] [i8* blockaddress(@nophi, %bb0), i8* blockaddress(@nophi, %bb1)], align 16
anatofuz
parents:
diff changeset
20
anatofuz
parents:
diff changeset
21 ; CHECK: @noncritical.targets = constant [2 x i8*] [i8* blockaddress(@noncritical, %bb0), i8* blockaddress(@noncritical, %bb1)], align 16
anatofuz
parents:
diff changeset
22 @noncritical.targets = constant [2 x i8*] [i8* blockaddress(@noncritical, %bb0), i8* blockaddress(@noncritical, %bb1)], align 16
anatofuz
parents:
diff changeset
23
anatofuz
parents:
diff changeset
24 ; Check that we break the critical edge when an jump table has only one use.
anatofuz
parents:
diff changeset
25 define void @simple(i32* nocapture readonly %p) {
anatofuz
parents:
diff changeset
26 ; CHECK-LABEL: @simple(
anatofuz
parents:
diff changeset
27 ; CHECK-NEXT: entry:
anatofuz
parents:
diff changeset
28 ; CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
anatofuz
parents:
diff changeset
29 ; CHECK-NEXT: [[INITVAL:%.*]] = load i32, i32* [[P]], align 4
anatofuz
parents:
diff changeset
30 ; CHECK-NEXT: [[INITOP:%.*]] = load i32, i32* [[INCDEC_PTR]], align 4
anatofuz
parents:
diff changeset
31 ; CHECK-NEXT: switch i32 [[INITOP]], label [[EXIT:%.*]] [
anatofuz
parents:
diff changeset
32 ; CHECK-NEXT: i32 0, label [[BB0_CLONE:%.*]]
anatofuz
parents:
diff changeset
33 ; CHECK-NEXT: i32 1, label [[BB1_CLONE:%.*]]
anatofuz
parents:
diff changeset
34 ; CHECK-NEXT: ]
anatofuz
parents:
diff changeset
35 ; CHECK: bb0:
anatofuz
parents:
diff changeset
36 ; CHECK-NEXT: br label [[DOTSPLIT:%.*]]
anatofuz
parents:
diff changeset
37 ; CHECK: .split:
anatofuz
parents:
diff changeset
38 ; CHECK-NEXT: [[MERGE:%.*]] = phi i32* [ [[PTR:%.*]], [[BB0:%.*]] ], [ [[INCDEC_PTR]], [[BB0_CLONE]] ]
anatofuz
parents:
diff changeset
39 ; CHECK-NEXT: [[MERGE2:%.*]] = phi i32 [ 0, [[BB0]] ], [ [[INITVAL]], [[BB0_CLONE]] ]
anatofuz
parents:
diff changeset
40 ; CHECK-NEXT: tail call void @use(i32 [[MERGE2]])
anatofuz
parents:
diff changeset
41 ; CHECK-NEXT: br label [[INDIRECTGOTO:%.*]]
anatofuz
parents:
diff changeset
42 ; CHECK: bb1:
anatofuz
parents:
diff changeset
43 ; CHECK-NEXT: br label [[DOTSPLIT3:%.*]]
anatofuz
parents:
diff changeset
44 ; CHECK: .split3:
anatofuz
parents:
diff changeset
45 ; CHECK-NEXT: [[MERGE5:%.*]] = phi i32* [ [[PTR]], [[BB1:%.*]] ], [ [[INCDEC_PTR]], [[BB1_CLONE]] ]
anatofuz
parents:
diff changeset
46 ; CHECK-NEXT: [[MERGE7:%.*]] = phi i32 [ 1, [[BB1]] ], [ [[INITVAL]], [[BB1_CLONE]] ]
anatofuz
parents:
diff changeset
47 ; CHECK-NEXT: tail call void @use(i32 [[MERGE7]])
anatofuz
parents:
diff changeset
48 ; CHECK-NEXT: br label [[INDIRECTGOTO]]
anatofuz
parents:
diff changeset
49 ; CHECK: indirectgoto:
anatofuz
parents:
diff changeset
50 ; CHECK-NEXT: [[P_ADDR_SINK:%.*]] = phi i32* [ [[MERGE5]], [[DOTSPLIT3]] ], [ [[MERGE]], [[DOTSPLIT]] ]
anatofuz
parents:
diff changeset
51 ; CHECK-NEXT: [[PTR]] = getelementptr inbounds i32, i32* [[P_ADDR_SINK]], i64 1
anatofuz
parents:
diff changeset
52 ; CHECK-NEXT: [[NEWP:%.*]] = load i32, i32* [[P_ADDR_SINK]], align 4
anatofuz
parents:
diff changeset
53 ; CHECK-NEXT: [[IDX:%.*]] = sext i32 [[NEWP]] to i64
anatofuz
parents:
diff changeset
54 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* @simple.targets, i64 0, i64 [[IDX]]
anatofuz
parents:
diff changeset
55 ; CHECK-NEXT: [[NEWOP:%.*]] = load i8*, i8** [[ARRAYIDX]], align 8
anatofuz
parents:
diff changeset
56 ; CHECK-NEXT: indirectbr i8* [[NEWOP]], [label [[BB0]], label %bb1]
anatofuz
parents:
diff changeset
57 ; CHECK: exit:
anatofuz
parents:
diff changeset
58 ; CHECK-NEXT: ret void
anatofuz
parents:
diff changeset
59 ; CHECK: bb0.clone:
anatofuz
parents:
diff changeset
60 ; CHECK-NEXT: br label [[DOTSPLIT]]
anatofuz
parents:
diff changeset
61 ; CHECK: bb1.clone:
anatofuz
parents:
diff changeset
62 ; CHECK-NEXT: br label [[DOTSPLIT3]]
anatofuz
parents:
diff changeset
63 ;
anatofuz
parents:
diff changeset
64 entry:
anatofuz
parents:
diff changeset
65 %incdec.ptr = getelementptr inbounds i32, i32* %p, i64 1
anatofuz
parents:
diff changeset
66 %initval = load i32, i32* %p, align 4
anatofuz
parents:
diff changeset
67 %initop = load i32, i32* %incdec.ptr, align 4
anatofuz
parents:
diff changeset
68 switch i32 %initop, label %exit [
anatofuz
parents:
diff changeset
69 i32 0, label %bb0
anatofuz
parents:
diff changeset
70 i32 1, label %bb1
anatofuz
parents:
diff changeset
71 ]
anatofuz
parents:
diff changeset
72
anatofuz
parents:
diff changeset
73 bb0:
anatofuz
parents:
diff changeset
74 %p.addr.0 = phi i32* [ %incdec.ptr, %entry ], [ %ptr, %indirectgoto ]
anatofuz
parents:
diff changeset
75 %opcode.0 = phi i32 [ %initval, %entry ], [ 0, %indirectgoto ]
anatofuz
parents:
diff changeset
76 tail call void @use(i32 %opcode.0)
anatofuz
parents:
diff changeset
77 br label %indirectgoto
anatofuz
parents:
diff changeset
78
anatofuz
parents:
diff changeset
79 bb1:
anatofuz
parents:
diff changeset
80 %p.addr.1 = phi i32* [ %incdec.ptr, %entry ], [ %ptr, %indirectgoto ]
anatofuz
parents:
diff changeset
81 %opcode.1 = phi i32 [ %initval, %entry ], [ 1, %indirectgoto ]
anatofuz
parents:
diff changeset
82 tail call void @use(i32 %opcode.1)
anatofuz
parents:
diff changeset
83 br label %indirectgoto
anatofuz
parents:
diff changeset
84
anatofuz
parents:
diff changeset
85 indirectgoto:
anatofuz
parents:
diff changeset
86 %p.addr.sink = phi i32* [ %p.addr.1, %bb1 ], [ %p.addr.0, %bb0 ]
anatofuz
parents:
diff changeset
87 %ptr = getelementptr inbounds i32, i32* %p.addr.sink, i64 1
anatofuz
parents:
diff changeset
88 %newp = load i32, i32* %p.addr.sink, align 4
anatofuz
parents:
diff changeset
89 %idx = sext i32 %newp to i64
anatofuz
parents:
diff changeset
90 %arrayidx = getelementptr inbounds [2 x i8*], [2 x i8*]* @simple.targets, i64 0, i64 %idx
anatofuz
parents:
diff changeset
91 %newop = load i8*, i8** %arrayidx, align 8
anatofuz
parents:
diff changeset
92 indirectbr i8* %newop, [label %bb0, label %bb1]
anatofuz
parents:
diff changeset
93
anatofuz
parents:
diff changeset
94 exit:
anatofuz
parents:
diff changeset
95 ret void
anatofuz
parents:
diff changeset
96 }
anatofuz
parents:
diff changeset
97
anatofuz
parents:
diff changeset
98 ; Don't try to break critical edges when several indirectbr point to a single block
anatofuz
parents:
diff changeset
99 define void @multi(i32* nocapture readonly %p) {
anatofuz
parents:
diff changeset
100 ; CHECK-LABEL: @multi(
anatofuz
parents:
diff changeset
101 ; CHECK-NEXT: entry:
anatofuz
parents:
diff changeset
102 ; CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
anatofuz
parents:
diff changeset
103 ; CHECK-NEXT: [[INITVAL:%.*]] = load i32, i32* [[P]], align 4
anatofuz
parents:
diff changeset
104 ; CHECK-NEXT: [[INITOP:%.*]] = load i32, i32* [[INCDEC_PTR]], align 4
anatofuz
parents:
diff changeset
105 ; CHECK-NEXT: switch i32 [[INITOP]], label [[EXIT:%.*]] [
anatofuz
parents:
diff changeset
106 ; CHECK-NEXT: i32 0, label [[BB0:%.*]]
anatofuz
parents:
diff changeset
107 ; CHECK-NEXT: i32 1, label [[BB1:%.*]]
anatofuz
parents:
diff changeset
108 ; CHECK-NEXT: ]
anatofuz
parents:
diff changeset
109 ; CHECK: bb0:
anatofuz
parents:
diff changeset
110 ; CHECK-NEXT: [[P_ADDR_0:%.*]] = phi i32* [ [[INCDEC_PTR]], [[ENTRY:%.*]] ], [ [[NEXT0:%.*]], [[BB0]] ], [ [[NEXT1:%.*]], [[BB1]] ]
anatofuz
parents:
diff changeset
111 ; CHECK-NEXT: [[OPCODE_0:%.*]] = phi i32 [ [[INITVAL]], [[ENTRY]] ], [ 0, [[BB0]] ], [ 1, [[BB1]] ]
anatofuz
parents:
diff changeset
112 ; CHECK-NEXT: tail call void @use(i32 [[OPCODE_0]])
anatofuz
parents:
diff changeset
113 ; CHECK-NEXT: [[NEXT0]] = getelementptr inbounds i32, i32* [[P_ADDR_0]], i64 1
anatofuz
parents:
diff changeset
114 ; CHECK-NEXT: [[NEWP0:%.*]] = load i32, i32* [[P_ADDR_0]], align 4
anatofuz
parents:
diff changeset
115 ; CHECK-NEXT: [[IDX0:%.*]] = sext i32 [[NEWP0]] to i64
anatofuz
parents:
diff changeset
116 ; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* @multi.targets, i64 0, i64 [[IDX0]]
anatofuz
parents:
diff changeset
117 ; CHECK-NEXT: [[NEWOP0:%.*]] = load i8*, i8** [[ARRAYIDX0]], align 8
anatofuz
parents:
diff changeset
118 ; CHECK-NEXT: indirectbr i8* [[NEWOP0]], [label [[BB0]], label %bb1]
anatofuz
parents:
diff changeset
119 ; CHECK: bb1:
anatofuz
parents:
diff changeset
120 ; CHECK-NEXT: [[P_ADDR_1:%.*]] = phi i32* [ [[INCDEC_PTR]], [[ENTRY]] ], [ [[NEXT0]], [[BB0]] ], [ [[NEXT1]], [[BB1]] ]
anatofuz
parents:
diff changeset
121 ; CHECK-NEXT: [[OPCODE_1:%.*]] = phi i32 [ [[INITVAL]], [[ENTRY]] ], [ 0, [[BB0]] ], [ 1, [[BB1]] ]
anatofuz
parents:
diff changeset
122 ; CHECK-NEXT: tail call void @use(i32 [[OPCODE_1]])
anatofuz
parents:
diff changeset
123 ; CHECK-NEXT: [[NEXT1]] = getelementptr inbounds i32, i32* [[P_ADDR_1]], i64 1
anatofuz
parents:
diff changeset
124 ; CHECK-NEXT: [[NEWP1:%.*]] = load i32, i32* [[P_ADDR_1]], align 4
anatofuz
parents:
diff changeset
125 ; CHECK-NEXT: [[IDX1:%.*]] = sext i32 [[NEWP1]] to i64
anatofuz
parents:
diff changeset
126 ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* @multi.targets, i64 0, i64 [[IDX1]]
anatofuz
parents:
diff changeset
127 ; CHECK-NEXT: [[NEWOP1:%.*]] = load i8*, i8** [[ARRAYIDX1]], align 8
anatofuz
parents:
diff changeset
128 ; CHECK-NEXT: indirectbr i8* [[NEWOP1]], [label [[BB0]], label %bb1]
anatofuz
parents:
diff changeset
129 ; CHECK: exit:
anatofuz
parents:
diff changeset
130 ; CHECK-NEXT: ret void
anatofuz
parents:
diff changeset
131 ;
anatofuz
parents:
diff changeset
132 entry:
anatofuz
parents:
diff changeset
133 %incdec.ptr = getelementptr inbounds i32, i32* %p, i64 1
anatofuz
parents:
diff changeset
134 %initval = load i32, i32* %p, align 4
anatofuz
parents:
diff changeset
135 %initop = load i32, i32* %incdec.ptr, align 4
anatofuz
parents:
diff changeset
136 switch i32 %initop, label %exit [
anatofuz
parents:
diff changeset
137 i32 0, label %bb0
anatofuz
parents:
diff changeset
138 i32 1, label %bb1
anatofuz
parents:
diff changeset
139 ]
anatofuz
parents:
diff changeset
140
anatofuz
parents:
diff changeset
141 bb0:
anatofuz
parents:
diff changeset
142 %p.addr.0 = phi i32* [ %incdec.ptr, %entry ], [ %next0, %bb0 ], [ %next1, %bb1 ]
anatofuz
parents:
diff changeset
143 %opcode.0 = phi i32 [ %initval, %entry ], [ 0, %bb0 ], [ 1, %bb1 ]
anatofuz
parents:
diff changeset
144 tail call void @use(i32 %opcode.0)
anatofuz
parents:
diff changeset
145 %next0 = getelementptr inbounds i32, i32* %p.addr.0, i64 1
anatofuz
parents:
diff changeset
146 %newp0 = load i32, i32* %p.addr.0, align 4
anatofuz
parents:
diff changeset
147 %idx0 = sext i32 %newp0 to i64
anatofuz
parents:
diff changeset
148 %arrayidx0 = getelementptr inbounds [2 x i8*], [2 x i8*]* @multi.targets, i64 0, i64 %idx0
anatofuz
parents:
diff changeset
149 %newop0 = load i8*, i8** %arrayidx0, align 8
anatofuz
parents:
diff changeset
150 indirectbr i8* %newop0, [label %bb0, label %bb1]
anatofuz
parents:
diff changeset
151
anatofuz
parents:
diff changeset
152 bb1:
anatofuz
parents:
diff changeset
153 %p.addr.1 = phi i32* [ %incdec.ptr, %entry ], [ %next0, %bb0 ], [ %next1, %bb1 ]
anatofuz
parents:
diff changeset
154 %opcode.1 = phi i32 [ %initval, %entry ], [ 0, %bb0 ], [ 1, %bb1 ]
anatofuz
parents:
diff changeset
155 tail call void @use(i32 %opcode.1)
anatofuz
parents:
diff changeset
156 %next1 = getelementptr inbounds i32, i32* %p.addr.1, i64 1
anatofuz
parents:
diff changeset
157 %newp1 = load i32, i32* %p.addr.1, align 4
anatofuz
parents:
diff changeset
158 %idx1 = sext i32 %newp1 to i64
anatofuz
parents:
diff changeset
159 %arrayidx1 = getelementptr inbounds [2 x i8*], [2 x i8*]* @multi.targets, i64 0, i64 %idx1
anatofuz
parents:
diff changeset
160 %newop1 = load i8*, i8** %arrayidx1, align 8
anatofuz
parents:
diff changeset
161 indirectbr i8* %newop1, [label %bb0, label %bb1]
anatofuz
parents:
diff changeset
162
anatofuz
parents:
diff changeset
163 exit:
anatofuz
parents:
diff changeset
164 ret void
anatofuz
parents:
diff changeset
165 }
anatofuz
parents:
diff changeset
166
anatofuz
parents:
diff changeset
167 ; Make sure we do the right thing for cases where the indirectbr branches to
anatofuz
parents:
diff changeset
168 ; the block it terminates.
anatofuz
parents:
diff changeset
169 define void @loop(i64* nocapture readonly %p) {
anatofuz
parents:
diff changeset
170 ; CHECK-LABEL: @loop(
anatofuz
parents:
diff changeset
171 ; CHECK-NEXT: entry:
anatofuz
parents:
diff changeset
172 ; CHECK-NEXT: br label [[DOTSPLIT:%.*]]
anatofuz
parents:
diff changeset
173 ; CHECK: bb0:
anatofuz
parents:
diff changeset
174 ; CHECK-NEXT: br label [[DOTSPLIT]]
anatofuz
parents:
diff changeset
175 ; CHECK: .split:
anatofuz
parents:
diff changeset
176 ; CHECK-NEXT: [[MERGE:%.*]] = phi i64 [ [[I_NEXT:%.*]], [[BB0:%.*]] ], [ 0, [[BB0_CLONE:%.*]] ]
anatofuz
parents:
diff changeset
177 ; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds i64, i64* [[P:%.*]], i64 [[MERGE]]
anatofuz
parents:
diff changeset
178 ; CHECK-NEXT: store i64 [[MERGE]], i64* [[TMP0]], align 4
anatofuz
parents:
diff changeset
179 ; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[MERGE]], 1
anatofuz
parents:
diff changeset
180 ; CHECK-NEXT: [[IDX:%.*]] = srem i64 [[MERGE]], 2
anatofuz
parents:
diff changeset
181 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* @loop.targets, i64 0, i64 [[IDX]]
anatofuz
parents:
diff changeset
182 ; CHECK-NEXT: [[TARGET:%.*]] = load i8*, i8** [[ARRAYIDX]], align 8
anatofuz
parents:
diff changeset
183 ; CHECK-NEXT: indirectbr i8* [[TARGET]], [label [[BB0]], label %bb1]
anatofuz
parents:
diff changeset
184 ; CHECK: bb1:
anatofuz
parents:
diff changeset
185 ; CHECK-NEXT: ret void
anatofuz
parents:
diff changeset
186 ;
anatofuz
parents:
diff changeset
187 entry:
anatofuz
parents:
diff changeset
188 br label %bb0
anatofuz
parents:
diff changeset
189
anatofuz
parents:
diff changeset
190 bb0:
anatofuz
parents:
diff changeset
191 %i = phi i64 [ %i.next, %bb0 ], [ 0, %entry ]
anatofuz
parents:
diff changeset
192 %tmp0 = getelementptr inbounds i64, i64* %p, i64 %i
anatofuz
parents:
diff changeset
193 store i64 %i, i64* %tmp0, align 4
anatofuz
parents:
diff changeset
194 %i.next = add nuw nsw i64 %i, 1
anatofuz
parents:
diff changeset
195 %idx = srem i64 %i, 2
anatofuz
parents:
diff changeset
196 %arrayidx = getelementptr inbounds [2 x i8*], [2 x i8*]* @loop.targets, i64 0, i64 %idx
anatofuz
parents:
diff changeset
197 %target = load i8*, i8** %arrayidx, align 8
anatofuz
parents:
diff changeset
198 indirectbr i8* %target, [label %bb0, label %bb1]
anatofuz
parents:
diff changeset
199
anatofuz
parents:
diff changeset
200 bb1:
anatofuz
parents:
diff changeset
201 ret void
anatofuz
parents:
diff changeset
202 }
anatofuz
parents:
diff changeset
203
anatofuz
parents:
diff changeset
204 ; Don't do anything for cases that contain no phis.
anatofuz
parents:
diff changeset
205 define void @nophi(i32* %p) {
anatofuz
parents:
diff changeset
206 ; CHECK-LABEL: @nophi(
anatofuz
parents:
diff changeset
207 ; CHECK-NEXT: entry:
anatofuz
parents:
diff changeset
208 ; CHECK-NEXT: [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, i32* [[P:%.*]], i64 1
anatofuz
parents:
diff changeset
209 ; CHECK-NEXT: [[INITOP:%.*]] = load i32, i32* [[INCDEC_PTR]], align 4
anatofuz
parents:
diff changeset
210 ; CHECK-NEXT: switch i32 [[INITOP]], label [[EXIT:%.*]] [
anatofuz
parents:
diff changeset
211 ; CHECK-NEXT: i32 0, label [[BB0:%.*]]
anatofuz
parents:
diff changeset
212 ; CHECK-NEXT: i32 1, label [[BB1:%.*]]
anatofuz
parents:
diff changeset
213 ; CHECK-NEXT: ]
anatofuz
parents:
diff changeset
214 ; CHECK: bb0:
anatofuz
parents:
diff changeset
215 ; CHECK-NEXT: tail call void @use(i32 0)
anatofuz
parents:
diff changeset
216 ; CHECK-NEXT: br label [[INDIRECTGOTO:%.*]]
anatofuz
parents:
diff changeset
217 ; CHECK: bb1:
anatofuz
parents:
diff changeset
218 ; CHECK-NEXT: tail call void @use(i32 1)
anatofuz
parents:
diff changeset
219 ; CHECK-NEXT: br label [[INDIRECTGOTO]]
anatofuz
parents:
diff changeset
220 ; CHECK: indirectgoto:
anatofuz
parents:
diff changeset
221 ; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[P]] to i8*
anatofuz
parents:
diff changeset
222 ; CHECK-NEXT: [[SUNKADDR:%.*]] = getelementptr inbounds i8, i8* [[TMP0]], i64 4
anatofuz
parents:
diff changeset
223 ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[SUNKADDR]] to i32*
anatofuz
parents:
diff changeset
224 ; CHECK-NEXT: [[NEWP:%.*]] = load i32, i32* [[TMP1]], align 4
anatofuz
parents:
diff changeset
225 ; CHECK-NEXT: [[IDX:%.*]] = sext i32 [[NEWP]] to i64
anatofuz
parents:
diff changeset
226 ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8*], [2 x i8*]* @nophi.targets, i64 0, i64 [[IDX]]
anatofuz
parents:
diff changeset
227 ; CHECK-NEXT: [[NEWOP:%.*]] = load i8*, i8** [[ARRAYIDX]], align 8
anatofuz
parents:
diff changeset
228 ; CHECK-NEXT: indirectbr i8* [[NEWOP]], [label [[BB0]], label %bb1]
anatofuz
parents:
diff changeset
229 ; CHECK: exit:
anatofuz
parents:
diff changeset
230 ; CHECK-NEXT: ret void
anatofuz
parents:
diff changeset
231 ;
anatofuz
parents:
diff changeset
232 entry:
anatofuz
parents:
diff changeset
233 %incdec.ptr = getelementptr inbounds i32, i32* %p, i64 1
anatofuz
parents:
diff changeset
234 %initop = load i32, i32* %incdec.ptr, align 4
anatofuz
parents:
diff changeset
235 switch i32 %initop, label %exit [
anatofuz
parents:
diff changeset
236 i32 0, label %bb0
anatofuz
parents:
diff changeset
237 i32 1, label %bb1
anatofuz
parents:
diff changeset
238 ]
anatofuz
parents:
diff changeset
239
anatofuz
parents:
diff changeset
240 bb0:
anatofuz
parents:
diff changeset
241 tail call void @use(i32 0) br label %indirectgoto
anatofuz
parents:
diff changeset
242
anatofuz
parents:
diff changeset
243 bb1:
anatofuz
parents:
diff changeset
244 tail call void @use(i32 1)
anatofuz
parents:
diff changeset
245 br label %indirectgoto
anatofuz
parents:
diff changeset
246
anatofuz
parents:
diff changeset
247 indirectgoto:
anatofuz
parents:
diff changeset
248 %newp = load i32, i32* %incdec.ptr, align 4
anatofuz
parents:
diff changeset
249 %idx = sext i32 %newp to i64
anatofuz
parents:
diff changeset
250 %arrayidx = getelementptr inbounds [2 x i8*], [2 x i8*]* @nophi.targets, i64 0, i64 %idx
anatofuz
parents:
diff changeset
251 %newop = load i8*, i8** %arrayidx, align 8
anatofuz
parents:
diff changeset
252 indirectbr i8* %newop, [label %bb0, label %bb1]
anatofuz
parents:
diff changeset
253
anatofuz
parents:
diff changeset
254 exit:
anatofuz
parents:
diff changeset
255 ret void
anatofuz
parents:
diff changeset
256 }
anatofuz
parents:
diff changeset
257
anatofuz
parents:
diff changeset
258 ; Don't do anything if the edge isn't critical.
anatofuz
parents:
diff changeset
259 define i32 @noncritical(i32 %k, i8* %p)
anatofuz
parents:
diff changeset
260 ; CHECK-LABEL: @noncritical(
anatofuz
parents:
diff changeset
261 ; CHECK-NEXT: entry:
anatofuz
parents:
diff changeset
262 ; CHECK-NEXT: [[D:%.*]] = add i32 [[K:%.*]], 1
anatofuz
parents:
diff changeset
263 ; CHECK-NEXT: indirectbr i8* [[P:%.*]], [label [[BB0:%.*]], label %bb1]
anatofuz
parents:
diff changeset
264 ; CHECK: bb0:
anatofuz
parents:
diff changeset
265 ; CHECK-NEXT: [[R0:%.*]] = sub i32 [[K]], [[D]]
anatofuz
parents:
diff changeset
266 ; CHECK-NEXT: br label [[EXIT:%.*]]
anatofuz
parents:
diff changeset
267 ; CHECK: bb1:
anatofuz
parents:
diff changeset
268 ; CHECK-NEXT: [[R1:%.*]] = sub i32 [[D]], [[K]]
anatofuz
parents:
diff changeset
269 ; CHECK-NEXT: br label [[EXIT]]
anatofuz
parents:
diff changeset
270 ; CHECK: exit:
anatofuz
parents:
diff changeset
271 ; CHECK-NEXT: [[V:%.*]] = phi i32 [ [[R0]], [[BB0]] ], [ [[R1]], [[BB1:%.*]] ]
anatofuz
parents:
diff changeset
272 ; CHECK-NEXT: ret i32 0
anatofuz
parents:
diff changeset
273 ;
anatofuz
parents:
diff changeset
274 {
anatofuz
parents:
diff changeset
275 entry:
anatofuz
parents:
diff changeset
276 %d = add i32 %k, 1
anatofuz
parents:
diff changeset
277 indirectbr i8* %p, [label %bb0, label %bb1]
anatofuz
parents:
diff changeset
278
anatofuz
parents:
diff changeset
279 bb0:
anatofuz
parents:
diff changeset
280 %v00 = phi i32 [%k, %entry]
anatofuz
parents:
diff changeset
281 %v01 = phi i32 [%d, %entry]
anatofuz
parents:
diff changeset
282 %r0 = sub i32 %v00, %v01
anatofuz
parents:
diff changeset
283 br label %exit
anatofuz
parents:
diff changeset
284
anatofuz
parents:
diff changeset
285 bb1:
anatofuz
parents:
diff changeset
286 %v10 = phi i32 [%d, %entry]
anatofuz
parents:
diff changeset
287 %v11 = phi i32 [%k, %entry]
anatofuz
parents:
diff changeset
288 %r1 = sub i32 %v10, %v11
anatofuz
parents:
diff changeset
289 br label %exit
anatofuz
parents:
diff changeset
290
anatofuz
parents:
diff changeset
291 exit:
anatofuz
parents:
diff changeset
292 %v = phi i32 [%r0, %bb0], [%r1, %bb1]
anatofuz
parents:
diff changeset
293 ret i32 0
anatofuz
parents:
diff changeset
294 }