GlobalDCE: Delete available_externally initializers if it allows removing the value the initializer is referring to.

This is useful for functions that are not actually available externally but
referenced by a vtable of some kind. Clang emits functions like this for the MS
ABI.

PR20182.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212337 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer
2014-07-04 12:36:05 +00:00
parent f3f355dd95
commit 5b55a47e94
2 changed files with 74 additions and 4 deletions

View File

@@ -1,10 +1,43 @@
; RUN: opt < %s -globaldce -S | not grep test_
; RUN: opt < %s -globaldce -S | FileCheck %s
; test_function should not be emitted to the .s file.
; CHECK-NOT: @test_function
define available_externally i32 @test_function() {
ret i32 4
}
; test_global should not be emitted to the .s file.
; CHECK-NOT: @test_global
@test_global = available_externally global i32 4
; CHECK: @x = external constant void ()*
@x = available_externally constant void()* @f
; CHECK: @y = external constant i32
@y = available_externally constant i32 ptrtoint (void()* @g to i32)
; @h is still alive, so don't remove the initializer too eagerly.
; CHECK: @z = available_externally constant i8 ptrtoint (void (i8)* @h to i8)
@z = available_externally constant i8 ptrtoint (void(i8)* @h to i8)
; CHECK-NOT: @f
define linkonce_odr void @f() {
ret void
}
; CHECK-NOT: @g
define linkonce_odr void @g() {
ret void
}
; CHECK: define linkonce_odr void @h
define linkonce_odr void @h(i8) {
ret void
}
define i32 @main() {
%f = load void()** @x
call void %f()
%g = load i32* @y
%h = load i8* @z
call void @h(i8 %h)
ret i32 %g
}