tejohnson updated this revision to Diff 239406.
tejohnson added a comment.

Remove stale change that didn't belong here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D71907/new/

https://reviews.llvm.org/D71907

Files:
  clang/lib/CodeGen/CGVTables.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGenCXX/vcall-visibility-metadata.cpp
  llvm/include/llvm/IR/GlobalObject.h
  llvm/lib/IR/Metadata.cpp
  llvm/lib/Transforms/IPO/GlobalDCE.cpp
  llvm/lib/Transforms/IPO/GlobalSplit.cpp
  llvm/test/Transforms/GlobalDCE/virtual-functions-base-call.ll
  llvm/test/Transforms/GlobalDCE/virtual-functions-base-pointer-call.ll
  llvm/test/Transforms/GlobalDCE/virtual-functions-derived-call.ll
  llvm/test/Transforms/GlobalDCE/virtual-functions-derived-pointer-call.ll
  llvm/test/Transforms/GlobalDCE/virtual-functions-novfe.ll
  llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-post-lto.ll
  llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-pre-lto.ll
  llvm/test/Transforms/GlobalDCE/virtual-functions.ll
  llvm/test/Transforms/GlobalDCE/vtable-rtti.ll

Index: llvm/test/Transforms/GlobalDCE/vtable-rtti.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/vtable-rtti.ll
+++ llvm/test/Transforms/GlobalDCE/vtable-rtti.ll
@@ -39,9 +39,10 @@
 declare dso_local noalias nonnull i8* @_Znwm(i64)
 @_ZTVN10__cxxabiv117__class_type_infoE = external dso_local global i8*
 
-!llvm.module.flags = !{!3}
+!llvm.module.flags = !{!3, !4}
 
 !0 = !{i64 16, !"_ZTS1A"}
 !1 = !{i64 16, !"_ZTSM1AFvvE.virtual"}
 !2 = !{i64 2} ; translation-unit vcall visibility
 !3 = !{i32 1, !"LTOPostLink", i32 1}
+!4 = !{i32 1, !"Virtual Function Elim", i32 1}
Index: llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-pre-lto.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-pre-lto.ll
+++ llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-pre-lto.ll
@@ -85,10 +85,11 @@
 
 declare dso_local noalias nonnull i8* @_Znwm(i64)
 
-!llvm.module.flags = !{}
+!llvm.module.flags = !{!5}
 
 !0 = !{i64 16, !"_ZTS1A"}
 !1 = !{i64 16, !"_ZTSM1AFvvE.virtual"}
 !2 = !{i64 0} ; public vcall visibility
 !3 = !{i64 1} ; linkage-unit vcall visibility
 !4 = !{i64 2} ; translation-unit vcall visibility
+!5 = !{i32 1, !"Virtual Function Elim", i32 1}
Index: llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-post-lto.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-post-lto.ll
+++ llvm/test/Transforms/GlobalDCE/virtual-functions-visibility-post-lto.ll
@@ -85,7 +85,7 @@
 
 declare dso_local noalias nonnull i8* @_Znwm(i64)
 
-!llvm.module.flags = !{!5}
+!llvm.module.flags = !{!5, !6}
 
 !0 = !{i64 16, !"_ZTS1A"}
 !1 = !{i64 16, !"_ZTSM1AFvvE.virtual"}
@@ -93,3 +93,4 @@
 !3 = !{i64 1} ; linkage-unit vcall visibility
 !4 = !{i64 2} ; translation-unit vcall visibility
 !5 = !{i32 1, !"LTOPostLink", i32 1}
+!6 = !{i32 1, !"Virtual Function Elim", i32 1}
Index: llvm/test/Transforms/GlobalDCE/virtual-functions.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/virtual-functions.ll
+++ llvm/test/Transforms/GlobalDCE/virtual-functions.ll
@@ -48,8 +48,11 @@
   ret i32 %call1
 }
 
+!llvm.module.flags = !{!4}
+
 !0 = !{i64 16, !"_ZTS1A"}
 !1 = !{i64 16, !"_ZTSM1AFivE.virtual"}
 !2 = !{i64 24, !"_ZTSM1AFivE.virtual"}
 !3 = !{i64 2}
