132 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 42; RUN: opt < %s -passes=jump-table-to-switch -verify-dom-info -S | FileCheck %s3 4@func_array0 = constant [2 x ptr] [ptr @func0, ptr @declared_only_func1]5 6define i32 @func0() {7 ret i32 18}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 817; 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 %index21 %func_ptr = load ptr, ptr %gep, align 822 %result = call i32 %func_ptr()23 ret i32 %result24}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 833; 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 null40; CHECK-NEXT: resume { ptr, i32 } [[LANDING_PAD]]41;42 %gep = getelementptr inbounds [2 x ptr], ptr @func_array0, i32 0, i32 %index43 %func_ptr = load ptr, ptr %gep, align 844 %result = invoke i32 %func_ptr() to label %normal unwind label %exceptional45normal:46 ret i32 %result47exceptional:48 %landing_pad = landingpad { ptr, i32 } catch ptr null49 resume { ptr, i32 } %landing_pad50}51 52@func_array1 = constant [1 x ptr] [ptr @func2]53 54define i32 @func2(i32 %arg) {55 ret i32 %arg56}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 863; 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 %index67 %func_ptr = load ptr, ptr %gep, align 868 %result = musttail call i32 %func_ptr(i32 %index)69 ret i32 %result70}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 877; 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 %index81 %func_ptr = load volatile ptr, ptr %gep, align 882 %result = call i32 %func_ptr(i32 %index)83 ret i32 %result84}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 891; 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 %index95 %func_ptr = load atomic ptr, ptr %gep monotonic, align 896 %result = call i32 %func_ptr(i32 %index)97 ret i32 %result98}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 8107; 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 %index111 %func_ptr = load ptr, ptr %gep, align 8112 %result = call i32 %func_ptr(i32 %index)113 ret i32 %result114}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 8123; 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 %index127 %func_ptr = load ptr, ptr %gep, align 8128 %result = call i32 %func_ptr(i32 %index)129 ret i32 %result130}131 132