xref: /aosp_15_r20/external/llvm/test/Transforms/SimplifyCFG/indirectbr.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -simplifycfg < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should eliminate redundant indirectbr edges.
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker; CHECK: indbrtest0
6*9880d681SAndroid Build Coastguard Worker; CHECK: indirectbr i8* %t, [label %BB0, label %BB1, label %BB2]
7*9880d681SAndroid Build Coastguard Worker; CHECK: %x = phi i32 [ 0, %BB0 ], [ 1, %entry ]
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Workerdeclare void @foo()
10*9880d681SAndroid Build Coastguard Workerdeclare void @A()
11*9880d681SAndroid Build Coastguard Workerdeclare void @B(i32)
12*9880d681SAndroid Build Coastguard Workerdeclare void @C()
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest0(i8** %P, i8** %Q) {
15*9880d681SAndroid Build Coastguard Workerentry:
16*9880d681SAndroid Build Coastguard Worker  store i8* blockaddress(@indbrtest0, %BB0), i8** %P
17*9880d681SAndroid Build Coastguard Worker  store i8* blockaddress(@indbrtest0, %BB1), i8** %P
18*9880d681SAndroid Build Coastguard Worker  store i8* blockaddress(@indbrtest0, %BB2), i8** %P
19*9880d681SAndroid Build Coastguard Worker  call void @foo()
20*9880d681SAndroid Build Coastguard Worker  %t = load i8*, i8** %Q
21*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %t, [label %BB0, label %BB1, label %BB2, label %BB0, label %BB1, label %BB2]
22*9880d681SAndroid Build Coastguard WorkerBB0:
23*9880d681SAndroid Build Coastguard Worker  call void @A()
24*9880d681SAndroid Build Coastguard Worker  br label %BB1
25*9880d681SAndroid Build Coastguard WorkerBB1:
26*9880d681SAndroid Build Coastguard Worker  %x = phi i32 [ 0, %BB0 ], [ 1, %entry ], [ 1, %entry ]
27*9880d681SAndroid Build Coastguard Worker  call void @B(i32 %x)
28*9880d681SAndroid Build Coastguard Worker  ret void
29*9880d681SAndroid Build Coastguard WorkerBB2:
30*9880d681SAndroid Build Coastguard Worker  call void @C()
31*9880d681SAndroid Build Coastguard Worker  ret void
32*9880d681SAndroid Build Coastguard Worker}
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should convert the indirectbr into a directbr. It would be even
35*9880d681SAndroid Build Coastguard Worker; better if it removed the branch altogether, but simplifycfdg currently misses
36*9880d681SAndroid Build Coastguard Worker; that because the predecessor is the entry block.
37*9880d681SAndroid Build Coastguard Worker
38*9880d681SAndroid Build Coastguard Worker; CHECK: indbrtest1
39*9880d681SAndroid Build Coastguard Worker; CHECK: br label %BB0
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest1(i8** %P, i8** %Q) {
42*9880d681SAndroid Build Coastguard Workerentry:
43*9880d681SAndroid Build Coastguard Worker  store i8* blockaddress(@indbrtest1, %BB0), i8** %P
44*9880d681SAndroid Build Coastguard Worker  call void @foo()
45*9880d681SAndroid Build Coastguard Worker  %t = load i8*, i8** %Q
46*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %t, [label %BB0, label %BB0]
47*9880d681SAndroid Build Coastguard WorkerBB0:
48*9880d681SAndroid Build Coastguard Worker  call void @A()
49*9880d681SAndroid Build Coastguard Worker  ret void
50*9880d681SAndroid Build Coastguard Worker}
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should notice that BB0 does not have its address taken and
53*9880d681SAndroid Build Coastguard Worker; remove it from entry's successor list.
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker; CHECK: indbrtest2
56*9880d681SAndroid Build Coastguard Worker; CHECK: entry:
57*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest2(i8* %t) {
60*9880d681SAndroid Build Coastguard Workerentry:
61*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %t, [label %BB0, label %BB0]
62*9880d681SAndroid Build Coastguard WorkerBB0:
63*9880d681SAndroid Build Coastguard Worker  ret void
64*9880d681SAndroid Build Coastguard Worker}
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker; Make sure the blocks in the next few tests aren't trivially removable as
68*9880d681SAndroid Build Coastguard Worker; successors by taking their addresses.
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker@anchor = constant [13 x i8*] [
71*9880d681SAndroid Build Coastguard Worker  i8* blockaddress(@indbrtest3, %L1), i8* blockaddress(@indbrtest3, %L2), i8* blockaddress(@indbrtest3, %L3),
72*9880d681SAndroid Build Coastguard Worker  i8* blockaddress(@indbrtest4, %L1), i8* blockaddress(@indbrtest4, %L2), i8* blockaddress(@indbrtest4, %L3),
73*9880d681SAndroid Build Coastguard Worker  i8* blockaddress(@indbrtest5, %L1), i8* blockaddress(@indbrtest5, %L2), i8* blockaddress(@indbrtest5, %L3), i8* blockaddress(@indbrtest5, %L4),
74*9880d681SAndroid Build Coastguard Worker  i8* blockaddress(@indbrtest6, %L1), i8* blockaddress(@indbrtest6, %L2), i8* blockaddress(@indbrtest6, %L3)
75*9880d681SAndroid Build Coastguard Worker]
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should turn the indirectbr into a conditional branch on the
78*9880d681SAndroid Build Coastguard Worker; condition of the select.
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @indbrtest3(
81*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br i1 %cond, label %L1, label %L2
83*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: indirectbr
84*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: br
85*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: L3:
86*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest3(i1 %cond, i8* %address) nounwind {
87*9880d681SAndroid Build Coastguard Workerentry:
88*9880d681SAndroid Build Coastguard Worker  %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest3, %L1), i8* blockaddress(@indbrtest3, %L2)
89*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3]
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard WorkerL1:
92*9880d681SAndroid Build Coastguard Worker  call void @A()
93*9880d681SAndroid Build Coastguard Worker  ret void
94*9880d681SAndroid Build Coastguard WorkerL2:
95*9880d681SAndroid Build Coastguard Worker  call void @C()
96*9880d681SAndroid Build Coastguard Worker  ret void
97*9880d681SAndroid Build Coastguard WorkerL3:
98*9880d681SAndroid Build Coastguard Worker  call void @foo()
99*9880d681SAndroid Build Coastguard Worker  ret void
100*9880d681SAndroid Build Coastguard Worker}
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should turn the indirectbr into an unconditional branch to the
103*9880d681SAndroid Build Coastguard Worker; only possible destination.
104*9880d681SAndroid Build Coastguard Worker; As in @indbrtest1, it should really remove the branch entirely, but it doesn't
105*9880d681SAndroid Build Coastguard Worker; because it's in the entry block.
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @indbrtest4(
108*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
109*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %L1
110*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest4(i1 %cond) nounwind {
111*9880d681SAndroid Build Coastguard Workerentry:
112*9880d681SAndroid Build Coastguard Worker  %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest4, %L1), i8* blockaddress(@indbrtest4, %L1)
113*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3]
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard WorkerL1:
116*9880d681SAndroid Build Coastguard Worker  call void @A()
117*9880d681SAndroid Build Coastguard Worker  ret void
118*9880d681SAndroid Build Coastguard WorkerL2:
119*9880d681SAndroid Build Coastguard Worker  call void @C()
120*9880d681SAndroid Build Coastguard Worker  ret void
121*9880d681SAndroid Build Coastguard WorkerL3:
122*9880d681SAndroid Build Coastguard Worker  call void @foo()
123*9880d681SAndroid Build Coastguard Worker  ret void
124*9880d681SAndroid Build Coastguard Worker}
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker; SimplifyCFG should turn the indirectbr into an unreachable because neither
127*9880d681SAndroid Build Coastguard Worker; destination is listed as a successor.
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @indbrtest5(
130*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
131*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable
132*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
133*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest5(i1 %cond, i8* %anchor) nounwind {
134*9880d681SAndroid Build Coastguard Workerentry:
135*9880d681SAndroid Build Coastguard Worker  %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest5, %L1), i8* blockaddress(@indbrtest5, %L2)
136*9880d681SAndroid Build Coastguard Worker; This needs to have more than one successor for this test, otherwise it gets
137*9880d681SAndroid Build Coastguard Worker; replaced with an unconditional branch to the single successor.
138*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %indirect.goto.dest, [label %L3, label %L4]
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard WorkerL1:
141*9880d681SAndroid Build Coastguard Worker  call void @A()
142*9880d681SAndroid Build Coastguard Worker  ret void
143*9880d681SAndroid Build Coastguard WorkerL2:
144*9880d681SAndroid Build Coastguard Worker  call void @C()
145*9880d681SAndroid Build Coastguard Worker  ret void
146*9880d681SAndroid Build Coastguard WorkerL3:
147*9880d681SAndroid Build Coastguard Worker  call void @foo()
148*9880d681SAndroid Build Coastguard Worker  ret void
149*9880d681SAndroid Build Coastguard WorkerL4:
150*9880d681SAndroid Build Coastguard Worker  call void @foo()
151*9880d681SAndroid Build Coastguard Worker
152*9880d681SAndroid Build Coastguard Worker; This keeps blockaddresses not otherwise listed as successors from being zapped
153*9880d681SAndroid Build Coastguard Worker; before SimplifyCFG even looks at the indirectbr.
154*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %anchor, [label %L1, label %L2]
155*9880d681SAndroid Build Coastguard Worker}
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker; The same as above, except the selected addresses are equal.
158*9880d681SAndroid Build Coastguard Worker
159*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @indbrtest6(
160*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
161*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: unreachable
162*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: }
163*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest6(i1 %cond, i8* %anchor) nounwind {
164*9880d681SAndroid Build Coastguard Workerentry:
165*9880d681SAndroid Build Coastguard Worker  %indirect.goto.dest = select i1 %cond, i8* blockaddress(@indbrtest6, %L1), i8* blockaddress(@indbrtest6, %L1)
166*9880d681SAndroid Build Coastguard Worker; This needs to have more than one successor for this test, otherwise it gets
167*9880d681SAndroid Build Coastguard Worker; replaced with an unconditional branch to the single successor.
168*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %indirect.goto.dest, [label %L2, label %L3]
169*9880d681SAndroid Build Coastguard Worker
170*9880d681SAndroid Build Coastguard WorkerL1:
171*9880d681SAndroid Build Coastguard Worker  call void @A()
172*9880d681SAndroid Build Coastguard Worker  ret void
173*9880d681SAndroid Build Coastguard WorkerL2:
174*9880d681SAndroid Build Coastguard Worker  call void @C()
175*9880d681SAndroid Build Coastguard Worker  ret void
176*9880d681SAndroid Build Coastguard WorkerL3:
177*9880d681SAndroid Build Coastguard Worker  call void @foo()
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker; This keeps blockaddresses not otherwise listed as successors from being zapped
180*9880d681SAndroid Build Coastguard Worker; before SimplifyCFG even looks at the indirectbr.
181*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %anchor, [label %L1, label %L2]
182*9880d681SAndroid Build Coastguard Worker}
183*9880d681SAndroid Build Coastguard Worker
184*9880d681SAndroid Build Coastguard Worker; PR10072
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Worker@xblkx.bbs = internal unnamed_addr constant [9 x i8*] [i8* blockaddress(@indbrtest7, %xblkx.begin), i8* blockaddress(@indbrtest7, %xblkx.begin3), i8* blockaddress(@indbrtest7, %xblkx.begin4), i8* blockaddress(@indbrtest7, %xblkx.begin5), i8* blockaddress(@indbrtest7, %xblkx.begin6), i8* blockaddress(@indbrtest7, %xblkx.begin7), i8* blockaddress(@indbrtest7, %xblkx.begin8), i8* blockaddress(@indbrtest7, %xblkx.begin9), i8* blockaddress(@indbrtest7, %xblkx.end)]
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Workerdefine void @indbrtest7() {
189*9880d681SAndroid Build Coastguard Workerescape-string.top:
190*9880d681SAndroid Build Coastguard Worker  %xval202x = call i32 @xfunc5x()
191*9880d681SAndroid Build Coastguard Worker  br label %xlab5x
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Workerxlab8x:                                           ; preds = %xlab5x
194*9880d681SAndroid Build Coastguard Worker  %xvaluex = call i32 @xselectorx()
195*9880d681SAndroid Build Coastguard Worker  %xblkx.x = getelementptr [9 x i8*], [9 x i8*]* @xblkx.bbs, i32 0, i32 %xvaluex
196*9880d681SAndroid Build Coastguard Worker  %xblkx.load = load i8*, i8** %xblkx.x
197*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %xblkx.load, [label %xblkx.begin, label %xblkx.begin3, label %xblkx.begin4, label %xblkx.begin5, label %xblkx.begin6, label %xblkx.begin7, label %xblkx.begin8, label %xblkx.begin9, label %xblkx.end]
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Workerxblkx.begin:
200*9880d681SAndroid Build Coastguard Worker  br label %xblkx.end
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Workerxblkx.begin3:
203*9880d681SAndroid Build Coastguard Worker  br label %xblkx.end
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Workerxblkx.begin4:
206*9880d681SAndroid Build Coastguard Worker  br label %xblkx.end
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Workerxblkx.begin5:
209*9880d681SAndroid Build Coastguard Worker  br label %xblkx.end
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Workerxblkx.begin6:
212*9880d681SAndroid Build Coastguard Worker  br label %xblkx.end
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Workerxblkx.begin7:
215*9880d681SAndroid Build Coastguard Worker  br label %xblkx.end
216*9880d681SAndroid Build Coastguard Worker
217*9880d681SAndroid Build Coastguard Workerxblkx.begin8:
218*9880d681SAndroid Build Coastguard Worker  br label %xblkx.end
219*9880d681SAndroid Build Coastguard Worker
220*9880d681SAndroid Build Coastguard Workerxblkx.begin9:
221*9880d681SAndroid Build Coastguard Worker  br label %xblkx.end
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Workerxblkx.end:
224*9880d681SAndroid Build Coastguard Worker  %yes.0 = phi i1 [ false, %xblkx.begin ], [ true, %xlab8x ], [ false, %xblkx.begin9 ], [ false, %xblkx.begin8 ], [ false, %xblkx.begin7 ], [ false, %xblkx.begin6 ], [ false, %xblkx.begin5 ], [ true, %xblkx.begin4 ], [ false, %xblkx.begin3 ]
225*9880d681SAndroid Build Coastguard Worker  br i1 %yes.0, label %v2j, label %xlab17x
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Workerv2j:
228*9880d681SAndroid Build Coastguard Worker; CHECK: %xunusedx = call i32 @xactionx()
229*9880d681SAndroid Build Coastguard Worker  %xunusedx = call i32 @xactionx()
230*9880d681SAndroid Build Coastguard Worker  br label %xlab4x
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Workerxlab17x:
233*9880d681SAndroid Build Coastguard Worker  br label %xlab4x
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Workerxlab4x:
236*9880d681SAndroid Build Coastguard Worker  %incr19 = add i32 %xval704x.0, 1
237*9880d681SAndroid Build Coastguard Worker  br label %xlab5x
238*9880d681SAndroid Build Coastguard Worker
239*9880d681SAndroid Build Coastguard Workerxlab5x:
240*9880d681SAndroid Build Coastguard Worker  %xval704x.0 = phi i32 [ 0, %escape-string.top ], [ %incr19, %xlab4x ]
241*9880d681SAndroid Build Coastguard Worker  %xval10x = icmp ult i32 %xval704x.0, %xval202x
242*9880d681SAndroid Build Coastguard Worker  br i1 %xval10x, label %xlab8x, label %xlab9x
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Workerxlab9x:
245*9880d681SAndroid Build Coastguard Worker  ret void
246*9880d681SAndroid Build Coastguard Worker}
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Workerdeclare i32 @xfunc5x()
249*9880d681SAndroid Build Coastguard Workerdeclare i8 @xfunc7x()
250*9880d681SAndroid Build Coastguard Workerdeclare i32 @xselectorx()
251*9880d681SAndroid Build Coastguard Workerdeclare i32 @xactionx()
252