[PATCH] D109114: [GlobalDCE] In VFE, replace the whole 'sub' expression of unused relative-pointer-based vtable slots
Kuba (Brecka) Mracek via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 15 14:00:42 PDT 2021
kubamracek updated this revision to Diff 372796.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D109114/new/
https://reviews.llvm.org/D109114
Files:
llvm/lib/Transforms/IPO/GlobalDCE.cpp
llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers-bad.ll
llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers-gep.ll
llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers.ll
Index: llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers.ll
+++ llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers.ll
@@ -14,7 +14,7 @@
; CHECK: @vtable = internal unnamed_addr constant { [2 x i32] } { [2 x i32] [
; CHECK-SAME: i32 trunc (i64 sub (i64 ptrtoint (void ()* @vfunc1_live to i64), i64 ptrtoint ({ [2 x i32] }* @vtable to i64)) to i32),
-; CHECK-SAME: i32 trunc (i64 sub (i64 0, i64 ptrtoint ({ [2 x i32] }* @vtable to i64)) to i32)
+; CHECK-SAME: i32 0
; CHECK-SAME: ] }, align 8, !type !0, !type !1, !vcall_visibility !2
; (1) vfunc1_live is referenced from @main, stays alive
Index: llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers-gep.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers-gep.ll
+++ llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers-gep.ll
@@ -16,7 +16,7 @@
; CHECK: @vtable = internal unnamed_addr constant { [4 x i32] } { [4 x i32] [
; CHECK-SAME: i32 trunc (i64 sub (i64 ptrtoint (void ()* @vfunc1_live to i64), i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @vtable, i32 0, i32 0, i32 2) to i64)) to i32),
-; CHECK-SAME: i32 trunc (i64 sub (i64 0, i64 ptrtoint (i32* getelementptr inbounds ({ [4 x i32] }, { [4 x i32] }* @vtable, i32 0, i32 0, i32 2) to i64)) to i32)
+; CHECK-SAME: i32 0
; CHECK-SAME: ] }, align 8, !type !0, !type !1, !vcall_visibility !2
; (1) vfunc1_live is referenced from @main, stays alive
Index: llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers-bad.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers-bad.ll
+++ llvm/test/Transforms/GlobalDCE/virtual-functions-relative-pointers-bad.ll
@@ -15,9 +15,9 @@
!1 = !{i64 4, !"vfunc2.type"}
; CHECK: @vtable = internal unnamed_addr constant { [3 x i32] } { [3 x i32] [
-; CHECK-SAME: i32 trunc (i64 sub (i64 0, i64 ptrtoint ({ [3 x i32] }* @vtable to i64)) to i32),
-; CHECK-SAME: i32 trunc (i64 sub (i64 0, i64 ptrtoint ({ [3 x i32] }* @vtable to i64)) to i32),
-; CHECK-SAME: i32 trunc (i64 sub (i64 0, i64 ptrtoint (void ()* @weird_ref_2 to i64)) to i32)
+; CHECK-SAME: i32 0,
+; CHECK-SAME: i32 0,
+; CHECK-SAME: i32 0
; CHECK-SAME: ] }, align 8, !type !0, !type !1, !vcall_visibility !2
define internal void @vfunc1() { ret void }
Index: llvm/lib/Transforms/IPO/GlobalDCE.cpp
===================================================================
--- llvm/lib/Transforms/IPO/GlobalDCE.cpp
+++ llvm/lib/Transforms/IPO/GlobalDCE.cpp
@@ -416,6 +416,29 @@
// virtual function pointers with null, allowing us to remove the
// function itself.
++NumVFuncs;
+
+ // Detect vfuncs that are referenced as "relative pointers" which are used
+ // in Swift vtables, i.e. entries in the form of:
+ //
+ // i32 trunc (i64 sub (i64 ptrtoint @f, i64 ptrtoint ...)) to i32)
+ //
+ // In this case, replace the whole "sub" expression with constant 0 to
+ // avoid leaving a weird sub(0, symbol) expression behind.
+ for (auto *U : F->users()) {
+ if (auto *PtrExpr = dyn_cast<ConstantExpr>(U)) {
+ if (PtrExpr->getOpcode() == Instruction::PtrToInt) {
+ assert(PtrExpr->hasOneUser());
+ if (auto *SubExpr = dyn_cast<ConstantExpr>(PtrExpr->user_back())) {
+ assert(SubExpr->hasOneUser());
+ if (SubExpr->getOpcode() == Instruction::Sub) {
+ SubExpr->replaceNonMetadataUsesWith(
+ ConstantInt::get(SubExpr->getType(), 0));
+ }
+ }
+ }
+ }
+ }
+
F->replaceNonMetadataUsesWith(ConstantPointerNull::get(F->getType()));
}
EraseUnusedGlobalValue(F);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D109114.372796.patch
Type: text/x-patch
Size: 4175 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210915/dbe2a96f/attachment.bin>
More information about the llvm-commits
mailing list