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