diff --git a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp --- a/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp +++ b/llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp @@ -1099,6 +1099,10 @@ if (VTP.VTableOffset != P.AddressPointOffset + ByteOffset) continue; + assert((VTP.FuncVI) && "FuncVI must not be nullptr"); + if (mustBeUnreachableFunction(VTP.FuncVI)) + continue; + TargetsForSlot.push_back(VTP.FuncVI); } } diff --git a/llvm/test/ThinLTO/X86/Inputs/devirt_hybrid_after_filtering_unreachable_lib.ll b/llvm/test/ThinLTO/X86/Inputs/devirt_after_filtering_unreachable_lib.ll rename from llvm/test/ThinLTO/X86/Inputs/devirt_hybrid_after_filtering_unreachable_lib.ll rename to llvm/test/ThinLTO/X86/Inputs/devirt_after_filtering_unreachable_lib.ll diff --git a/llvm/test/ThinLTO/X86/devirt_hybrid_after_filtering_unreachable.ll b/llvm/test/ThinLTO/X86/devirt_after_filtering_unreachable.ll rename from llvm/test/ThinLTO/X86/devirt_hybrid_after_filtering_unreachable.ll rename to llvm/test/ThinLTO/X86/devirt_after_filtering_unreachable.ll --- a/llvm/test/ThinLTO/X86/devirt_hybrid_after_filtering_unreachable.ll +++ b/llvm/test/ThinLTO/X86/devirt_after_filtering_unreachable.ll @@ -1,9 +1,9 @@ -; Test that unreachable functions are ignored by WPD in hybrid LTO. +; Test that unreachable functions are ignored by WPD in hybrid LTO, and thin LTO. ; In this test case, the unreachable function is the virtual deleting destructor of an abstract class. ; Generate split module with summary for hybrid Regular LTO WPD ; RUN: opt -thinlto-bc -thinlto-split-lto-unit %s -o %t-main.bc -; RUN: opt -thinlto-bc -thinlto-split-lto-unit %p/Inputs/devirt_hybrid_after_filtering_unreachable_lib.ll -o %t-foo.bc +; RUN: opt -thinlto-bc -thinlto-split-lto-unit %p/Inputs/devirt_after_filtering_unreachable_lib.ll -o %t-foo.bc ; Tests that devirtualization happens. ; RUN: llvm-lto2 run -save-temps %t-main.bc %t-foo.bc -pass-remarks=. -o %t \ ; RUN: -whole-program-visibility \ @@ -56,6 +56,80 @@ ; REMARK-COUNT-1: single-impl: devirtualized a call to _ZN7DerivedD0Ev +; Generate unsplit module with summary for ThinLTO index-based WPD. +; RUN: opt -thinlto-bc -o %t3.o %s +; RUN: opt -thinlto-bc -o %t4.o %p/Inputs/devirt_after_filtering_unreachable_lib.ll + +; Check that EnableSplitLTOUnit is off, and check the content of summary information. +; RUN: llvm-dis -o - %t3.o | FileCheck %s --check-prefix=NOENABLESPLITFLAG +; NOENABLESPLITFLAG-DAG: !{i32 1, !"EnableSplitLTOUnit", i32 0} +; NOENABLESPLITFLAG-DAG: [[BaseD0:\^[0-9]+]] = gv: (name: "_ZN4BaseD0Ev" +; NOENABLESPLITFLAG-DAG: [[BaseD2:\^[0-9]+]] = gv: (name: "_ZN4BaseD2Ev" +; NOENABLESPLITFLAG-DAG: [[BaseTI:\^[0-9]+]] = gv: (name: "_ZTI4Base" +; NOENABLESPLITFLAG-DAG: [[PureVirtual:\^[0-9]+]] = gv: (name: "__cxa_pure_virtual" +; NOENABLESPLITFLAG-DAG: [[Base:\^[0-9]+]] = gv: (name: "_ZTV4Base", {{.*}} vTableFuncs: ((virtFunc: [[BaseD2]], offset: 16), (virtFunc: [[BaseD0]], offset: 24)), refs: ([[BaseTI]], [[BaseD2]], [[BaseD0]], [[PureVirtual]]) +; NOENABLESPLITFLAG-DAG: typeidCompatibleVTable: (name: "_ZTS4Base", summary: ((offset: 16, [[Base]]))) +; NOENABLESPLITFLAG-DAG: typeidCompatibleVTable: (name: "_ZTSM4BaseFvvE.virtual", summary: ((offset: 32, [[Base]]))) + +; Check that EnableSplitLTOUnit is off, and check the content of summary information. +; RUN: llvm-dis -o - %t4.o | FileCheck %s --check-prefix=LIBNOENABLESPLITFLAG +; LIBNOENABLESPLITFLAG-DAG: !{i32 1, !"EnableSplitLTOUnit", i32 0} +; LIBNOENABLESPLITFLAG-DAG: [[DerivedD0:\^[0-9]+]] = gv: (name: "_ZN7DerivedD0Ev" +; LIBNOENABLESPLITFLAG-DAG: [[BaseD0:\^[0-9]+]] = gv: (name: "_ZN4BaseD0Ev" +; LIBNOENABLESPLITFLAG-DAG: [[DerivedTI:\^[0-9]+]] = gv: (name: "_ZTI7Derived" +; LIBNOENABLESPLITFLAG-DAG: [[DerivedD2:\^[0-9]+]] = gv: (name: "_ZN7DerivedD2Ev" +; LIBNOENABLESPLITFLAG-DAG: [[DerivedX:\^[0-9]+]] = gv: (name: "_ZN7Derived1xEv" +; LIBNOENABLESPLITFLAG-DAG: [[BaseTI:\^[0-9]+]] = gv: (name: "_ZTI4Base" +; LIBNOENABLESPLITFLAG-DAG: [[PureVirtual:\^[0-9]+]] = gv: (name: "__cxa_pure_virtual" +; LIBNOENABLESPLITFLAG-DAG: [[BaseD2:\^[0-9]+]] = gv: (name: "_ZN4BaseD2Ev" +; LIBNOENABLESPLITFLAG-DAG: [[Base:\^[0-9]+]] = gv: (name: "_ZTV4Base", {{.*}} vTableFuncs: ((virtFunc: [[BaseD2]], offset: 16), (virtFunc: [[BaseD0]], offset: 24)), refs: ([[BaseTI]], [[BaseD2]], [[BaseD0]], [[PureVirtual]]) +; LIBNOENABLESPLITFLAG-DAG: [[Derived:\^[0-9]+]] = gv: (name: "_ZTV7Derived", {{.*}} vTableFuncs: ((virtFunc: [[DerivedD2]], offset: 16), (virtFunc: [[DerivedD0]], offset: 24), (virtFunc: [[DerivedX]], offset: 32)), refs: ([[DerivedTI]], [[DerivedX]], [[DerivedD2]], [[DerivedD0]]) +; LIBNOENABLESPLITFLAG-DAG: typeidCompatibleVTable: (name: "_ZTS4Base", summary: ((offset: 16, [[Derived]]), (offset: 16, [[Base]]))) +; LIBNOENABLESPLITFLAG-DAG: typeidCompatibleVTable: (name: "_ZTS7Derived", summary: ((offset: 16, [[Derived]]))) +; LIBNOENABLESPLITFLAG-DAG: typeidCompatibleVTable: (name: "_ZTSM4BaseFvvE.virtual", summary: ((offset: 32, [[Derived]]), (offset: 32, [[Base]]))) +; LIBNOENABLESPLITFLAG-DAG: typeidCompatibleVTable: (name: "_ZTSM7DerivedFvvE.virtual", summary: ((offset: 32, [[Derived]]))) + +; Index based WPD +; RUN: llvm-lto2 run %t4.o %t3.o -save-temps -pass-remarks=. \ +; RUN: -whole-program-visibility \ +; RUN: -wholeprogramdevirt-print-index-based \ +; RUN: -o %t5 \ +; RUN: -r=%t4.o,_ZN7Derived1xEv,pl \ +; RUN: -r=%t4.o,printf, \ +; RUN: -r=%t4.o,_Z3fooP4Base,pl \ +; RUN: -r=%t4.o,_ZN7DerivedD2Ev,pl \ +; RUN: -r=%t4.o,_ZN7DerivedD0Ev,pl \ +; RUN: -r=%t4.o,_ZN4BaseD2Ev,pl \ +; RUN: -r=%t4.o,_ZN4BaseD0Ev,pl \ +; RUN: -r=%t4.o,__cxa_pure_virtual, \ +; RUN: -r=%t4.o,_ZdlPv, \ +; RUN: -r=%t4.o,_ZTV7Derived,pl \ +; RUN: -r=%t4.o,_ZTVN10__cxxabiv120__si_class_type_infoE, \ +; RUN: -r=%t4.o,_ZTS7Derived,pl \ +; RUN: -r=%t4.o,_ZTVN10__cxxabiv117__class_type_infoE, \ +; RUN: -r=%t4.o,_ZTS4Base,pl \ +; RUN: -r=%t4.o,_ZTI4Base,pl \ +; RUN: -r=%t4.o,_ZTI7Derived,pl \ +; RUN: -r=%t4.o,_ZTV4Base,pl \ +; RUN: -r=%t3.o,main,plx \ +; RUN: -r=%t3.o,_Znwm, \ +; RUN: -r=%t3.o,_ZN7DerivedC2Ev,pl \ +; RUN: -r=%t3.o,_Z3fooP4Base, \ +; RUN: -r=%t3.o,_ZN4BaseC2Ev,pl \ +; RUN: -r=%t3.o,_ZN4BaseD2Ev, \ +; RUN: -r=%t3.o,_ZN4BaseD0Ev, \ +; RUN: -r=%t3.o,__cxa_pure_virtual, \ +; RUN: -r=%t3.o,printf, \ +; RUN: -r=%t3.o,_ZTV7Derived, \ +; RUN: -r=%t3.o,_ZTV4Base, \ +; RUN: -r=%t3.o,_ZTVN10__cxxabiv117__class_type_infoE, \ +; RUN: -r=%t3.o,_ZTS4Base, \ +; RUN: -r=%t3.o,_ZTI4Base, 2>&1 | FileCheck %s --check-prefix=PRINT --check-prefix=THINREMARK + +; PRINT-DAG: Devirtualized call to {{.*}} (_ZN7DerivedD0Ev) +; THINREMARK: single-impl: devirtualized a call to _ZN7DerivedD0Ev +; THINREMARK: single-impl: devirtualized a call to _ZN7DerivedD0Ev + ; ModuleID = 'tmp.cc' source_filename = "tmp.cc" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"