[llvm] [LTT] Add `unknown` branch weights when lowering type tests with conditional (PR #170752)

Mircea Trofin via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 4 13:49:25 PST 2025


https://github.com/mtrofin created https://github.com/llvm/llvm-project/pull/170752

None

>From c1d86613920419edc085a8742e3002388e3cad5e Mon Sep 17 00:00:00 2001
From: Mircea Trofin <mtrofin at google.com>
Date: Thu, 4 Dec 2025 13:48:43 -0800
Subject: [PATCH] [LTT] Add `unknown` branch weights when lowering type tests
 with conditional

---
 llvm/lib/Transforms/IPO/LowerTypeTests.cpp    |   3 +
 llvm/test/Transforms/LowerTypeTests/import.ll | 133 +++++++++++-------
 llvm/utils/profcheck-xfail.txt                |   2 -
 3 files changed, 86 insertions(+), 52 deletions(-)

diff --git a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
index f7aeda95e41b3..ef0bc29b03c2a 100644
--- a/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ b/llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -54,6 +54,7 @@
 #include "llvm/IR/ModuleSummaryIndexYAML.h"
 #include "llvm/IR/Operator.h"
 #include "llvm/IR/PassManager.h"
+#include "llvm/IR/ProfDataUtils.h"
 #include "llvm/IR/ReplaceConstant.h"
 #include "llvm/IR/Type.h"
 #include "llvm/IR/Use.h"
@@ -803,6 +804,8 @@ Value *LowerTypeTestsModule::lowerTypeTestCall(Metadata *TypeId, CallInst *CI,
       }
 
   IRBuilder<> ThenB(SplitBlockAndInsertIfThen(OffsetInRange, CI, false));
+  setExplicitlyUnknownBranchWeightsIfProfiled(*InitialBB->getTerminator(),
+                                              DEBUG_TYPE);
 
   // Now that we know that the offset is in range and aligned, load the
   // appropriate bit from the bitset.
diff --git a/llvm/test/Transforms/LowerTypeTests/import.ll b/llvm/test/Transforms/LowerTypeTests/import.ll
index 819ede96f997e..3d61b68c90e47 100644
--- a/llvm/test/Transforms/LowerTypeTests/import.ll
+++ b/llvm/test/Transforms/LowerTypeTests/import.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals --version 3
 ; RUN: opt -mtriple=x86_64-unknown-linux -S -passes=lowertypetests -lowertypetests-summary-action=import -lowertypetests-read-summary=%S/Inputs/import.yaml %s | FileCheck --check-prefixes=CHECK,X86 %s
 ; RUN: opt -mtriple=aarch64-unknown-linux -S -passes=lowertypetests -lowertypetests-summary-action=import -lowertypetests-read-summary=%S/Inputs/import.yaml %s | FileCheck --check-prefixes=CHECK,ARM %s
 
@@ -6,32 +6,44 @@ target datalayout = "e-p:64:64"
 
 declare i1 @llvm.type.test(ptr %ptr, metadata %bitset) nounwind readnone
 
-; CHECK-DAG: @__typeid_single_global_addr = external hidden global [0 x i8], code_model "small"
-; CHECK-DAG: @__typeid_inline6_global_addr = external hidden global [0 x i8], code_model "small"
-; X86-DAG: @__typeid_inline6_align = external hidden global [0 x i8], !absolute_symbol !0
-; X86-DAG: @__typeid_inline6_size_m1 = external hidden global [0 x i8], !absolute_symbol !1
-; X86-DAG: @__typeid_inline6_inline_bits = external hidden global [0 x i8], !absolute_symbol !2
-; CHECK-DAG: @__typeid_inline5_global_addr = external hidden global [0 x i8], code_model "small"
-; X86-DAG: @__typeid_inline5_align = external hidden global [0 x i8], !absolute_symbol !0
-; X86-DAG: @__typeid_inline5_size_m1 = external hidden global [0 x i8], !absolute_symbol !3
-; X86-DAG: @__typeid_inline5_inline_bits = external hidden global [0 x i8], !absolute_symbol !4
-; CHECK-DAG: @__typeid_bytearray32_global_addr = external hidden global [0 x i8], code_model "small"
-; X86-DAG: @__typeid_bytearray32_align = external hidden global [0 x i8], !absolute_symbol !0
-; X86-DAG: @__typeid_bytearray32_size_m1 = external hidden global [0 x i8], !absolute_symbol !4
-; CHECK-DAG: @__typeid_bytearray32_byte_array = external hidden global [0 x i8]
-; X86-DAG: @__typeid_bytearray32_bit_mask = external hidden global [0 x i8], !absolute_symbol !0
-; CHECK-DAG: @__typeid_bytearray7_global_addr = external hidden global [0 x i8], code_model "small"
-; X86-DAG: @__typeid_bytearray7_align = external hidden global [0 x i8], !absolute_symbol !0
-; X86-DAG: @__typeid_bytearray7_size_m1 = external hidden global [0 x i8], !absolute_symbol !5
-; CHECK-DAG: @__typeid_bytearray7_byte_array = external hidden global [0 x i8]
-; X86-DAG: @__typeid_bytearray7_bit_mask = external hidden global [0 x i8], !absolute_symbol !0
-; CHECK-DAG: @__typeid_allones32_global_addr = external hidden global [0 x i8], code_model "small"
-; X86-DAG: @__typeid_allones32_align = external hidden global [0 x i8], !absolute_symbol !0
-; X86-DAG: @__typeid_allones32_size_m1 = external hidden global [0 x i8], !absolute_symbol !4
-; CHECK-DAG: @__typeid_allones7_global_addr = external hidden global [0 x i8], code_model "small"
-; X86-DAG: @__typeid_allones7_align = external hidden global [0 x i8], !absolute_symbol !0
-; X86-DAG: @__typeid_allones7_size_m1 = external hidden global [0 x i8], !absolute_symbol !5
 
+;.
+; X86: @__typeid_single_global_addr = external hidden global [0 x i8], code_model "small"
+; X86: @__typeid_inline6_global_addr = external hidden global [0 x i8], code_model "small"
+; X86: @__typeid_inline6_align = external hidden global [0 x i8], !absolute_symbol [[META0:![0-9]+]]
+; X86: @__typeid_inline6_size_m1 = external hidden global [0 x i8], !absolute_symbol [[META1:![0-9]+]]
+; X86: @__typeid_inline6_inline_bits = external hidden global [0 x i8], !absolute_symbol [[META2:![0-9]+]]
+; X86: @__typeid_inline5_global_addr = external hidden global [0 x i8], code_model "small"
+; X86: @__typeid_inline5_align = external hidden global [0 x i8], !absolute_symbol [[META0]]
+; X86: @__typeid_inline5_size_m1 = external hidden global [0 x i8], !absolute_symbol [[META3:![0-9]+]]
+; X86: @__typeid_inline5_inline_bits = external hidden global [0 x i8], !absolute_symbol [[META4:![0-9]+]]
+; X86: @__typeid_bytearray32_global_addr = external hidden global [0 x i8], code_model "small"
+; X86: @__typeid_bytearray32_align = external hidden global [0 x i8], !absolute_symbol [[META0]]
+; X86: @__typeid_bytearray32_size_m1 = external hidden global [0 x i8], !absolute_symbol [[META4]]
+; X86: @__typeid_bytearray32_byte_array = external hidden global [0 x i8]
+; X86: @__typeid_bytearray32_bit_mask = external hidden global [0 x i8], !absolute_symbol [[META0]]
+; X86: @__typeid_bytearray7_global_addr = external hidden global [0 x i8], code_model "small"
+; X86: @__typeid_bytearray7_align = external hidden global [0 x i8], !absolute_symbol [[META0]]
+; X86: @__typeid_bytearray7_size_m1 = external hidden global [0 x i8], !absolute_symbol [[META5:![0-9]+]]
+; X86: @__typeid_bytearray7_byte_array = external hidden global [0 x i8]
+; X86: @__typeid_bytearray7_bit_mask = external hidden global [0 x i8], !absolute_symbol [[META0]]
+; X86: @__typeid_allones32_global_addr = external hidden global [0 x i8], code_model "small"
+; X86: @__typeid_allones32_align = external hidden global [0 x i8], !absolute_symbol [[META0]]
+; X86: @__typeid_allones32_size_m1 = external hidden global [0 x i8], !absolute_symbol [[META4]]
+; X86: @__typeid_allones7_global_addr = external hidden global [0 x i8], code_model "small"
+; X86: @__typeid_allones7_align = external hidden global [0 x i8], !absolute_symbol [[META0]]
+; X86: @__typeid_allones7_size_m1 = external hidden global [0 x i8], !absolute_symbol [[META5]]
+;.
+; ARM: @__typeid_single_global_addr = external hidden global [0 x i8], code_model "small"
+; ARM: @__typeid_inline6_global_addr = external hidden global [0 x i8], code_model "small"
+; ARM: @__typeid_inline5_global_addr = external hidden global [0 x i8], code_model "small"
+; ARM: @__typeid_bytearray32_global_addr = external hidden global [0 x i8], code_model "small"
+; ARM: @__typeid_bytearray32_byte_array = external hidden global [0 x i8]
+; ARM: @__typeid_bytearray7_global_addr = external hidden global [0 x i8], code_model "small"
+; ARM: @__typeid_bytearray7_byte_array = external hidden global [0 x i8]
+; ARM: @__typeid_allones32_global_addr = external hidden global [0 x i8], code_model "small"
+; ARM: @__typeid_allones7_global_addr = external hidden global [0 x i8], code_model "small"
+;.
 define i1 @allones7(ptr %p) {
 ; X86-LABEL: define i1 @allones7(
 ; X86-SAME: ptr [[P:%.*]]) {
@@ -74,31 +86,31 @@ define i1 @allones32(ptr %p) {
   ret i1 %x
 }
 
-define i1 @bytearray7(ptr %p) {
+define i1 @bytearray7(ptr %p) !prof !0 {
 ; X86-LABEL: define i1 @bytearray7(
-; X86-SAME: ptr [[P:%.*]]) {
+; X86-SAME: ptr [[P:%.*]]) !prof [[PROF6:![0-9]+]] {
 ; X86-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[P]] to i64
 ; X86-NEXT:    [[TMP2:%.*]] = sub i64 ptrtoint (ptr @__typeid_bytearray7_global_addr to i64), [[TMP1]]
 ; X86-NEXT:    [[TMP7:%.*]] = call i64 @llvm.fshr.i64(i64 [[TMP2]], i64 [[TMP2]], i64 ptrtoint (ptr @__typeid_bytearray7_align to i64))
 ; X86-NEXT:    [[TMP8:%.*]] = icmp ule i64 [[TMP7]], ptrtoint (ptr @__typeid_bytearray7_size_m1 to i64)
-; X86-NEXT:    br i1 [[TMP8]], label %[[TMP9:.*]], label %[[TMP14:.*]]
-; X86:       [[TMP9]]:
+; X86-NEXT:    br i1 [[TMP8]], label [[TMP5:%.*]], label [[TMP14:%.*]], !prof [[PROF7:![0-9]+]]
+; X86:       5:
 ; X86-NEXT:    [[TMP10:%.*]] = getelementptr i8, ptr @__typeid_bytearray7_byte_array, i64 [[TMP7]]
 ; X86-NEXT:    [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
 ; X86-NEXT:    [[TMP12:%.*]] = and i8 [[TMP11]], ptrtoint (ptr @__typeid_bytearray7_bit_mask to i8)
 ; X86-NEXT:    [[TMP13:%.*]] = icmp ne i8 [[TMP12]], 0
-; X86-NEXT:    br label %[[TMP14]]
-; X86:       [[TMP14]]:
-; X86-NEXT:    [[TMP15:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP13]], %[[TMP9]] ]
+; X86-NEXT:    br label [[TMP14]]
+; X86:       10:
+; X86-NEXT:    [[TMP15:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP13]], [[TMP5]] ]
 ; X86-NEXT:    ret i1 [[TMP15]]
 ;
 ; ARM-LABEL: define i1 @bytearray7(
-; ARM-SAME: ptr [[P:%.*]]) {
+; ARM-SAME: ptr [[P:%.*]]) !prof [[PROF0:![0-9]+]] {
 ; ARM-NEXT:    [[TMP1:%.*]] = ptrtoint ptr [[P]] to i64
 ; ARM-NEXT:    [[TMP2:%.*]] = sub i64 ptrtoint (ptr @__typeid_bytearray7_global_addr to i64), [[TMP1]]
 ; ARM-NEXT:    [[TMP5:%.*]] = call i64 @llvm.fshr.i64(i64 [[TMP2]], i64 [[TMP2]], i64 3)
 ; ARM-NEXT:    [[TMP6:%.*]] = icmp ule i64 [[TMP5]], 43
-; ARM-NEXT:    br i1 [[TMP6]], label [[TMP7:%.*]], label [[TMP12:%.*]]
+; ARM-NEXT:    br i1 [[TMP6]], label [[TMP7:%.*]], label [[TMP12:%.*]], !prof [[PROF1:![0-9]+]]
 ; ARM:       5:
 ; ARM-NEXT:    [[TMP8:%.*]] = getelementptr i8, ptr @__typeid_bytearray7_byte_array, i64 [[TMP5]]
 ; ARM-NEXT:    [[TMP9:%.*]] = load i8, ptr [[TMP8]], align 1
@@ -120,15 +132,15 @@ define i1 @bytearray32(ptr %p) {
 ; X86-NEXT:    [[TMP2:%.*]] = sub i64 ptrtoint (ptr @__typeid_bytearray32_global_addr to i64), [[TMP1]]
 ; X86-NEXT:    [[TMP7:%.*]] = call i64 @llvm.fshr.i64(i64 [[TMP2]], i64 [[TMP2]], i64 ptrtoint (ptr @__typeid_bytearray32_align to i64))
 ; X86-NEXT:    [[TMP8:%.*]] = icmp ule i64 [[TMP7]], ptrtoint (ptr @__typeid_bytearray32_size_m1 to i64)
-; X86-NEXT:    br i1 [[TMP8]], label %[[TMP9:.*]], label %[[TMP14:.*]]
-; X86:       [[TMP9]]:
+; X86-NEXT:    br i1 [[TMP8]], label [[TMP5:%.*]], label [[TMP14:%.*]]
+; X86:       5:
 ; X86-NEXT:    [[TMP10:%.*]] = getelementptr i8, ptr @__typeid_bytearray32_byte_array, i64 [[TMP7]]
 ; X86-NEXT:    [[TMP11:%.*]] = load i8, ptr [[TMP10]], align 1
 ; X86-NEXT:    [[TMP12:%.*]] = and i8 [[TMP11]], ptrtoint (ptr @__typeid_bytearray32_bit_mask to i8)
 ; X86-NEXT:    [[TMP13:%.*]] = icmp ne i8 [[TMP12]], 0
-; X86-NEXT:    br label %[[TMP14]]
-; X86:       [[TMP14]]:
-; X86-NEXT:    [[TMP15:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP13]], %[[TMP9]] ]
+; X86-NEXT:    br label [[TMP14]]
+; X86:       10:
+; X86-NEXT:    [[TMP15:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP13]], [[TMP5]] ]
 ; X86-NEXT:    ret i1 [[TMP15]]
 ;
 ; ARM-LABEL: define i1 @bytearray32(
@@ -159,16 +171,16 @@ define i1 @inline5(ptr %p) {
 ; X86-NEXT:    [[TMP2:%.*]] = sub i64 ptrtoint (ptr @__typeid_inline5_global_addr to i64), [[TMP1]]
 ; X86-NEXT:    [[TMP7:%.*]] = call i64 @llvm.fshr.i64(i64 [[TMP2]], i64 [[TMP2]], i64 ptrtoint (ptr @__typeid_inline5_align to i64))
 ; X86-NEXT:    [[TMP8:%.*]] = icmp ule i64 [[TMP7]], ptrtoint (ptr @__typeid_inline5_size_m1 to i64)
-; X86-NEXT:    br i1 [[TMP8]], label %[[TMP9:.*]], label %[[TMP15:.*]]
-; X86:       [[TMP9]]:
+; X86-NEXT:    br i1 [[TMP8]], label [[TMP5:%.*]], label [[TMP15:%.*]]
+; X86:       5:
 ; X86-NEXT:    [[TMP10:%.*]] = trunc i64 [[TMP7]] to i32
 ; X86-NEXT:    [[TMP11:%.*]] = and i32 [[TMP10]], 31
 ; X86-NEXT:    [[TMP12:%.*]] = shl i32 1, [[TMP11]]
 ; X86-NEXT:    [[TMP13:%.*]] = and i32 ptrtoint (ptr @__typeid_inline5_inline_bits to i32), [[TMP12]]
 ; X86-NEXT:    [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0
-; X86-NEXT:    br label %[[TMP15]]
-; X86:       [[TMP15]]:
-; X86-NEXT:    [[TMP16:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP14]], %[[TMP9]] ]
+; X86-NEXT:    br label [[TMP15]]
+; X86:       11:
+; X86-NEXT:    [[TMP16:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP14]], [[TMP5]] ]
 ; X86-NEXT:    ret i1 [[TMP16]]
 ;
 ; ARM-LABEL: define i1 @inline5(
@@ -200,15 +212,15 @@ define i1 @inline6(ptr %p) {
 ; X86-NEXT:    [[TMP2:%.*]] = sub i64 ptrtoint (ptr @__typeid_inline6_global_addr to i64), [[TMP1]]
 ; X86-NEXT:    [[TMP7:%.*]] = call i64 @llvm.fshr.i64(i64 [[TMP2]], i64 [[TMP2]], i64 ptrtoint (ptr @__typeid_inline6_align to i64))
 ; X86-NEXT:    [[TMP8:%.*]] = icmp ule i64 [[TMP7]], ptrtoint (ptr @__typeid_inline6_size_m1 to i64)
-; X86-NEXT:    br i1 [[TMP8]], label %[[TMP9:.*]], label %[[TMP14:.*]]
-; X86:       [[TMP9]]:
+; X86-NEXT:    br i1 [[TMP8]], label [[TMP5:%.*]], label [[TMP14:%.*]]
+; X86:       5:
 ; X86-NEXT:    [[TMP10:%.*]] = and i64 [[TMP7]], 63
 ; X86-NEXT:    [[TMP11:%.*]] = shl i64 1, [[TMP10]]
 ; X86-NEXT:    [[TMP12:%.*]] = and i64 ptrtoint (ptr @__typeid_inline6_inline_bits to i64), [[TMP11]]
 ; X86-NEXT:    [[TMP13:%.*]] = icmp ne i64 [[TMP12]], 0
-; X86-NEXT:    br label %[[TMP14]]
-; X86:       [[TMP14]]:
-; X86-NEXT:    [[TMP15:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP13]], %[[TMP9]] ]
+; X86-NEXT:    br label [[TMP14]]
+; X86:       10:
+; X86-NEXT:    [[TMP15:%.*]] = phi i1 [ false, [[TMP0:%.*]] ], [ [[TMP13]], [[TMP5]] ]
 ; X86-NEXT:    ret i1 [[TMP15]]
 ;
 ; ARM-LABEL: define i1 @inline6(
@@ -249,3 +261,24 @@ define i1 @single(ptr %p) {
 ; X86: !3 = !{i64 0, i64 32}
 ; X86: !4 = !{i64 0, i64 4294967296}
 ; X86: !5 = !{i64 0, i64 128}
+
+!0 = !{!"function_entry_count", i32 10}
+;.
+; X86: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+; X86: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+;.
+; ARM: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
+; ARM: attributes #[[ATTR1:[0-9]+]] = { nocallback nocreateundeforpoison nofree nosync nounwind speculatable willreturn memory(none) }
+;.
+; X86: [[META0]] = !{i64 0, i64 256}
+; X86: [[META1]] = !{i64 0, i64 64}
+; X86: [[META2]] = !{i64 -1, i64 -1}
+; X86: [[META3]] = !{i64 0, i64 32}
+; X86: [[META4]] = !{i64 0, i64 4294967296}
+; X86: [[META5]] = !{i64 0, i64 128}
+; X86: [[PROF6]] = !{!"function_entry_count", i32 10}
+; X86: [[PROF7]] = !{!"unknown", !"lowertypetests"}
+;.
+; ARM: [[PROF0]] = !{!"function_entry_count", i32 10}
+; ARM: [[PROF1]] = !{!"unknown", !"lowertypetests"}
+;.
diff --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt
index 3cde50de7d0c1..a36cec940b605 100644
--- a/llvm/utils/profcheck-xfail.txt
+++ b/llvm/utils/profcheck-xfail.txt
@@ -493,8 +493,6 @@ Transforms/LowerSwitch/do-not-handle-impossible-values.ll
 Transforms/LowerSwitch/feature.ll
 Transforms/LowerSwitch/fold-popular-case-to-unreachable-default.ll
 Transforms/LowerSwitch/pr59316.ll
-Transforms/LowerTypeTests/import.ll
-Transforms/LowerTypeTests/simple.ll
 Transforms/MergeFunc/2011-02-08-RemoveEqual.ll
 Transforms/MergeFunc/apply_function_attributes.ll
 Transforms/MergeFunc/call-and-invoke-with-ranges-attr.ll



More information about the llvm-commits mailing list