xref: /aosp_15_r20/external/llvm/test/CodeGen/X86/switch-bt.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc -march=x86-64 -asm-verbose=false < %s -jump-table-density=40 | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker; This switch should use bit tests, and the third bit test case is just
4*9880d681SAndroid Build Coastguard Worker; testing for one possible value, so it doesn't need a bt.
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker;      CHECK: movabsq $2305843009482129440, %r
7*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: btq %rax, %r
8*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jb
9*9880d681SAndroid Build Coastguard Worker;     CHECK: movl  $671088640, %e
10*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: btq %rax, %r
11*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jae
12*9880d681SAndroid Build Coastguard Worker;      CHECK: testq %rax, %r
13*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: j
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Workerdefine void @test(i8* %l) nounwind {
16*9880d681SAndroid Build Coastguard Workerentry:
17*9880d681SAndroid Build Coastguard Worker  %l.addr = alloca i8*, align 8                   ; <i8**> [#uses=2]
18*9880d681SAndroid Build Coastguard Worker  store i8* %l, i8** %l.addr
19*9880d681SAndroid Build Coastguard Worker  %tmp = load i8*, i8** %l.addr                        ; <i8*> [#uses=1]
20*9880d681SAndroid Build Coastguard Worker  %tmp1 = load i8, i8* %tmp                           ; <i8> [#uses=1]
21*9880d681SAndroid Build Coastguard Worker  %conv = sext i8 %tmp1 to i32                    ; <i32> [#uses=1]
22*9880d681SAndroid Build Coastguard Worker  switch i32 %conv, label %sw.default [
23*9880d681SAndroid Build Coastguard Worker    i32 62, label %sw.bb
24*9880d681SAndroid Build Coastguard Worker    i32 60, label %sw.bb
25*9880d681SAndroid Build Coastguard Worker    i32 38, label %sw.bb2
26*9880d681SAndroid Build Coastguard Worker    i32 94, label %sw.bb2
27*9880d681SAndroid Build Coastguard Worker    i32 61, label %sw.bb2
28*9880d681SAndroid Build Coastguard Worker    i32 33, label %sw.bb4
29*9880d681SAndroid Build Coastguard Worker  ]
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Workersw.bb:                                            ; preds = %entry, %entry
32*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 0)
33*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
34*9880d681SAndroid Build Coastguard Worker
35*9880d681SAndroid Build Coastguard Workersw.bb2:                                           ; preds = %entry, %entry, %entry
36*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 1)
37*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Workersw.bb4:                                           ; preds = %entry
40*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 3)
41*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Workersw.default:                                       ; preds = %entry
44*9880d681SAndroid Build Coastguard Worker  call void @foo(i32 97)
45*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Workersw.epilog:                                        ; preds = %sw.default, %sw.bb4, %sw.bb2, %sw.bb
48*9880d681SAndroid Build Coastguard Worker  ret void
49*9880d681SAndroid Build Coastguard Worker}
50*9880d681SAndroid Build Coastguard Worker
51*9880d681SAndroid Build Coastguard Workerdeclare void @foo(i32)
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker; Don't zero extend the test operands to pointer type if it can be avoided.
54*9880d681SAndroid Build Coastguard Worker; rdar://8781238
55*9880d681SAndroid Build Coastguard Workerdefine void @test2(i32 %x) nounwind ssp {
56*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test2:
57*9880d681SAndroid Build Coastguard Worker; CHECK: cmpl $6
58*9880d681SAndroid Build Coastguard Worker; CHECK: ja
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl $91
61*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: movl
62*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: btl
63*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: jae
64*9880d681SAndroid Build Coastguard Workerentry:
65*9880d681SAndroid Build Coastguard Worker  switch i32 %x, label %if.end [
66*9880d681SAndroid Build Coastguard Worker    i32 6, label %if.then
67*9880d681SAndroid Build Coastguard Worker    i32 4, label %if.then
68*9880d681SAndroid Build Coastguard Worker    i32 3, label %if.then
69*9880d681SAndroid Build Coastguard Worker    i32 1, label %if.then
70*9880d681SAndroid Build Coastguard Worker    i32 0, label %if.then
71*9880d681SAndroid Build Coastguard Worker  ]
72*9880d681SAndroid Build Coastguard Worker
73*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry, %entry, %entry, %entry, %entry
74*9880d681SAndroid Build Coastguard Worker  tail call void @bar() nounwind
75*9880d681SAndroid Build Coastguard Worker  ret void
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %entry
78*9880d681SAndroid Build Coastguard Worker  ret void
79*9880d681SAndroid Build Coastguard Worker}
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Workerdeclare void @bar()
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Workerdefine void @test3(i32 %x) nounwind {
84*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test3:
85*9880d681SAndroid Build Coastguard Worker; CHECK: cmpl $5
86*9880d681SAndroid Build Coastguard Worker; CHECK: ja
87*9880d681SAndroid Build Coastguard Worker; CHECK: cmpl $4
88*9880d681SAndroid Build Coastguard Worker; CHECK: je
89*9880d681SAndroid Build Coastguard Worker  switch i32 %x, label %if.end [
90*9880d681SAndroid Build Coastguard Worker    i32 0, label %if.then
91*9880d681SAndroid Build Coastguard Worker    i32 1, label %if.then
92*9880d681SAndroid Build Coastguard Worker    i32 2, label %if.then
93*9880d681SAndroid Build Coastguard Worker    i32 3, label %if.then
94*9880d681SAndroid Build Coastguard Worker    i32 5, label %if.then
95*9880d681SAndroid Build Coastguard Worker  ]
96*9880d681SAndroid Build Coastguard Workerif.then:
97*9880d681SAndroid Build Coastguard Worker  tail call void @bar() nounwind
98*9880d681SAndroid Build Coastguard Worker  ret void
99*9880d681SAndroid Build Coastguard Workerif.end:
100*9880d681SAndroid Build Coastguard Worker  ret void
101*9880d681SAndroid Build Coastguard Worker}
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker; Ensure that optimizing for jump tables doesn't needlessly deteriorate the
104*9880d681SAndroid Build Coastguard Worker; created binary tree search. See PR22262.
105*9880d681SAndroid Build Coastguard Workerdefine void @test4(i32 %x, i32* %y) {
106*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: test4:
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Workerentry:
109*9880d681SAndroid Build Coastguard Worker  switch i32 %x, label %sw.default [
110*9880d681SAndroid Build Coastguard Worker    i32 10, label %sw.bb
111*9880d681SAndroid Build Coastguard Worker    i32 20, label %sw.bb1
112*9880d681SAndroid Build Coastguard Worker    i32 30, label %sw.bb2
113*9880d681SAndroid Build Coastguard Worker    i32 40, label %sw.bb3
114*9880d681SAndroid Build Coastguard Worker    i32 50, label %sw.bb4
115*9880d681SAndroid Build Coastguard Worker    i32 60, label %sw.bb5
116*9880d681SAndroid Build Coastguard Worker  ]
117*9880d681SAndroid Build Coastguard Workersw.bb:
118*9880d681SAndroid Build Coastguard Worker  store i32 1, i32* %y
119*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
120*9880d681SAndroid Build Coastguard Workersw.bb1:
121*9880d681SAndroid Build Coastguard Worker  store i32 2, i32* %y
122*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
123*9880d681SAndroid Build Coastguard Workersw.bb2:
124*9880d681SAndroid Build Coastguard Worker  store i32 3, i32* %y
125*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
126*9880d681SAndroid Build Coastguard Workersw.bb3:
127*9880d681SAndroid Build Coastguard Worker  store i32 4, i32* %y
128*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
129*9880d681SAndroid Build Coastguard Workersw.bb4:
130*9880d681SAndroid Build Coastguard Worker  store i32 5, i32* %y
131*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
132*9880d681SAndroid Build Coastguard Workersw.bb5:
133*9880d681SAndroid Build Coastguard Worker  store i32 6, i32* %y
134*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
135*9880d681SAndroid Build Coastguard Workersw.default:
136*9880d681SAndroid Build Coastguard Worker  store i32 7, i32* %y
137*9880d681SAndroid Build Coastguard Worker  br label %sw.epilog
138*9880d681SAndroid Build Coastguard Workersw.epilog:
139*9880d681SAndroid Build Coastguard Worker  ret void
140*9880d681SAndroid Build Coastguard Worker
141*9880d681SAndroid Build Coastguard Worker; The balanced binary switch here would start with a comparison against 39, but
142*9880d681SAndroid Build Coastguard Worker; it is currently starting with 29 because of the density-sum heuristic.
143*9880d681SAndroid Build Coastguard Worker; CHECK: cmpl $39
144*9880d681SAndroid Build Coastguard Worker; CHECK: jg
145*9880d681SAndroid Build Coastguard Worker; CHECK: cmpl $10
146*9880d681SAndroid Build Coastguard Worker; CHECK: je
147*9880d681SAndroid Build Coastguard Worker; CHECK: cmpl $20
148*9880d681SAndroid Build Coastguard Worker; CHECK: je
149*9880d681SAndroid Build Coastguard Worker; CHECK: cmpl $30
150*9880d681SAndroid Build Coastguard Worker; CHECK: jne
151*9880d681SAndroid Build Coastguard Worker; CHECK: cmpl $40
152*9880d681SAndroid Build Coastguard Worker; CHECK: je
153*9880d681SAndroid Build Coastguard Worker; CHECK: cmpl $50
154*9880d681SAndroid Build Coastguard Worker; CHECK: je
155*9880d681SAndroid Build Coastguard Worker; CHECK: cmpl $60
156*9880d681SAndroid Build Coastguard Worker; CHECK: jne
157*9880d681SAndroid Build Coastguard Worker}
158