xref: /llvm-project/llvm/test/CodeGen/AArch64/jump-table.ll (revision bdc0afc87181d4f7ab8aad2da6fa70a1204f0a84)
1; RUN: llc -no-integrated-as -verify-machineinstrs -o - %s -aarch64-min-jump-table-entries=4 -mtriple=aarch64-none-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 | FileCheck %s
2; RUN: llc -no-integrated-as -code-model=large -verify-machineinstrs -o - %s -aarch64-min-jump-table-entries=4 -mtriple=aarch64-none-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 | FileCheck --check-prefix=CHECK-LARGE %s
3; RUN: llc -no-integrated-as -code-model=large -relocation-model=pic -o - %s -aarch64-min-jump-table-entries=4 -mtriple=aarch64-none-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 | FileCheck --check-prefix=CHECK-PIC %s
4; RUN: llc -no-integrated-as -mtriple=aarch64-none-linux-gnu -verify-machineinstrs -relocation-model=pic -aarch64-min-jump-table-entries=4 -aarch64-enable-atomic-cfg-tidy=0 -o - %s | FileCheck --check-prefix=CHECK-PIC %s
5; RUN: llc -no-integrated-as -verify-machineinstrs -o - %s -mtriple=arm64-apple-ios -aarch64-min-jump-table-entries=4 -aarch64-enable-atomic-cfg-tidy=0 | FileCheck --check-prefix=CHECK-IOS %s
6; RUN: llc -no-integrated-as -code-model=tiny -verify-machineinstrs -o - %s -aarch64-min-jump-table-entries=4 -mtriple=aarch64-none-linux-gnu -aarch64-enable-atomic-cfg-tidy=0 | FileCheck --check-prefix=CHECK-TINY %s
7
8define i32 @test_jumptable(i32 %in) {
9; CHECK: test_jumptable
10
11  switch i32 %in, label %def [
12    i32 0, label %lbl1
13    i32 1, label %lbl2
14    i32 2, label %lbl3
15    i32 4, label %lbl4
16  ]
17; CHECK-LABEL: test_jumptable:
18; CHECK:     adrp [[JTPAGE:x[0-9]+]], .LJTI0_0
19; CHECK:     add x[[JT:[0-9]+]], [[JTPAGE]], {{#?}}:lo12:.LJTI0_0
20; CHECK:     adr [[PCBASE:x[0-9]+]], [[JTBASE:.LBB[0-9]+_[0-9]+]]
21; CHECK:     ldrb w[[OFFSET:[0-9]+]], [x[[JT]], {{x[0-9]+}}]
22; CHECK:     add [[DEST:x[0-9]+]], [[PCBASE]], x[[OFFSET]], lsl #2
23; CHECK:     br [[DEST]]
24
25; CHECK-LARGE:     movz x[[JTADDR:[0-9]+]], #:abs_g0_nc:.LJTI0_0
26; CHECK-LARGE:     movk x[[JTADDR]], #:abs_g1_nc:.LJTI0_0
27; CHECK-LARGE:     movk x[[JTADDR]], #:abs_g2_nc:.LJTI0_0
28; CHECK-LARGE:     movk x[[JTADDR]], #:abs_g3:.LJTI0_0
29; CHECK-LARGE:     adr [[PCBASE:x[0-9]+]], [[JTBASE:.LBB[0-9]+_[0-9]+]]
30; CHECK-LARGE:     ldrb w[[OFFSET:[0-9]+]], [x[[JTADDR]], {{x[0-9]+}}]
31; CHECK-LARGE:     add [[DEST:x[0-9]+]], [[PCBASE]], x[[OFFSET]], lsl #2
32; CHECK-LARGE:     br [[DEST]]
33
34; CHECK-PIC-LABEL: test_jumptable:
35; CHECK-PIC:     adrp [[JTPAGE:x[0-9]+]], .LJTI0_0
36; CHECK-PIC:     add x[[JT:[0-9]+]], [[JTPAGE]], {{#?}}:lo12:.LJTI0_0
37; CHECK-PIC:     adr [[PCBASE:x[0-9]+]], [[JTBASE:.LBB[0-9]+_[0-9]+]]
38; CHECK-PIC:     ldrb w[[OFFSET:[0-9]+]], [x[[JT]], {{x[0-9]+}}]
39; CHECK-PIC:     add [[DEST:x[0-9]+]], [[PCBASE]], x[[OFFSET]], lsl #2
40; CHECK-PIC:     br [[DEST]]
41
42; CHECK-IOS:     adrp [[JTPAGE:x[0-9]+]], LJTI0_0@PAGE
43; CHECK-IOS:     add x[[JT:[0-9]+]], [[JTPAGE]], LJTI0_0@PAGEOFF
44; CHECK-IOS:     adr [[PCBASE:x[0-9]+]], [[JTBASE:LBB[0-9]+_[0-9]+]]
45; CHECK-IOS:     ldrb w[[OFFSET:[0-9]+]], [x[[JT]], {{x[0-9]+}}]
46; CHECK-IOS:     add [[DEST:x[0-9]+]], [[PCBASE]], x[[OFFSET]], lsl #2
47; CHECK-IOS: br [[DEST]]
48
49; CHECK-TINY-LABEL: test_jumptable:
50; CHECK-TINY:     adr x[[JT:[0-9]+]], .LJTI0_0
51; CHECK-TINY:     adr [[PCBASE:x[0-9]+]], [[JTBASE:.LBB[0-9]+_[0-9]+]]
52; CHECK-TINY:     ldrb w[[OFFSET:[0-9]+]], [x[[JT]], {{x[0-9]+}}]
53; CHECK-TINY:     add [[DEST:x[0-9]+]], [[PCBASE]], x[[OFFSET]], lsl #2
54; CHECK-TINY:     br [[DEST]]
55
56
57def:
58  ret i32 0
59
60lbl1:
61  ret i32 1
62
63lbl2:
64  ret i32 2
65
66lbl3:
67  ret i32 4
68
69lbl4:
70  ret i32 8
71
72}
73
74; CHECK: .rodata
75
76; CHECK: .LJTI0_0:
77; CHECK-NEXT: .byte ([[JTBASE]]-[[JTBASE]])>>2
78; CHECK-NEXT: .byte (.LBB{{.*}}-[[JTBASE]])>>2
79; CHECK-NEXT: .byte (.LBB{{.*}}-[[JTBASE]])>>2
80; CHECK-NEXT: .byte (.LBB{{.*}}-[[JTBASE]])>>2
81; CHECK-NEXT: .byte (.LBB{{.*}}-[[JTBASE]])>>2
82
83define i32 @test_jumptable16(i32 %in) {
84
85  switch i32 %in, label %def [
86    i32 0, label %lbl1
87    i32 1, label %lbl2
88    i32 2, label %lbl3
89    i32 4, label %lbl4
90  ]
91; CHECK-LABEL: test_jumptable16:
92; CHECK:     adrp [[JTPAGE:x[0-9]+]], .LJTI1_0
93; CHECK:     add x[[JT:[0-9]+]], [[JTPAGE]], {{#?}}:lo12:.LJTI1_0
94; CHECK:     adr [[PCBASE:x[0-9]+]], [[JTBASE:.LBB[0-9]+_[0-9]+]]
95; CHECK:     ldrh w[[OFFSET:[0-9]+]], [x[[JT]], {{x[0-9]+}}, lsl #1]
96; CHECK:     add [[DEST:x[0-9]+]], [[PCBASE]], x[[OFFSET]], lsl #2
97; CHECK:     br [[DEST]]
98
99def:
100  ret i32 0
101
102lbl1:
103  ret i32 1
104
105lbl2:
106  call i64 @llvm.aarch64.space(i32 1024, i64 undef)
107  ret i32 2
108
109lbl3:
110  ret i32 4
111
112lbl4:
113  ret i32 8
114
115}
116
117; CHECK:      .rodata
118; CHECK:      .p2align 1
119; CHECK: .LJTI1_0:
120; CHECK-NEXT: .hword ([[JTBASE]]-[[JTBASE]])>>2
121; CHECK-NEXT: .hword (.LBB{{.*}}-[[JTBASE]])>>2
122; CHECK-NEXT: .hword (.LBB{{.*}}-[[JTBASE]])>>2
123; CHECK-NEXT: .hword (.LBB{{.*}}-[[JTBASE]])>>2
124; CHECK-NEXT: .hword (.LBB{{.*}}-[[JTBASE]])>>2
125
126; CHECK-PIC-NOT: .data_region
127; CHECK-PIC-NOT: .LJTI0_0
128; CHECK-PIC: .LJTI0_0:
129; CHECK-PIC-NEXT: .byte ([[JTBASE]]-[[JTBASE]])>>2
130; CHECK-PIC-NEXT: .byte (.LBB{{.*}}-[[JTBASE]])>>2
131; CHECK-PIC-NEXT: .byte (.LBB{{.*}}-[[JTBASE]])>>2
132; CHECK-PIC-NEXT: .byte (.LBB{{.*}}-[[JTBASE]])>>2
133; CHECK-PIC-NEXT: .byte (.LBB{{.*}}-[[JTBASE]])>>2
134; CHECK-PIC-NOT: .end_data_region
135
136; CHECK-IOS: .section __TEXT,__const
137; CHECK-IOS-NOT: .data_region
138; CHECK-IOS: LJTI0_0:
139; CHECK-IOS-NEXT:     .byte ([[JTBASE]]-[[JTBASE]])>>2
140; CHECK-IOS-NEXT:     .byte (LBB{{.*}}-[[JTBASE]])>>2
141; CHECK-IOS-NEXT:     .byte (LBB{{.*}}-[[JTBASE]])>>2
142; CHECK-IOS-NEXT:     .byte (LBB{{.*}}-[[JTBASE]])>>2
143; CHECK-IOS-NEXT:     .byte (LBB{{.*}}-[[JTBASE]])>>2
144; CHECK-IOS-NOT: .end_data_region
145
146; Compressing just the first table has the opportunity to truncate the vector of
147; sizes. Make sure it doesn't.
148define i32 @test_twotables(i32 %in1, i32 %in2) {
149; CHECK-LABEL: test_twotables:
150; CHECK: .LJTI2_0
151; CHECK: .LJTI2_1
152
153  switch i32 %in1, label %def [
154    i32 0, label %lbl1
155    i32 1, label %lbl2
156    i32 2, label %lbl3
157    i32 4, label %lbl4
158  ]
159
160def:
161  ret i32 0
162
163lbl1:
164  ret i32 1
165
166lbl2:
167  ret i32 2
168
169lbl3:
170  ret i32 4
171
172lbl4:
173  switch i32 %in1, label %def [
174    i32 0, label %lbl5
175    i32 1, label %lbl6
176    i32 2, label %lbl7
177    i32 4, label %lbl8
178  ]
179
180lbl5:
181  call i64 @llvm.aarch64.space(i32 262144, i64 undef)
182  ret i32 1
183
184lbl6:
185  call i64 @llvm.aarch64.space(i32 262144, i64 undef)
186  ret i32 2
187
188lbl7:
189  call i64 @llvm.aarch64.space(i32 262144, i64 undef)
190  ret i32 4
191lbl8:
192  call i64 @llvm.aarch64.space(i32 262144, i64 undef)
193  ret i32 8
194
195}
196
197declare i64 @llvm.aarch64.space(i32, i64)
198