xref: /llvm-project/llvm/test/Transforms/JumpTableToSwitch/skip.ll (revision d26b43ff4f7396f79de4b099160262c750d6aba7)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt < %s -passes=jump-table-to-switch -verify-dom-info -S | FileCheck %s
3
4@func_array0 = constant [2 x ptr] [ptr @func0, ptr @declared_only_func1]
5
6define i32 @func0() {
7  ret i32 1
8}
9
10declare i32 @declared_only_func1()
11
12define i32 @function_with_jump_table_with_a_declared_only_func(i32 %index) {
13; CHECK-LABEL: define i32 @function_with_jump_table_with_a_declared_only_func(
14; CHECK-SAME: i32 [[INDEX:%.*]]) {
15; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [2 x ptr], ptr @func_array0, i32 0, i32 [[INDEX]]
16; CHECK-NEXT:    [[FUNC_PTR:%.*]] = load ptr, ptr [[GEP]], align 8
17; CHECK-NEXT:    [[RESULT:%.*]] = call i32 [[FUNC_PTR]]()
18; CHECK-NEXT:    ret i32 [[RESULT]]
19;
20  %gep = getelementptr inbounds [2 x ptr], ptr @func_array0, i32 0, i32 %index
21  %func_ptr = load ptr, ptr %gep, align 8
22  %result = call i32 %func_ptr()
23  ret i32 %result
24}
25
26declare i32 @__gxx_personality_v0(...)
27
28define i32 @function_with_jump_table_invoke(i32 %index) personality ptr @__gxx_personality_v0 {
29; CHECK-LABEL: define i32 @function_with_jump_table_invoke(
30; CHECK-SAME: i32 [[INDEX:%.*]]) personality ptr @__gxx_personality_v0 {
31; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [2 x ptr], ptr @func_array0, i32 0, i32 [[INDEX]]
32; CHECK-NEXT:    [[FUNC_PTR:%.*]] = load ptr, ptr [[GEP]], align 8
33; CHECK-NEXT:    [[RESULT:%.*]] = invoke i32 [[FUNC_PTR]]()
34; CHECK-NEXT:            to label [[NORMAL:%.*]] unwind label [[EXCEPTIONAL:%.*]]
35; CHECK:       normal:
36; CHECK-NEXT:    ret i32 [[RESULT]]
37; CHECK:       exceptional:
38; CHECK-NEXT:    [[LANDING_PAD:%.*]] = landingpad { ptr, i32 }
39; CHECK-NEXT:            catch ptr null
40; CHECK-NEXT:    resume { ptr, i32 } [[LANDING_PAD]]
41;
42  %gep = getelementptr inbounds [2 x ptr], ptr @func_array0, i32 0, i32 %index
43  %func_ptr = load ptr, ptr %gep, align 8
44  %result = invoke i32 %func_ptr() to label %normal unwind label %exceptional
45normal:
46  ret i32 %result
47exceptional:
48  %landing_pad = landingpad { ptr, i32 } catch ptr null
49  resume { ptr, i32 } %landing_pad
50}
51
52@func_array1 = constant [1 x ptr] [ptr @func2]
53
54define i32 @func2(i32 %arg) {
55  ret i32 %arg
56}
57
58define i32 @function_with_jump_table_musttail_call(i32 %index) {
59; CHECK-LABEL: define i32 @function_with_jump_table_musttail_call(
60; CHECK-SAME: i32 [[INDEX:%.*]]) {
61; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [1 x ptr], ptr @func_array1, i32 0, i32 [[INDEX]]
62; CHECK-NEXT:    [[FUNC_PTR:%.*]] = load ptr, ptr [[GEP]], align 8
63; CHECK-NEXT:    [[RESULT:%.*]] = musttail call i32 [[FUNC_PTR]](i32 [[INDEX]])
64; CHECK-NEXT:    ret i32 [[RESULT]]
65;
66  %gep = getelementptr inbounds [1 x ptr], ptr @func_array1, i32 0, i32 %index
67  %func_ptr = load ptr, ptr %gep, align 8
68  %result = musttail call i32 %func_ptr(i32 %index)
69  ret i32 %result
70}
71
72define i32 @function_with_jump_table_and_volatile_load(i32 %index) {
73; CHECK-LABEL: define i32 @function_with_jump_table_and_volatile_load(
74; CHECK-SAME: i32 [[INDEX:%.*]]) {
75; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [1 x ptr], ptr @func_array1, i32 0, i32 [[INDEX]]
76; CHECK-NEXT:    [[FUNC_PTR:%.*]] = load volatile ptr, ptr [[GEP]], align 8
77; CHECK-NEXT:    [[RESULT:%.*]] = call i32 [[FUNC_PTR]](i32 [[INDEX]])
78; CHECK-NEXT:    ret i32 [[RESULT]]
79;
80  %gep = getelementptr inbounds [1 x ptr], ptr @func_array1, i32 0, i32 %index
81  %func_ptr = load volatile ptr, ptr %gep, align 8
82  %result = call i32 %func_ptr(i32 %index)
83  ret i32 %result
84}
85
86define i32 @function_with_jump_table_and_atomic_load(i32 %index) {
87; CHECK-LABEL: define i32 @function_with_jump_table_and_atomic_load(
88; CHECK-SAME: i32 [[INDEX:%.*]]) {
89; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [1 x ptr], ptr @func_array1, i32 0, i32 [[INDEX]]
90; CHECK-NEXT:    [[FUNC_PTR:%.*]] = load atomic ptr, ptr [[GEP]] monotonic, align 8
91; CHECK-NEXT:    [[RESULT:%.*]] = call i32 [[FUNC_PTR]](i32 [[INDEX]])
92; CHECK-NEXT:    ret i32 [[RESULT]]
93;
94  %gep = getelementptr inbounds [1 x ptr], ptr @func_array1, i32 0, i32 %index
95  %func_ptr = load atomic ptr, ptr %gep monotonic, align 8
96  %result = call i32 %func_ptr(i32 %index)
97  ret i32 %result
98}
99
100@func_array2 = global [1 x ptr] [ptr @func2]
101
102define i32 @function_with_nonconstant_jump_table(i32 %index) {
103; CHECK-LABEL: define i32 @function_with_nonconstant_jump_table(
104; CHECK-SAME: i32 [[INDEX:%.*]]) {
105; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [1 x ptr], ptr @func_array2, i32 0, i32 [[INDEX]]
106; CHECK-NEXT:    [[FUNC_PTR:%.*]] = load ptr, ptr [[GEP]], align 8
107; CHECK-NEXT:    [[RESULT:%.*]] = call i32 [[FUNC_PTR]](i32 [[INDEX]])
108; CHECK-NEXT:    ret i32 [[RESULT]]
109;
110  %gep = getelementptr inbounds [1 x ptr], ptr @func_array2, i32 0, i32 %index
111  %func_ptr = load ptr, ptr %gep, align 8
112  %result = call i32 %func_ptr(i32 %index)
113  ret i32 %result
114}
115
116@func_array3 = weak constant [1 x ptr] [ptr @func2]
117
118define i32 @function_with_constant_weak_jump_table(i32 %index) {
119; CHECK-LABEL: define i32 @function_with_constant_weak_jump_table(
120; CHECK-SAME: i32 [[INDEX:%.*]]) {
121; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds [1 x ptr], ptr @func_array3, i32 0, i32 [[INDEX]]
122; CHECK-NEXT:    [[FUNC_PTR:%.*]] = load ptr, ptr [[GEP]], align 8
123; CHECK-NEXT:    [[RESULT:%.*]] = call i32 [[FUNC_PTR]](i32 [[INDEX]])
124; CHECK-NEXT:    ret i32 [[RESULT]]
125;
126  %gep = getelementptr inbounds [1 x ptr], ptr @func_array3, i32 0, i32 %index
127  %func_ptr = load ptr, ptr %gep, align 8
128  %result = call i32 %func_ptr(i32 %index)
129  ret i32 %result
130}
131
132