diff --git a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp index 9dde131185cf8..9d915d0d967e5 100644 --- a/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp +++ b/llvm/lib/Transforms/Scalar/JumpTableToSwitch.cpp @@ -159,6 +159,10 @@ expandToSwitch(CallBase *CB, const JumpTableTy &JT, DomTreeUpdater &DTU, DTUpdates.push_back({DominatorTree::Insert, B, Tail}); CallBase *Call = cast(CB->clone()); + // The MD_prof metadata (VP kind), if it existed, can be dropped, it doesn't + // make sense on a direct call. Note that the values are used for the branch + // weights of the switch. + Call->setMetadata(LLVMContext::MD_prof, nullptr); Call->setCalledFunction(Func); Call->insertInto(B, B->end()); Switch->addCase( @@ -180,14 +184,8 @@ expandToSwitch(CallBase *CB, const JumpTableTy &JT, DomTreeUpdater &DTU, if (HadProfile && !ProfcheckDisableMetadataFixes) { // At least one of the targets must've been taken. assert(llvm::any_of(BranchWeights, [](uint64_t V) { return V != 0; })); - // FIXME: this duplicates logic in instrumentation. Note: since there's at - // least a nonzero and these are unsigned values, it follows MaxBW != 0. - uint64_t MaxBW = *llvm::max_element(BranchWeights); - SmallVector ScaledBranchWeights( - llvm::map_range(BranchWeights, [MaxBW](uint64_t V) { - return static_cast(V / MaxBW); - })); - setBranchWeights(*Switch, ScaledBranchWeights, /*IsExpected=*/false); + setBranchWeights(*Switch, downscaleWeights(BranchWeights), + /*IsExpected=*/false); } else setExplicitlyUnknownBranchWeights(*Switch); if (PHI) diff --git a/llvm/test/Transforms/JumpTableToSwitch/basic.ll b/llvm/test/Transforms/JumpTableToSwitch/basic.ll index 577c2adaf5afa..e3c032b9d4bf7 100644 --- a/llvm/test/Transforms/JumpTableToSwitch/basic.ll +++ b/llvm/test/Transforms/JumpTableToSwitch/basic.ll @@ -1,14 +1,39 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 4 ; RUN: opt < %s -passes=jump-table-to-switch -verify-dom-info -S | FileCheck %s ; RUN: opt < %s -passes=jump-table-to-switch -jump-table-to-switch-size-threshold=0 -verify-dom-info -S | FileCheck %s --check-prefix=THRESHOLD-0 @func_array = constant [2 x ptr] [ptr @func0, ptr @func1] +;. +; CHECK: @func_array = constant [2 x ptr] [ptr @func0, ptr @func1] +; CHECK: @void_func_array = constant [2 x ptr] [ptr @void_func0, ptr @void_func1] +; CHECK: @func_array_addrspace_42 = addrspace(42) constant [2 x ptr addrspace(42)] [ptr addrspace(42) @func0_addrspace_42, ptr addrspace(42) @func1_addrspace_42] +;. +; THRESHOLD-0: @func_array = constant [2 x ptr] [ptr @func0, ptr @func1] +; THRESHOLD-0: @void_func_array = constant [2 x ptr] [ptr @void_func0, ptr @void_func1] +; THRESHOLD-0: @func_array_addrspace_42 = addrspace(42) constant [2 x ptr addrspace(42)] [ptr addrspace(42) @func0_addrspace_42, ptr addrspace(42) @func1_addrspace_42] +;. define i32 @func0() !guid !0 { +; CHECK-LABEL: define i32 @func0( +; CHECK-SAME: ) !guid [[META0:![0-9]+]] { +; CHECK-NEXT: ret i32 1 +; +; THRESHOLD-0-LABEL: define i32 @func0( +; THRESHOLD-0-SAME: ) !guid [[META0:![0-9]+]] { +; THRESHOLD-0-NEXT: ret i32 1 +; ret i32 1 } define i32 @func1() !guid !1 { +; CHECK-LABEL: define i32 @func1( +; CHECK-SAME: ) !guid [[META1:![0-9]+]] { +; CHECK-NEXT: ret i32 2 +; +; THRESHOLD-0-LABEL: define i32 @func1( +; THRESHOLD-0-SAME: ) !guid [[META1:![0-9]+]] { +; THRESHOLD-0-NEXT: ret i32 2 +; ret i32 2 } @@ -20,7 +45,7 @@ define i32 @function_with_jump_table(i32 %index) { ; CHECK-NEXT: switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE:%.*]] [ ; CHECK-NEXT: i32 0, label [[CALL_0:%.*]] ; CHECK-NEXT: i32 1, label [[CALL_1:%.*]] -; CHECK-NEXT: ] +; CHECK-NEXT: ], !prof [[PROF2:![0-9]+]] ; CHECK: default.switch.case.unreachable: ; CHECK-NEXT: unreachable ; CHECK: call.0: @@ -37,7 +62,7 @@ define i32 @function_with_jump_table(i32 %index) { ; THRESHOLD-0-SAME: i32 [[INDEX:%.*]]) { ; THRESHOLD-0-NEXT: [[GEP:%.*]] = getelementptr inbounds [2 x ptr], ptr @func_array, i32 0, i32 [[INDEX]] ; THRESHOLD-0-NEXT: [[FUNC_PTR:%.*]] = load ptr, ptr [[GEP]], align 8 -; THRESHOLD-0-NEXT: [[RESULT:%.*]] = call i32 [[FUNC_PTR]]() +; THRESHOLD-0-NEXT: [[RESULT:%.*]] = call i32 [[FUNC_PTR]](), !prof [[PROF2:![0-9]+]] ; THRESHOLD-0-NEXT: ret i32 [[RESULT]] ; %gep = getelementptr inbounds [2 x ptr], ptr @func_array, i32 0, i32 %index @@ -54,7 +79,7 @@ define i32 @basic_block_splitted_twice(i32 %index) { ; CHECK-NEXT: switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE:%.*]] [ ; CHECK-NEXT: i32 0, label [[CALL_0:%.*]] ; CHECK-NEXT: i32 1, label [[CALL_1:%.*]] -; CHECK-NEXT: ] +; CHECK-NEXT: ], !prof [[PROF3:![0-9]+]] ; CHECK: default.switch.case.unreachable: ; CHECK-NEXT: unreachable ; CHECK: call.0: @@ -70,7 +95,7 @@ define i32 @basic_block_splitted_twice(i32 %index) { ; CHECK-NEXT: switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE1:%.*]] [ ; CHECK-NEXT: i32 0, label [[CALL_02:%.*]] ; CHECK-NEXT: i32 1, label [[CALL_13:%.*]] -; CHECK-NEXT: ] +; CHECK-NEXT: ], !prof [[PROF3]] ; CHECK: default.switch.case.unreachable1: ; CHECK-NEXT: unreachable ; CHECK: call.02: @@ -106,10 +131,22 @@ define i32 @basic_block_splitted_twice(i32 %index) { } define void @void_func0() { +; CHECK-LABEL: define void @void_func0() { +; CHECK-NEXT: ret void +; +; THRESHOLD-0-LABEL: define void @void_func0() { +; THRESHOLD-0-NEXT: ret void +; ret void } define void @void_func1() { +; CHECK-LABEL: define void @void_func1() { +; CHECK-NEXT: ret void +; +; THRESHOLD-0-LABEL: define void @void_func1() { +; THRESHOLD-0-NEXT: ret void +; ret void } @@ -123,7 +160,7 @@ define void @void_function_with_jump_table(i32 %index) { ; CHECK-NEXT: switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE:%.*]] [ ; CHECK-NEXT: i32 0, label [[CALL_0:%.*]] ; CHECK-NEXT: i32 1, label [[CALL_1:%.*]] -; CHECK-NEXT: ] +; CHECK-NEXT: ], !prof [[PROF3]] ; CHECK: default.switch.case.unreachable: ; CHECK-NEXT: unreachable ; CHECK: call.0: @@ -156,7 +193,7 @@ define void @void_function_with_jump_table_and_call_site_attr(i32 %index) { ; CHECK-NEXT: switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE:%.*]] [ ; CHECK-NEXT: i32 0, label [[CALL_0:%.*]] ; CHECK-NEXT: i32 1, label [[CALL_1:%.*]] -; CHECK-NEXT: ] +; CHECK-NEXT: ], !prof [[PROF3]] ; CHECK: default.switch.case.unreachable: ; CHECK-NEXT: unreachable ; CHECK: call.0: @@ -183,10 +220,22 @@ define void @void_function_with_jump_table_and_call_site_attr(i32 %index) { define i32 @func0_addrspace_42() addrspace(42) { +; CHECK-LABEL: define i32 @func0_addrspace_42() addrspace(42) { +; CHECK-NEXT: ret i32 1 +; +; THRESHOLD-0-LABEL: define i32 @func0_addrspace_42() addrspace(42) { +; THRESHOLD-0-NEXT: ret i32 1 +; ret i32 1 } define i32 @func1_addrspace_42() addrspace(42) { +; CHECK-LABEL: define i32 @func1_addrspace_42() addrspace(42) { +; CHECK-NEXT: ret i32 2 +; +; THRESHOLD-0-LABEL: define i32 @func1_addrspace_42() addrspace(42) { +; THRESHOLD-0-NEXT: ret i32 2 +; ret i32 2 } @@ -200,7 +249,7 @@ define i32 @function_with_jump_table_addrspace_42(i32 %index) addrspace(42) { ; CHECK-NEXT: switch i32 [[INDEX]], label [[DEFAULT_SWITCH_CASE_UNREACHABLE:%.*]] [ ; CHECK-NEXT: i32 0, label [[CALL_0:%.*]] ; CHECK-NEXT: i32 1, label [[CALL_1:%.*]] -; CHECK-NEXT: ] +; CHECK-NEXT: ], !prof [[PROF3]] ; CHECK: default.switch.case.unreachable: ; CHECK-NEXT: unreachable ; CHECK: call.0: @@ -228,4 +277,18 @@ define i32 @function_with_jump_table_addrspace_42(i32 %index) addrspace(42) { !0 = !{i64 5678} !1 = !{i64 5555} -!2 = !{!"VP", i32 0, i64 25, i64 5678, i64 20, i64 5555, i64 5} \ No newline at end of file +!2 = !{!"VP", i32 0, i64 25, i64 5678, i64 20, i64 5555, i64 5} +;. +; CHECK: attributes #[[ATTR0]] = { nounwind } +;. +; THRESHOLD-0: attributes #[[ATTR0]] = { nounwind } +;. +; CHECK: [[META0]] = !{i64 5678} +; CHECK: [[META1]] = !{i64 5555} +; CHECK: [[PROF2]] = !{!"branch_weights", i32 0, i32 20, i32 5} +; CHECK: [[PROF3]] = !{!"unknown"} +;. +; THRESHOLD-0: [[META0]] = !{i64 5678} +; THRESHOLD-0: [[META1]] = !{i64 5555} +; THRESHOLD-0: [[PROF2]] = !{!"VP", i32 0, i64 25, i64 5678, i64 20, i64 5555, i64 5} +;.