+!4 = !{i32 1, !"Virtual Function Elim", i32 1}
 !9 = !{}
Index: llvm/test/Transforms/GlobalDCE/virtual-functions-novfe.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/virtual-functions-novfe.ll
+++ llvm/test/Transforms/GlobalDCE/virtual-functions-novfe.ll
@@ -1,3 +1,5 @@
+; Tests that VFE is not performed when the Virtual Function Elim metadata set
+; to 0. This is the same as virtual-functions.ll otherwise.
 ; RUN: opt < %s -globaldce -S | FileCheck %s
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@@ -11,14 +13,12 @@
 ; intrinsic. Function test_A makes a call to A::foo, but there is no call to
 ; A::bar anywhere, so A::bar can be deleted, and its vtable slot replaced with
 ; null.
+; However, with the metadata set to 0 we should not perform this VFE.
 
 %struct.A = type { i32 (...)** }
 
-; The pointer to A::bar in the vtable can be removed, because it will never be
-; loaded. We replace it with null to keep the layout the same. Because it is at
-; the end of the vtable we could potentially shrink the vtable, but don't
-; currently do that.
-; CHECK: @_ZTV1A = internal unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* null, i8* bitcast (i32 (%struct.A*)* @_ZN1A3fooEv to i8*), i8* null] }
+; We should retain @_ZN1A3barEv in the vtable.
+; CHECK: @_ZTV1A = internal unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* null, i8* bitcast (i32 (%struct.A*)* @_ZN1A3fooEv to i8*), i8* bitcast (i32 (%struct.A*)* @_ZN1A3barEv to i8*)] }
 @_ZTV1A = internal unnamed_addr constant { [4 x i8*] } { [4 x i8*] [i8* null, i8* null, i8* bitcast (i32 (%struct.A*)* @_ZN1A3fooEv to i8*), i8* bitcast (i32 (%struct.A*)* @_ZN1A3barEv to i8*)] }, align 8, !type !0, !type !1, !type !2, !vcall_visibility !3
 
 ; A::foo is called, so must be retained.
@@ -28,8 +28,9 @@
   ret i32 42
 }
 
