blob: ef44820d55b4286e8ffabc84fac4ff58a22261c0 [file] [edit]
; RUN: split-file %s %t
; RUN: opt -S -passes=mergefunc %t/coff.ll | FileCheck %s --check-prefix=COFF
; RUN: opt -S -passes=mergefunc %t/coff-noalias.ll | \
; RUN: FileCheck %s --check-prefix=NOALIAS
; RUN: opt -S -passes=mergefunc -mergefunc-use-aliases %t/coff-odr.ll | \
; RUN: FileCheck %s --check-prefix=ODR
; RUN: opt -S -passes=mergefunc %t/elf.ll | FileCheck %s --check-prefix=ELF
; A COFF weak external names the symbol it resolves to, and a local symbol
; cannot be named, so an alias must keep pointing at an external definition.
;--- coff.ll
target triple = "x86_64-pc-windows-msvc"
; @f is local, so @g is kept as a thunk rather than replaced, and the alias
; goes on naming @g.
; COFF: @alias_g = weak alias i32 (i32), ptr @g
; COFF: define internal i32 @f
; COFF: define linkonce_odr i32 @g
@alias_g = weak alias i32 (i32), ptr @g
define internal i32 @f(i32 %x) {
%a = mul i32 %x, 3
%b = add i32 %a, 7
ret i32 %b
}
define linkonce_odr i32 @g(i32 %x) unnamed_addr {
%a = mul i32 %x, 3
%b = add i32 %a, 7
ret i32 %b
}
;--- coff-noalias.ll
target triple = "x86_64-pc-windows-msvc"
; Without an alias naming it, @g is replaced as usual.
; NOALIAS: define internal i32 @f
; NOALIAS: call i32 @f
define internal i32 @f(i32 %x) {
%a = mul i32 %x, 3
%b = add i32 %a, 7
ret i32 %b
}
define linkonce_odr i32 @g(i32 %x) unnamed_addr {
%a = mul i32 %x, 3
%b = add i32 %a, 7
ret i32 %b
}
define i32 @use() {
%r = call i32 @g(i32 1)
ret i32 %r
}
;--- coff-odr.ll
target triple = "x86_64-pc-windows-msvc"
; The shared body is private, so both halves get a thunk instead of an alias
; even though aliases are enabled.
; ODR-NOT: alias i32
; ODR-DAG: define weak_odr i32 @f
; ODR-DAG: define weak_odr i32 @g
define weak_odr i32 @f(i32 %x) unnamed_addr {
%a = mul i32 %x, 3
%b = add i32 %a, 7
%c = add i32 %b, 1
ret i32 %c
}
define weak_odr i32 @g(i32 %x) unnamed_addr {
%a = mul i32 %x, 3
%b = add i32 %a, 7
%c = add i32 %b, 1
ret i32 %c
}
;--- elf.ll
target triple = "x86_64-unknown-linux-gnu"
; Other formats can alias a local symbol, so @g is replaced there.
; ELF: @alias_g = weak alias i32 (i32), ptr @f
; ELF: define internal i32 @f
; ELF-NOT: define {{.*}} @g
@alias_g = weak alias i32 (i32), ptr @g
define internal i32 @f(i32 %x) {
%a = mul i32 %x, 3
%b = add i32 %a, 7
ret i32 %b
}
define linkonce_odr i32 @g(i32 %x) unnamed_addr {
%a = mul i32 %x, 3
%b = add i32 %a, 7
ret i32 %b
}