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