-; A::bar is not used, so can be deleted.
-; CHECK-NOT: define internal i32 @_ZN1A3barEv(
+; A::bar is not used, so can be deleted with VFE, however, we should not be
+; performing that elimination here.
+; CHECK: define internal i32 @_ZN1A3barEv(
 define internal i32 @_ZN1A3barEv(%struct.A* nocapture readnone %this) {
 entry:
   ret i32 1337
@@ -48,8 +49,11 @@
   ret i32 %call1
 }
 
+!llvm.module.flags = !{!4}
+
 !0 = !{i64 16, !"_ZTS1A"}
 !1 = !{i64 16, !"_ZTSM1AFivE.virtual"}
 !2 = !{i64 24, !"_ZTSM1AFivE.virtual"}
 !3 = !{i64 2}
+!4 = !{i32 1, !"Virtual Function Elim", i32 0}
 !9 = !{}
Index: llvm/test/Transforms/GlobalDCE/virtual-functions-derived-pointer-call.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/virtual-functions-derived-pointer-call.ll
+++ llvm/test/Transforms/GlobalDCE/virtual-functions-derived-pointer-call.ll
@@ -110,6 +110,8 @@
 
 declare { i8*, i1 } @llvm.type.checked.load(i8*, i32, metadata)
 
+!llvm.module.flags = !{!7}
+
 !0 = !{i64 16, !"_ZTS1A"}
 !1 = !{i64 16, !"_ZTSM1AFiiE.virtual"}
 !2 = !{i64 24, !"_ZTSM1AFifE.virtual"}
@@ -117,4 +119,5 @@
 !4 = !{i64 16, !"_ZTS1B"}
 !5 = !{i64 16, !"_ZTSM1BFiiE.virtual"}
 !6 = !{i64 24, !"_ZTSM1BFifE.virtual"}
+!7 = !{i32 1, !"Virtual Function Elim", i32 1}
 !12 = !{}
Index: llvm/test/Transforms/GlobalDCE/virtual-functions-derived-call.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/virtual-functions-derived-call.ll
+++ llvm/test/Transforms/GlobalDCE/virtual-functions-derived-call.ll
@@ -70,9 +70,12 @@
 
 declare { i8*, i1 } @llvm.type.checked.load(i8*, i32, metadata) #2
 
+!llvm.module.flags = !{!5}
+
 !0 = !{i64 16, !"_ZTS1A"}
 !1 = !{i64 16, !"_ZTSM1AFivE.virtual"}
 !2 = !{i64 2}
 !3 = !{i64 16, !"_ZTS1B"}
 !4 = !{i64 16, !"_ZTSM1BFivE.virtual"}
+!5 = !{i32 1, !"Virtual Function Elim", i32 1}
 !10 = !{}
Index: llvm/test/Transforms/GlobalDCE/virtual-functions-base-pointer-call.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/virtual-functions-base-pointer-call.ll
+++ llvm/test/Transforms/GlobalDCE/virtual-functions-base-pointer-call.ll
@@ -108,6 +108,8 @@
 
 declare { i8*, i1 } @llvm.type.checked.load(i8*, i32, metadata)
 
+!llvm.module.flags = !{!7}
+
 !0 = !{i64 16, !"_ZTS1A"}
 !1 = !{i64 16, !"_ZTSM1AFiiE.virtual"}
 !2 = !{i64 24, !"_ZTSM1AFifE.virtual"}
@@ -115,4 +117,5 @@
 !4 = !{i64 16, !"_ZTS1B"}
 !5 = !{i64 16, !"_ZTSM1BFiiE.virtual"}
 !6 = !{i64 24, !"_ZTSM1BFifE.virtual"}
+!7 = !{i32 1, !"Virtual Function Elim", i32 1}
 !12 = !{}
Index: llvm/test/Transforms/GlobalDCE/virtual-functions-base-call.ll
===================================================================
--- llvm/test/Transforms/GlobalDCE/virtual-functions-base-call.ll
+++ llvm/test/Transforms/GlobalDCE/virtual-functions-base-call.ll
@@ -70,9 +70,12 @@
 
 declare { i8*, i1 } @llvm.type.checked.load(i8*, i32, metadata) #2
 
+!llvm.module.flags = !{!5}
+
 !0 = !{i64 16, !"_ZTS1A"}
 !1 = !{i64 16, !"_ZTSM1AFivE.virtual"}
 !2 = !{i64 2}
 !3 = !{i64 16, !"_ZTS1B"}
 !4 = !{i64 16, !"_ZTSM1BFivE.virtual"}
+!5 = !{i32 1, !"Virtual Function Elim", i32 1}
 !10 = !{}
Index: llvm/lib/Transforms/IPO/GlobalSplit.cpp
===================================================================
--- llvm/lib/Transforms/IPO/GlobalSplit.cpp
+++ llvm/lib/Transforms/IPO/GlobalSplit.cpp
@@ -111,6 +111,9 @@
                             ConstantInt::get(Int32Ty, ByteOffset - SplitBegin)),
                         Type->getOperand(1)}));
     }
+
+    if (GV.hasMetadata(LLVMContext::MD_vcall_visibility))
+      SplitGV->setVCallVisibilityMetadata(GV.getVCallVisibility());
   }
 
   for (User *U : GV.users()) {
Index: llvm/lib/Transforms/IPO/GlobalDCE.cpp
===================================================================
--- llvm/lib/Transforms/IPO/GlobalDCE.cpp
+++ llvm/lib/Transforms/IPO/GlobalDCE.cpp
@@ -263,6 +263,15 @@
   if (!ClEnableVFE)
     return;
 
+  // If the Virtual Function Elim module flag is present and set to zero, then
+  // the vcall_visibility metadata was inserted for another optimization (WPD)
+  // and we may not have type checked loads on all accesses to the vtable.
+  // Don't attempt VFE in that case.
+  auto *Val = mdconst::dyn_extract_or_null<ConstantInt>(
+      M.getModuleFlag("Virtual Function Elim"));
+  if (!Val || Val->getZExtValue() == 0)
+    return;
+
   ScanVTables(M);
 
   if (VFESafeVTables.empty())
Index: llvm/lib/IR/Metadata.cpp
===================================================================
--- llvm/lib/IR/Metadata.cpp
+++ llvm/lib/IR/Metadata.cpp
@@ -1500,7 +1500,10 @@
                      TypeID}));
 }
 
