[llvm] WholeProgramDevirt: Fix importing in llvm.type.checked.load case. (PR #144019)
Peter Collingbourne via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 13 13:30:10 PDT 2025
https://github.com/pcc updated https://github.com/llvm/llvm-project/pull/144019
>From e7c2d788b7466a5ce7b272896dfa918b853333f0 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <peter at pcc.me.uk>
Date: Thu, 12 Jun 2025 22:06:04 -0700
Subject: [PATCH 1/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
=?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
---
.../lib/Transforms/IPO/WholeProgramDevirt.cpp | 35 +++++++++----------
.../Inputs/devirt_single_hybrid_foo_tcl.ll | 31 ++++++++++++++++
llvm/test/ThinLTO/X86/devirt_single_hybrid.ll | 22 +++++++++++-
3 files changed, 69 insertions(+), 19 deletions(-)
create mode 100644 llvm/test/ThinLTO/X86/Inputs/devirt_single_hybrid_foo_tcl.ll
diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
index a7d9f3ba24b24..d01907df0c7de 100644
--- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
+++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
@@ -494,28 +494,28 @@ struct CallSiteInfo {
/// Whether all call sites represented by this CallSiteInfo, including those
/// in summaries, have been devirtualized. This starts off as true because a
/// default constructed CallSiteInfo represents no call sites.
+ ///
+ /// If at the end of the pass there are still undevirtualized calls, we will
+ /// need to add a use of llvm.type.test to each of the function summaries in
+ /// the vector.
bool AllCallSitesDevirted = true;
// These fields are used during the export phase of ThinLTO and reflect
// information collected from function summaries.
- /// Whether any function summary contains an llvm.assume(llvm.type.test) for
- /// this slot.
- bool SummaryHasTypeTestAssumeUsers = false;
-
/// CFI-specific: a vector containing the list of function summaries that use
/// the llvm.type.checked.load intrinsic and therefore will require
/// resolutions for llvm.type.test in order to implement CFI checks if
- /// devirtualization was unsuccessful. If devirtualization was successful, the
- /// pass will clear this vector by calling markDevirt(). If at the end of the
- /// pass the vector is non-empty, we will need to add a use of llvm.type.test
- /// to each of the function summaries in the vector.
+ /// devirtualization was unsuccessful.
std::vector<FunctionSummary *> SummaryTypeCheckedLoadUsers;
+
+ /// A vector containing the list of function summaries that use
+ /// assume(llvm.type.test).
std::vector<FunctionSummary *> SummaryTypeTestAssumeUsers;
bool isExported() const {
- return SummaryHasTypeTestAssumeUsers ||
- !SummaryTypeCheckedLoadUsers.empty();
+ return !SummaryTypeCheckedLoadUsers.empty() ||
+ !SummaryTypeTestAssumeUsers.empty();
}
void addSummaryTypeCheckedLoadUser(FunctionSummary *FS) {
@@ -525,15 +525,11 @@ struct CallSiteInfo {
void addSummaryTypeTestAssumeUser(FunctionSummary *FS) {
SummaryTypeTestAssumeUsers.push_back(FS);
- SummaryHasTypeTestAssumeUsers = true;
AllCallSitesDevirted = false;
}
void markDevirt() {
AllCallSitesDevirted = true;
-
- // As explained in the comment for SummaryTypeCheckedLoadUsers.
- SummaryTypeCheckedLoadUsers.clear();
}
};
@@ -2465,11 +2461,14 @@ bool DevirtModule::run() {
if (ExportSummary && isa<MDString>(S.first.TypeID)) {
auto GUID = GlobalValue::getGUIDAssumingExternalLinkage(
cast<MDString>(S.first.TypeID)->getString());
- for (auto *FS : S.second.CSInfo.SummaryTypeCheckedLoadUsers)
- FS->addTypeTest(GUID);
+ auto AddTypeTestsForTypeCheckedLoads = [&](CallSiteInfo &CSI) {
+ if (!CSI.AllCallSitesDevirted)
+ for (auto *FS : CSI.SummaryTypeCheckedLoadUsers)
+ FS->addTypeTest(GUID);
+ };
+ AddTypeTestsForTypeCheckedLoads(S.second.CSInfo);
for (auto &CCS : S.second.ConstCSInfo)
- for (auto *FS : CCS.second.SummaryTypeCheckedLoadUsers)
- FS->addTypeTest(GUID);
+ AddTypeTestsForTypeCheckedLoads(CCS.second);
}
}
diff --git a/llvm/test/ThinLTO/X86/Inputs/devirt_single_hybrid_foo_tcl.ll b/llvm/test/ThinLTO/X86/Inputs/devirt_single_hybrid_foo_tcl.ll
new file mode 100644
index 0000000000000..4a696837bc8e9
--- /dev/null
+++ b/llvm/test/ThinLTO/X86/Inputs/devirt_single_hybrid_foo_tcl.ll
@@ -0,0 +1,31 @@
+; ModuleID = 'foo.cpp'
+source_filename = "foo.cpp"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+%struct.A = type { ptr }
+
+; Function Attrs: uwtable
+define hidden i32 @_Z3fooP1A(ptr %pA) local_unnamed_addr {
+entry:
+ %vtable = load ptr, ptr %pA, align 8, !tbaa !2
+ %0 = call { ptr, i1 } @llvm.type.checked.load(ptr %vtable, i32 0, metadata !"_ZTS1A")
+ %1 = extractvalue { ptr, i1 } %0, 0
+ %call = tail call i32 %1(ptr %pA)
+ %add = add nsw i32 %call, 10
+ ret i32 %add
+}
+
+declare { ptr, i1 } @llvm.type.checked.load(ptr, i32, metadata)
+
+; Function Attrs: nounwind willreturn
+declare void @llvm.assume(i1)
+
+!llvm.module.flags = !{!0}
+!llvm.ident = !{!1}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{!"clang version 10.0.0 (trunk 373596)"}
+!2 = !{!3, !3, i64 0}
+!3 = !{!"vtable pointer", !4, i64 0}
+!4 = !{!"Simple C++ TBAA"}
diff --git a/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll b/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll
index 90fdf0d7dfa09..fe3242e93159a 100644
--- a/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll
+++ b/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll
@@ -2,8 +2,28 @@
; when we're running hybrid LTO.
;
; RUN: opt -thinlto-bc -thinlto-split-lto-unit %s -o %t-main.bc
-; RUN: opt -thinlto-bc -thinlto-split-lto-unit %p/Inputs/devirt_single_hybrid_foo.ll -o %t-foo.bc
; RUN: opt -thinlto-bc -thinlto-split-lto-unit %p/Inputs/devirt_single_hybrid_bar.ll -o %t-bar.bc
+;
+; RUN: opt -thinlto-bc -thinlto-split-lto-unit %p/Inputs/devirt_single_hybrid_foo.ll -o %t-foo.bc
+; RUN: llvm-lto2 run -save-temps %t-main.bc %t-foo.bc %t-bar.bc -pass-remarks=. -o %t \
+; RUN: -whole-program-visibility \
+; RUN: -r=%t-foo.bc,_Z3fooP1A,pl \
+; RUN: -r=%t-main.bc,main,plx \
+; RUN: -r=%t-main.bc,_Z3barv,l \
+; RUN: -r=%t-bar.bc,_Z3barv,pl \
+; RUN: -r=%t-bar.bc,_Z3fooP1A, \
+; RUN: -r=%t-bar.bc,_ZNK1A1fEv,pl \
+; RUN: -r=%t-bar.bc,_ZTV1A,l \
+; RUN: -r=%t-bar.bc,_ZTVN10__cxxabiv117__class_type_infoE, \
+; RUN: -r=%t-bar.bc,_ZTS1A,pl \
+; RUN: -r=%t-bar.bc,_ZTI1A,pl \
+; RUN: -r=%t-bar.bc,_ZNK1A1fEv, \
+; RUN: -r=%t-bar.bc,_ZTV1A,pl \
+; RUN: -r=%t-bar.bc,_ZTI1A, 2>&1 | FileCheck %s --check-prefix=REMARK
+; RUN: llvm-dis %t.1.3.import.bc -o - | FileCheck %s --check-prefix=IMPORT
+; RUN: llvm-dis %t.1.5.precodegen.bc -o - | FileCheck %s --check-prefix=CODEGEN
+
+; RUN: opt -thinlto-bc -thinlto-split-lto-unit %p/Inputs/devirt_single_hybrid_foo_tcl.ll -o %t-foo.bc
; RUN: llvm-lto2 run -save-temps %t-main.bc %t-foo.bc %t-bar.bc -pass-remarks=. -o %t \
; RUN: -whole-program-visibility \
; RUN: -r=%t-foo.bc,_Z3fooP1A,pl \
>From ea597c1aa684f2db8178edba3afaa33968ac4300 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <peter at pcc.me.uk>
Date: Thu, 12 Jun 2025 22:31:26 -0700
Subject: [PATCH 2/3] Format
Created using spr 1.3.6-beta.1
---
llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
index d01907df0c7de..30e1dc7167a39 100644
--- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
+++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp
@@ -528,9 +528,7 @@ struct CallSiteInfo {
AllCallSitesDevirted = false;
}
- void markDevirt() {
- AllCallSitesDevirted = true;
- }
+ void markDevirt() { AllCallSitesDevirted = true; }
};
// Call site information collected for a specific VTableSlot.
>From c4197d03a45ad6334a8871cf4c7d90b1b62657d9 Mon Sep 17 00:00:00 2001
From: Peter Collingbourne <peter at pcc.me.uk>
Date: Fri, 13 Jun 2025 13:29:55 -0700
Subject: [PATCH 3/3] Address comment
Created using spr 1.3.6-beta.1
---
llvm/test/ThinLTO/X86/devirt_single_hybrid.ll | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll b/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll
index fe3242e93159a..53c001efc132e 100644
--- a/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll
+++ b/llvm/test/ThinLTO/X86/devirt_single_hybrid.ll
@@ -3,7 +3,9 @@
;
; RUN: opt -thinlto-bc -thinlto-split-lto-unit %s -o %t-main.bc
; RUN: opt -thinlto-bc -thinlto-split-lto-unit %p/Inputs/devirt_single_hybrid_bar.ll -o %t-bar.bc
-;
+
+; Test the assume(type.test) case.
+
; RUN: opt -thinlto-bc -thinlto-split-lto-unit %p/Inputs/devirt_single_hybrid_foo.ll -o %t-foo.bc
; RUN: llvm-lto2 run -save-temps %t-main.bc %t-foo.bc %t-bar.bc -pass-remarks=. -o %t \
; RUN: -whole-program-visibility \
@@ -23,6 +25,8 @@
; RUN: llvm-dis %t.1.3.import.bc -o - | FileCheck %s --check-prefix=IMPORT
; RUN: llvm-dis %t.1.5.precodegen.bc -o - | FileCheck %s --check-prefix=CODEGEN
+; Test the type.checked.load case.
+
; RUN: opt -thinlto-bc -thinlto-split-lto-unit %p/Inputs/devirt_single_hybrid_foo_tcl.ll -o %t-foo.bc
; RUN: llvm-lto2 run -save-temps %t-main.bc %t-foo.bc %t-bar.bc -pass-remarks=. -o %t \
; RUN: -whole-program-visibility \
More information about the llvm-commits
mailing list