xref: /aosp_15_r20/external/llvm/test/Transforms/JumpThreading/select.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt -S -jump-threading < %s | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Workerdeclare void @foo()
4*9880d681SAndroid Build Coastguard Workerdeclare void @bar()
5*9880d681SAndroid Build Coastguard Workerdeclare void @baz()
6*9880d681SAndroid Build Coastguard Workerdeclare void @quux()
7*9880d681SAndroid Build Coastguard Worker
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker; Jump threading of branch with select as condition.
10*9880d681SAndroid Build Coastguard Worker; Mostly theoretical since instruction combining simplifies all selects of
11*9880d681SAndroid Build Coastguard Worker; booleans where at least one operand is true/false/undef.
12*9880d681SAndroid Build Coastguard Worker
13*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_br(
14*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
15*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br i1 %cond, label %L1,
16*9880d681SAndroid Build Coastguard Workerdefine void @test_br(i1 %cond, i1 %value) nounwind {
17*9880d681SAndroid Build Coastguard Workerentry:
18*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %L0, label %L3
19*9880d681SAndroid Build Coastguard WorkerL0:
20*9880d681SAndroid Build Coastguard Worker  %expr = select i1 %cond, i1 true, i1 %value
21*9880d681SAndroid Build Coastguard Worker  br i1 %expr, label %L1, label %L2
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard WorkerL1:
24*9880d681SAndroid Build Coastguard Worker  call void @foo()
25*9880d681SAndroid Build Coastguard Worker  ret void
26*9880d681SAndroid Build Coastguard WorkerL2:
27*9880d681SAndroid Build Coastguard Worker  call void @bar()
28*9880d681SAndroid Build Coastguard Worker  ret void
29*9880d681SAndroid Build Coastguard WorkerL3:
30*9880d681SAndroid Build Coastguard Worker  call void @baz()
31*9880d681SAndroid Build Coastguard Worker  br label %L0
32*9880d681SAndroid Build Coastguard Worker}
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Worker; Jump threading of switch with select as condition.
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_switch(
38*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
39*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br i1 %cond, label %L1,
40*9880d681SAndroid Build Coastguard Workerdefine void @test_switch(i1 %cond, i8 %value) nounwind {
41*9880d681SAndroid Build Coastguard Workerentry:
42*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %L0, label %L4
43*9880d681SAndroid Build Coastguard WorkerL0:
44*9880d681SAndroid Build Coastguard Worker  %expr = select i1 %cond, i8 1, i8 %value
45*9880d681SAndroid Build Coastguard Worker  switch i8 %expr, label %L3 [i8 1, label %L1 i8 2, label %L2]
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard WorkerL1:
48*9880d681SAndroid Build Coastguard Worker  call void @foo()
49*9880d681SAndroid Build Coastguard Worker  ret void
50*9880d681SAndroid Build Coastguard WorkerL2:
51*9880d681SAndroid Build Coastguard Worker  call void @bar()
52*9880d681SAndroid Build Coastguard Worker  ret void
53*9880d681SAndroid Build Coastguard WorkerL3:
54*9880d681SAndroid Build Coastguard Worker  call void @baz()
55*9880d681SAndroid Build Coastguard Worker  ret void
56*9880d681SAndroid Build Coastguard WorkerL4:
57*9880d681SAndroid Build Coastguard Worker  call void @quux()
58*9880d681SAndroid Build Coastguard Worker  br label %L0
59*9880d681SAndroid Build Coastguard Worker}
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker; Make sure the blocks in the indirectbr test aren't trivially removable as
62*9880d681SAndroid Build Coastguard Worker; successors by taking their addresses.
63*9880d681SAndroid Build Coastguard Worker@anchor = constant [3 x i8*] [
64*9880d681SAndroid Build Coastguard Worker  i8* blockaddress(@test_indirectbr, %L1),
65*9880d681SAndroid Build Coastguard Worker  i8* blockaddress(@test_indirectbr, %L2),
66*9880d681SAndroid Build Coastguard Worker  i8* blockaddress(@test_indirectbr, %L3)
67*9880d681SAndroid Build Coastguard Worker]
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker; Jump threading of indirectbr with select as address.
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_indirectbr(
73*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
74*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br i1 %cond, label %L1, label %L3
75*9880d681SAndroid Build Coastguard Workerdefine void @test_indirectbr(i1 %cond, i8* %address) nounwind {
76*9880d681SAndroid Build Coastguard Workerentry:
77*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %L0, label %L3
78*9880d681SAndroid Build Coastguard WorkerL0:
79*9880d681SAndroid Build Coastguard Worker  %indirect.goto.dest = select i1 %cond, i8* blockaddress(@test_indirectbr, %L1), i8* %address
80*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3]
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard WorkerL1:
83*9880d681SAndroid Build Coastguard Worker  call void @foo()
84*9880d681SAndroid Build Coastguard Worker  ret void
85*9880d681SAndroid Build Coastguard WorkerL2:
86*9880d681SAndroid Build Coastguard Worker  call void @bar()
87*9880d681SAndroid Build Coastguard Worker  ret void
88*9880d681SAndroid Build Coastguard WorkerL3:
89*9880d681SAndroid Build Coastguard Worker  call void @baz()
90*9880d681SAndroid Build Coastguard Worker  ret void
91*9880d681SAndroid Build Coastguard Worker}
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker; Jump threading of indirectbr with select as address.  Test increased
95*9880d681SAndroid Build Coastguard Worker; duplication threshold for cases where indirectbr is being threaded
96*9880d681SAndroid Build Coastguard Worker; through.
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_indirectbr_thresh(
99*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
100*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br i1 %cond, label %L1, label %L3
101*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: indirectbr
102*9880d681SAndroid Build Coastguard Workerdefine void @test_indirectbr_thresh(i1 %cond, i8* %address) nounwind {
103*9880d681SAndroid Build Coastguard Workerentry:
104*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %L0, label %L3
105*9880d681SAndroid Build Coastguard WorkerL0:
106*9880d681SAndroid Build Coastguard Worker  %indirect.goto.dest = select i1 %cond, i8* blockaddress(@test_indirectbr_thresh, %L1), i8* %address
107*9880d681SAndroid Build Coastguard Worker  call void @quux()
108*9880d681SAndroid Build Coastguard Worker  call void @quux()
109*9880d681SAndroid Build Coastguard Worker  call void @quux()
110*9880d681SAndroid Build Coastguard Worker  indirectbr i8* %indirect.goto.dest, [label %L1, label %L2, label %L3]
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard WorkerL1:
113*9880d681SAndroid Build Coastguard Worker  call void @foo()
114*9880d681SAndroid Build Coastguard Worker  ret void
115*9880d681SAndroid Build Coastguard WorkerL2:
116*9880d681SAndroid Build Coastguard Worker  call void @bar()
117*9880d681SAndroid Build Coastguard Worker  ret void
118*9880d681SAndroid Build Coastguard WorkerL3:
119*9880d681SAndroid Build Coastguard Worker  call void @baz()
120*9880d681SAndroid Build Coastguard Worker  ret void
121*9880d681SAndroid Build Coastguard Worker}
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker; A more complicated case: the condition is a select based on a comparison.
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @test_switch_cmp(
127*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: entry:
128*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br i1 %cond, label %L0, label %[[THREADED:[A-Za-z.0-9]+]]
129*9880d681SAndroid Build Coastguard Worker; CHECK: [[THREADED]]:
130*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: call void @quux
131*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: br label %L1
132*9880d681SAndroid Build Coastguard Workerdefine void @test_switch_cmp(i1 %cond, i32 %val, i8 %value) nounwind {
133*9880d681SAndroid Build Coastguard Workerentry:
134*9880d681SAndroid Build Coastguard Worker  br i1 %cond, label %L0, label %L4
135*9880d681SAndroid Build Coastguard WorkerL0:
136*9880d681SAndroid Build Coastguard Worker  %val.phi = phi i32 [%val, %entry], [-1, %L4]
137*9880d681SAndroid Build Coastguard Worker  %cmp = icmp slt i32 %val.phi, 0
138*9880d681SAndroid Build Coastguard Worker  %expr = select i1 %cmp, i8 1, i8 %value
139*9880d681SAndroid Build Coastguard Worker  switch i8 %expr, label %L3 [i8 1, label %L1 i8 2, label %L2]
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard WorkerL1:
142*9880d681SAndroid Build Coastguard Worker  call void @foo()
143*9880d681SAndroid Build Coastguard Worker  ret void
144*9880d681SAndroid Build Coastguard WorkerL2:
145*9880d681SAndroid Build Coastguard Worker  call void @bar()
146*9880d681SAndroid Build Coastguard Worker  ret void
147*9880d681SAndroid Build Coastguard WorkerL3:
148*9880d681SAndroid Build Coastguard Worker  call void @baz()
149*9880d681SAndroid Build Coastguard Worker  ret void
150*9880d681SAndroid Build Coastguard WorkerL4:
151*9880d681SAndroid Build Coastguard Worker  call void @quux()
152*9880d681SAndroid Build Coastguard Worker  br label %L0
153*9880d681SAndroid Build Coastguard Worker}
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Worker; Make sure the edge value of %0 from entry to L2 includes 0 and L3 is
156*9880d681SAndroid Build Coastguard Worker; reachable.
157*9880d681SAndroid Build Coastguard Worker; CHECK: test_switch_default
158*9880d681SAndroid Build Coastguard Worker; CHECK: entry:
159*9880d681SAndroid Build Coastguard Worker; CHECK: load
160*9880d681SAndroid Build Coastguard Worker; CHECK: icmp
161*9880d681SAndroid Build Coastguard Worker; CHECK: [[THREADED:[A-Za-z.0-9]+]]:
162*9880d681SAndroid Build Coastguard Worker; CHECK: store
163*9880d681SAndroid Build Coastguard Worker; CHECK: br
164*9880d681SAndroid Build Coastguard Worker; CHECK: L2:
165*9880d681SAndroid Build Coastguard Worker; CHECK: icmp
166*9880d681SAndroid Build Coastguard Workerdefine void @test_switch_default(i32* nocapture %status) nounwind {
167*9880d681SAndroid Build Coastguard Workerentry:
168*9880d681SAndroid Build Coastguard Worker  %0 = load i32, i32* %status, align 4
169*9880d681SAndroid Build Coastguard Worker  switch i32 %0, label %L2 [
170*9880d681SAndroid Build Coastguard Worker    i32 5061, label %L1
171*9880d681SAndroid Build Coastguard Worker    i32 0, label %L2
172*9880d681SAndroid Build Coastguard Worker  ]
173*9880d681SAndroid Build Coastguard Worker
174*9880d681SAndroid Build Coastguard WorkerL1:
175*9880d681SAndroid Build Coastguard Worker  store i32 10025, i32* %status, align 4
176*9880d681SAndroid Build Coastguard Worker  br label %L2
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard WorkerL2:
179*9880d681SAndroid Build Coastguard Worker  %1 = load i32, i32* %status, align 4
180*9880d681SAndroid Build Coastguard Worker  %cmp57.i = icmp eq i32 %1, 0
181*9880d681SAndroid Build Coastguard Worker  br i1 %cmp57.i, label %L3, label %L4
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard WorkerL3:
184*9880d681SAndroid Build Coastguard Worker  store i32 10000, i32* %status, align 4
185*9880d681SAndroid Build Coastguard Worker  br label %L4
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard WorkerL4:
188*9880d681SAndroid Build Coastguard Worker  ret void
189*9880d681SAndroid Build Coastguard Worker}
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Workerdefine void @unfold1(double %x, double %y) nounwind {
192*9880d681SAndroid Build Coastguard Workerentry:
193*9880d681SAndroid Build Coastguard Worker  %sub = fsub double %x, %y
194*9880d681SAndroid Build Coastguard Worker  %cmp = fcmp ogt double %sub, 1.000000e+01
195*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %cond.end4, label %cond.false
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Workercond.false:                                       ; preds = %entry
198*9880d681SAndroid Build Coastguard Worker  %add = fadd double %x, %y
199*9880d681SAndroid Build Coastguard Worker  %cmp1 = fcmp ogt double %add, 1.000000e+01
200*9880d681SAndroid Build Coastguard Worker  %add. = select i1 %cmp1, double %add, double 0.000000e+00
201*9880d681SAndroid Build Coastguard Worker  br label %cond.end4
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Workercond.end4:                                        ; preds = %entry, %cond.false
204*9880d681SAndroid Build Coastguard Worker  %cond5 = phi double [ %add., %cond.false ], [ %sub, %entry ]
205*9880d681SAndroid Build Coastguard Worker  %cmp6 = fcmp oeq double %cond5, 0.000000e+00
206*9880d681SAndroid Build Coastguard Worker  br i1 %cmp6, label %if.then, label %if.end
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %cond.end4
209*9880d681SAndroid Build Coastguard Worker  call void @foo()
210*9880d681SAndroid Build Coastguard Worker  br label %if.end
211*9880d681SAndroid Build Coastguard Worker
212*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.then, %cond.end4
213*9880d681SAndroid Build Coastguard Worker  ret void
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @unfold1
216*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp, label %cond.end4, label %cond.false
217*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp1, label %cond.end4, label %if.then
218*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp6, label %if.then, label %if.end
219*9880d681SAndroid Build Coastguard Worker; CHECK: br label %if.end
220*9880d681SAndroid Build Coastguard Worker}
221*9880d681SAndroid Build Coastguard Worker
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Workerdefine void @unfold2(i32 %x, i32 %y) nounwind {
224*9880d681SAndroid Build Coastguard Workerentry:
225*9880d681SAndroid Build Coastguard Worker  %sub = sub nsw i32 %x, %y
226*9880d681SAndroid Build Coastguard Worker  %cmp = icmp sgt i32 %sub, 10
227*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %cond.end4, label %cond.false
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Workercond.false:                                       ; preds = %entry
230*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %x, %y
231*9880d681SAndroid Build Coastguard Worker  %cmp1 = icmp sgt i32 %add, 10
232*9880d681SAndroid Build Coastguard Worker  %add. = select i1 %cmp1, i32 0, i32 %add
233*9880d681SAndroid Build Coastguard Worker  br label %cond.end4
234*9880d681SAndroid Build Coastguard Worker
235*9880d681SAndroid Build Coastguard Workercond.end4:                                        ; preds = %entry, %cond.false
236*9880d681SAndroid Build Coastguard Worker  %cond5 = phi i32 [ %add., %cond.false ], [ %sub, %entry ]
237*9880d681SAndroid Build Coastguard Worker  %cmp6 = icmp eq i32 %cond5, 0
238*9880d681SAndroid Build Coastguard Worker  br i1 %cmp6, label %if.then, label %if.end
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %cond.end4
241*9880d681SAndroid Build Coastguard Worker  call void @foo()
242*9880d681SAndroid Build Coastguard Worker  br label %if.end
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.then, %cond.end4
245*9880d681SAndroid Build Coastguard Worker  ret void
246*9880d681SAndroid Build Coastguard Worker
247*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @unfold2
248*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp, label %if.end, label %cond.false
249*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp1, label %if.then, label %cond.end4
250*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp6, label %if.then, label %if.end
251*9880d681SAndroid Build Coastguard Worker; CHECK: br label %if.end
252*9880d681SAndroid Build Coastguard Worker}
253*9880d681SAndroid Build Coastguard Worker
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Workerdefine i32 @unfold3(i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z, i32 %j) nounwind {
256*9880d681SAndroid Build Coastguard Workerentry:
257*9880d681SAndroid Build Coastguard Worker  %add3 = add nsw i32 %j, 2
258*9880d681SAndroid Build Coastguard Worker  %cmp.i = icmp slt i32 %u, %v
259*9880d681SAndroid Build Coastguard Worker  br i1 %cmp.i, label %.exit, label %cond.false.i
260*9880d681SAndroid Build Coastguard Worker
261*9880d681SAndroid Build Coastguard Workercond.false.i:                                     ; preds = %entry
262*9880d681SAndroid Build Coastguard Worker  %cmp4.i = icmp sgt i32 %u, %v
263*9880d681SAndroid Build Coastguard Worker  br i1 %cmp4.i, label %.exit, label %cond.false.6.i
264*9880d681SAndroid Build Coastguard Worker
265*9880d681SAndroid Build Coastguard Workercond.false.6.i:                                   ; preds = %cond.false.i
266*9880d681SAndroid Build Coastguard Worker  %cmp8.i = icmp slt i32 %w, %x
267*9880d681SAndroid Build Coastguard Worker  br i1 %cmp8.i, label %.exit, label %cond.false.10.i
268*9880d681SAndroid Build Coastguard Worker
269*9880d681SAndroid Build Coastguard Workercond.false.10.i:                                  ; preds = %cond.false.6.i
270*9880d681SAndroid Build Coastguard Worker  %cmp13.i = icmp sgt i32 %w, %x
271*9880d681SAndroid Build Coastguard Worker  br i1 %cmp13.i, label %.exit, label %cond.false.15.i
272*9880d681SAndroid Build Coastguard Worker
273*9880d681SAndroid Build Coastguard Workercond.false.15.i:                                  ; preds = %cond.false.10.i
274*9880d681SAndroid Build Coastguard Worker  %phitmp = icmp sge i32 %y, %z
275*9880d681SAndroid Build Coastguard Worker  br label %.exit
276*9880d681SAndroid Build Coastguard Worker
277*9880d681SAndroid Build Coastguard Worker.exit:                                  ; preds = %entry, %cond.false.i, %cond.false.6.i, %cond.false.10.i, %cond.false.15.i
278*9880d681SAndroid Build Coastguard Worker  %cond23.i = phi i1 [ false, %entry ], [ true, %cond.false.i ], [ false, %cond.false.6.i ], [ %phitmp, %cond.false.15.i ], [ true, %cond.false.10.i ]
279*9880d681SAndroid Build Coastguard Worker  %j.add3 = select i1 %cond23.i, i32 %j, i32 %add3
280*9880d681SAndroid Build Coastguard Worker  ret i32 %j.add3
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: @unfold3
283*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp.i, label %.exit.thread2, label %cond.false.i
284*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp4.i, label %.exit.thread, label %cond.false.6.i
285*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp8.i, label %.exit.thread2, label %cond.false.10.i
286*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %cmp13.i, label %.exit.thread, label %.exit
287*9880d681SAndroid Build Coastguard Worker; CHECK: br i1 %phitmp, label %.exit.thread, label %.exit.thread2
288*9880d681SAndroid Build Coastguard Worker; CHECK: br label %.exit.thread2
289*9880d681SAndroid Build Coastguard Worker}
290