-void GlobalObject::addVCallVisibilityMetadata(VCallVisibility Visibility) {
+void GlobalObject::setVCallVisibilityMetadata(VCallVisibility Visibility) {
+  // Remove any existing vcall visibility metadata first in case we are
+  // updating.
+  eraseMetadata(LLVMContext::MD_vcall_visibility);
   addMetadata(LLVMContext::MD_vcall_visibility,
               *MDNode::get(getContext(),
                            {ConstantAsMetadata::get(ConstantInt::get(
Index: llvm/include/llvm/IR/GlobalObject.h
===================================================================
--- llvm/include/llvm/IR/GlobalObject.h
+++ llvm/include/llvm/IR/GlobalObject.h
@@ -178,7 +178,7 @@
   void copyMetadata(const GlobalObject *Src, unsigned Offset);
 
   void addTypeMetadata(unsigned Offset, Metadata *TypeID);
-  void addVCallVisibilityMetadata(VCallVisibility Visibility);
+  void setVCallVisibilityMetadata(VCallVisibility Visibility);
   VCallVisibility getVCallVisibility() const;
 
 protected:
Index: clang/test/CodeGenCXX/vcall-visibility-metadata.cpp
===================================================================
--- clang/test/CodeGenCXX/vcall-visibility-metadata.cpp
+++ clang/test/CodeGenCXX/vcall-visibility-metadata.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -emit-llvm -fvirtual-function-elimination -fwhole-program-vtables -o - %s | FileCheck %s
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -emit-llvm -fvirtual-function-elimination -fwhole-program-vtables -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VFE
+// RUN: %clang_cc1 -flto -flto-unit -triple x86_64-unknown-linux -emit-llvm -fwhole-program-vtables -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOVFE
 
 
 // Anonymous namespace.
@@ -83,6 +84,7 @@
   return new G();
 }
 
-
 // CHECK-DAG: [[VIS_DSO]] = !{i64 1}
 // CHECK-DAG: [[VIS_TU]] = !{i64 2}
+// CHECK-VFE-DAG: !{i32 1, !"Virtual Function Elim", i32 1}
+// CHECK-NOVFE-DAG: !{i32 1, !"Virtual Function Elim", i32 0}
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -542,6 +542,14 @@
     getModule().addModuleFlag(llvm::Module::Override, "Cross-DSO CFI", 1);
   }
 
+  if (CodeGenOpts.WholeProgramVTables) {
+    // Indicate whether VFE was enabled for this module, so that the
+    // vcall_visibility metadata added under whole program vtables is handled
+    // appropriately in the optimizer.
+    getModule().addModuleFlag(llvm::Module::Error, "Virtual Function Elim",
+                              CodeGenOpts.VirtualFunctionElimination);
+  }
+
   if (LangOpts.Sanitize.has(SanitizerKind::CFIICall)) {
     getModule().addModuleFlag(llvm::Module::Override,
                               "CFI Canonical Jump Tables",
Index: clang/lib/CodeGen/CGVTables.cpp
===================================================================
--- clang/lib/CodeGen/CGVTables.cpp
+++ clang/lib/CodeGen/CGVTables.cpp
@@ -1131,9 +1131,10 @@
     }
   }
 
-  if (getCodeGenOpts().VirtualFunctionElimination) {
+  if (getCodeGenOpts().VirtualFunctionElimination ||
+      getCodeGenOpts().WholeProgramVTables) {
     llvm::GlobalObject::VCallVisibility TypeVis = GetVCallVisibilityLevel(RD);
     if (TypeVis != llvm::GlobalObject::VCallVisibilityPublic)
-      VTable->addVCallVisibilityMetadata(TypeVis);
+      VTable->setVCallVisibilityMetadata(TypeVis);
   }
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to