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,9 @@ if (VTP.VTableOffset != P.AddressPointOffset + ByteOffset) continue; + 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,20 @@ -; 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 + +; Check that deleting destructor of pure virtual class is unreachable. +; RUN: llvm-modextract -b -n=0 %t-main.bc -o %t-main.bc.0 +; RUN: llvm-dis -o - %t-main.bc.0 | FileCheck %s --check-prefix=ENABLESPLITFLAG +; ENABLESPLITFLAG-DAG: [[BaseD0:\^[0-9]+]] = gv: (name: "_ZN4BaseD0Ev", {{.*}}, funcFlags: ({{.*}} mustBeUnreachable: 1 + +; Check that deleting destructor of pure virtual class is unreachable. +; RUN: llvm-modextract -b -n=0 %t-foo.bc -o %t-foo.bc.0 +; RUN: llvm-dis -o - %t-foo.bc.0 | FileCheck %s --check-prefix=LIBENABLESPLITFLAG +; LIBENABLESPLITFLAG-DAG: [[BaseD0:\^[0-9]+]] = gv: (name: "_ZN4BaseD0Ev", {{.*}}, funcFlags: ({{.*}} mustBeUnreachable: 1 + ; 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 +67,59 @@ ; 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 deleting destructor of pure virtual class is unreachable. +; RUN: llvm-dis -o - %t3.o | FileCheck %s --check-prefix=NOENABLESPLITFLAG +; NOENABLESPLITFLAG-DAG: [[BaseD0:\^[0-9]+]] = gv: (name: "_ZN4BaseD0Ev", {{.*}}, funcFlags: ({{.*}} mustBeUnreachable: 1 + +; Check that deleting destructor of pure virtual class is unreachable. +; RUN: llvm-dis -o - %t4.o | FileCheck %s --check-prefix=LIBNOENABLESPLITFLAG +; LIBNOENABLESPLITFLAG-DAG: [[BaseD0:\^[0-9]+]] = gv: (name: "_ZN4BaseD0Ev", {{.*}}, funcFlags: ({{.*}} mustBeUnreachable: 1 + +; Test that devirtualized happen in 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=THINREMARK + +; THINREMARK: 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"