From f3336bc1d52832a299d0530fb20071e8517bd80b Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 12 Mar 2014 20:15:49 +0000 Subject: [PATCH] Reject alias to undefined symbols in the verifier. On ELF and COFF an alias is just another name for a position in the file. There is no way to refer to a position in another file, so an alias to undefined is meaningless. MachO currently doesn't support aliases. The spec has a N_INDR, which when implemented will have a different set of restrictions. Adding support for it shouldn't be harder than any other IR extension. For now, having the IR represent what is actually possible with current tools makes it easier to fix the design of GlobalAlias. llvm-svn: 203705 --- llvm/docs/LangRef.rst | 5 + llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 6 +- llvm/lib/IR/Verifier.cpp | 1 + .../Analysis/BasicAA/2007-11-05-SizeCrash.ll | 2 +- .../BasicAA/2007-12-08-OutOfBoundsCrash.ll | 2 +- llvm/test/Assembler/2007-09-10-AliasFwdRef.ll | 4 +- .../CodeGen/X86/2008-03-14-SpillerCrash.ll | 2 +- llvm/test/CodeGen/X86/alias-error.ll | 5 - llvm/test/Feature/aliases.ll | 6 +- llvm/test/Linker/2011-08-22-ResolveAlias2.ll | 108 +++++++++++++----- .../Transforms/GVN/2009-03-10-PREOnVoid.ll | 56 ++++++--- .../GlobalOpt/2009-02-15-BitcastAlias.ll | 2 +- .../Transforms/GlobalOpt/alias-resolve.ll | 6 +- .../InstCombine/2007-09-10-AliasConstFold.ll | 4 +- .../InstCombine/2007-09-17-AliasConstFold2.ll | 4 +- .../Transforms/MetaRenamer/metarenamer.ll | 4 +- llvm/test/Verifier/alias.ll | 12 ++ 17 files changed, 166 insertions(+), 63 deletions(-) delete mode 100644 llvm/test/CodeGen/X86/alias-error.ll create mode 100644 llvm/test/Verifier/alias.ll diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index cf1243a04b10..0a46e8375e2c 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -687,6 +687,11 @@ The linkage must be one of ``private``, ``linker_private``, might not correctly handle dropping a weak symbol that is aliased by a non-weak alias. +Alias that are not ``unnamed_addr`` are guaranteed to have the same address as +the aliasee. + +The aliasee must be a definition. + .. _namedmetadatastructure: Named Metadata diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index ebca8e544baa..66ce4e1075d7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -928,11 +928,7 @@ bool AsmPrinter::doFinalization(Module &M) { MCSymbol *Name = getSymbol(I); const GlobalValue *GV = I->getAliasedGlobal(); - if (GV->isDeclaration()) { - report_fatal_error(Name->getName() + - ": Target doesn't support aliases to declarations"); - } - + assert(!GV->isDeclaration()); MCSymbol *Target = getSymbol(GV); if (I->hasExternalLinkage() || !MAI->getWeakRefDirective()) diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index fcdbac2f9f6f..2fc77cc2d727 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -501,6 +501,7 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) { &GA); } } + Assert1(!GV->isDeclaration(), "Alias must point to a definition", &GA); const GlobalValue* Resolved = GA.resolveAliasedGlobal(/*stopOnWeak*/ false); Assert1(Resolved, diff --git a/llvm/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll b/llvm/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll index 563d3326367b..32d9930f4270 100644 --- a/llvm/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll +++ b/llvm/test/Analysis/BasicAA/2007-11-05-SizeCrash.ll @@ -7,7 +7,7 @@ target triple = "x86_64-unknown-linux-gnu" %struct.pci_device_id = type { i32, i32, i32, i32, i32, i32, i64 } %struct.usb_bus = type { %struct.device* } %struct.usb_hcd = type { %struct.usb_bus, i64, [0 x i64] } -@uhci_pci_ids = external constant [1 x %struct.pci_device_id] ; <[1 x %struct.pci_device_id]*> [#uses=1] +@uhci_pci_ids = constant [1 x %struct.pci_device_id] zeroinitializer @__mod_pci_device_table = alias [1 x %struct.pci_device_id]* @uhci_pci_ids ; <[1 x %struct.pci_device_id]*> [#uses=0] diff --git a/llvm/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll b/llvm/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll index 52d0af1b81ce..cd997ea52513 100644 --- a/llvm/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll +++ b/llvm/test/Analysis/BasicAA/2007-12-08-OutOfBoundsCrash.ll @@ -7,7 +7,7 @@ target triple = "x86_64-unknown-linux-gnu" %struct.pci_device_id = type { i32, i32, i32, i32, i32, i32, i64 } %struct.usb_bus = type { %struct.device* } %struct.usb_hcd = type { %struct.usb_bus, [0 x i64] } -@pci_ids = external constant [1 x %struct.pci_device_id] ; <[1 x %struct.pci_device_id]*> [#uses=1] +@pci_ids = constant [1 x %struct.pci_device_id] zeroinitializer @__mod_pci_device_table = alias [1 x %struct.pci_device_id]* @pci_ids ; <[1 x %struct.pci_device_id]*> [#uses=0] diff --git a/llvm/test/Assembler/2007-09-10-AliasFwdRef.ll b/llvm/test/Assembler/2007-09-10-AliasFwdRef.ll index b21491ba5a90..2ebfc2719e95 100644 --- a/llvm/test/Assembler/2007-09-10-AliasFwdRef.ll +++ b/llvm/test/Assembler/2007-09-10-AliasFwdRef.ll @@ -6,4 +6,6 @@ -declare extern_weak i32 @pthread_cancel(i32) +define weak i32 @pthread_cancel(i32) { + ret i32 0 +} diff --git a/llvm/test/CodeGen/X86/2008-03-14-SpillerCrash.ll b/llvm/test/CodeGen/X86/2008-03-14-SpillerCrash.ll index 18b3714f851f..6b374a7f6f08 100644 --- a/llvm/test/CodeGen/X86/2008-03-14-SpillerCrash.ll +++ b/llvm/test/CodeGen/X86/2008-03-14-SpillerCrash.ll @@ -6,7 +6,7 @@ %struct.locale_data = type { i8*, i8*, i32, i32, { void (%struct.locale_data*)*, %struct.anon }, i32, i32, i32, [0 x %struct.locale_data_value] } %struct.locale_data_value = type { i32* } -@wcstoll_l = alias i64 (i32*, i32**, i32, %struct.__locale_struct*)* @__wcstoll_l ; [#uses=0] +@wcstoll_l = alias i64 (i32*, i32**, i32, %struct.__locale_struct*)* @__wcstoll_l define i64 @____wcstoll_l_internal(i32* %nptr, i32** %endptr, i32 %base, i32 %group, %struct.__locale_struct* %loc) nounwind { entry: diff --git a/llvm/test/CodeGen/X86/alias-error.ll b/llvm/test/CodeGen/X86/alias-error.ll deleted file mode 100644 index 8f01dcff2bf9..000000000000 --- a/llvm/test/CodeGen/X86/alias-error.ll +++ /dev/null @@ -1,5 +0,0 @@ -; RUN: not llc -mtriple=i686-pc-linux-gnu %s -o /dev/null 2>&1 | FileCheck %s - -@a = external global i32 -@b = alias i32* @a -; CHECK: b: Target doesn't support aliases to declarations diff --git a/llvm/test/Feature/aliases.ll b/llvm/test/Feature/aliases.ll index 139381215ee8..7ffa5f260136 100644 --- a/llvm/test/Feature/aliases.ll +++ b/llvm/test/Feature/aliases.ll @@ -4,14 +4,16 @@ @llvm.used = appending global [1 x i8*] [i8* bitcast (i32* @foo1 to i8*)], section "llvm.metadata" -@bar = external global i32 +@bar = global i32 0 @foo1 = alias i32* @bar @foo2 = alias i32* @bar @foo3 = alias i32* @foo2 %FunTy = type i32() -declare i32 @foo_f() +define i32 @foo_f() { + ret i32 0 +} @bar_f = alias weak %FunTy* @foo_f @bar_ff = alias i32()* @bar_f diff --git a/llvm/test/Linker/2011-08-22-ResolveAlias2.ll b/llvm/test/Linker/2011-08-22-ResolveAlias2.ll index 254904059733..eee60d49d026 100644 --- a/llvm/test/Linker/2011-08-22-ResolveAlias2.ll +++ b/llvm/test/Linker/2011-08-22-ResolveAlias2.ll @@ -37,56 +37,110 @@ @_ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti = alias weak i32 (%union.pthread_mutexattr_t*, i32)* @pthread_mutexattr_settype @_ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t = alias weak i32 (%union.pthread_mutexattr_t*)* @pthread_mutexattr_destroy -declare void @_ZN13HexxagonBoardC2ERKS_(%struct.HexxagonBoard*, %struct.HexxagonBoard*) uwtable align 2 +define void @_ZN13HexxagonBoardC2ERKS_(%struct.HexxagonBoard*, %struct.HexxagonBoard*) uwtable align 2 { + ret void +} -declare extern_weak i32 @pthread_once(i32*, void ()*) +define weak i32 @pthread_once(i32*, void ()*) { + ret i32 0 +} -declare extern_weak i8* @pthread_getspecific(i32) +define weak i8* @pthread_getspecific(i32) { + ret i8* null +} -declare extern_weak i32 @pthread_setspecific(i32, i8*) +define weak i32 @pthread_setspecific(i32, i8*) { + ret i32 0 +} -declare extern_weak i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*) +define weak i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*) { + ret i32 0 +} -declare extern_weak i32 @pthread_join(i64, i8**) +define weak i32 @pthread_join(i64, i8**) { + ret i32 0 +} -declare extern_weak i32 @pthread_equal(i64, i64) +define weak i32 @pthread_equal(i64, i64) { + ret i32 0 +} -declare extern_weak i64 @pthread_self() +define weak i64 @pthread_self() { + ret i64 0 +} -declare extern_weak i32 @pthread_detach(i64) +define weak i32 @pthread_detach(i64) { + ret i32 0 +} -declare extern_weak i32 @pthread_cancel(i64) +define weak i32 @pthread_cancel(i64) { + ret i32 0 +} -declare extern_weak i32 @sched_yield() +define weak i32 @sched_yield() { + ret i32 0 +} -declare extern_weak i32 @pthread_mutex_lock(%union.pthread_mutex_t*) +define weak i32 @pthread_mutex_lock(%union.pthread_mutex_t*) { + ret i32 0 +} -declare extern_weak i32 @pthread_mutex_trylock(%union.pthread_mutex_t*) +define weak i32 @pthread_mutex_trylock(%union.pthread_mutex_t*) { + ret i32 0 +} -declare extern_weak i32 @pthread_mutex_timedlock(%union.pthread_mutex_t*, %struct.timespec*) +define weak i32 @pthread_mutex_timedlock(%union.pthread_mutex_t*, %struct.timespec*) { + ret i32 0 +} -declare extern_weak i32 @pthread_mutex_unlock(%union.pthread_mutex_t*) +define weak i32 @pthread_mutex_unlock(%union.pthread_mutex_t*) { + ret i32 0 +} -declare extern_weak i32 @pthread_mutex_init(%union.pthread_mutex_t*, %union.pthread_mutexattr_t*) +define weak i32 @pthread_mutex_init(%union.pthread_mutex_t*, %union.pthread_mutexattr_t*) { + ret i32 0 +} -declare extern_weak i32 @pthread_mutex_destroy(%union.pthread_mutex_t*) +define weak i32 @pthread_mutex_destroy(%union.pthread_mutex_t*) { + ret i32 0 +} -declare extern_weak i32 @pthread_cond_broadcast(%union.pthread_cond_t*) +define weak i32 @pthread_cond_broadcast(%union.pthread_cond_t*) { + ret i32 0 +} -declare extern_weak i32 @pthread_cond_signal(%union.pthread_cond_t*) +define weak i32 @pthread_cond_signal(%union.pthread_cond_t*) { + ret i32 0 +} -declare extern_weak i32 @pthread_cond_wait(%union.pthread_cond_t*, %union.pthread_mutex_t*) +define weak i32 @pthread_cond_wait(%union.pthread_cond_t*, %union.pthread_mutex_t*) { + ret i32 0 +} -declare extern_weak i32 @pthread_cond_timedwait(%union.pthread_cond_t*, %union.pthread_mutex_t*, %struct.timespec*) +define weak i32 @pthread_cond_timedwait(%union.pthread_cond_t*, %union.pthread_mutex_t*, %struct.timespec*) { + ret i32 0 +} -declare extern_weak i32 @pthread_cond_destroy(%union.pthread_cond_t*) +define weak i32 @pthread_cond_destroy(%union.pthread_cond_t*) { + ret i32 0 +} -declare extern_weak i32 @pthread_key_create(i32*, void (i8*)*) +define weak i32 @pthread_key_create(i32*, void (i8*)*) { + ret i32 0 +} -declare extern_weak i32 @pthread_key_delete(i32) +define weak i32 @pthread_key_delete(i32) { + ret i32 0 +} -declare extern_weak i32 @pthread_mutexattr_init(%union.pthread_mutexattr_t*) +define weak i32 @pthread_mutexattr_init(%union.pthread_mutexattr_t*) { + ret i32 0 +} -declare extern_weak i32 @pthread_mutexattr_settype(%union.pthread_mutexattr_t*, i32) +define weak i32 @pthread_mutexattr_settype(%union.pthread_mutexattr_t*, i32) { + ret i32 0 +} -declare extern_weak i32 @pthread_mutexattr_destroy(%union.pthread_mutexattr_t*) +define weak i32 @pthread_mutexattr_destroy(%union.pthread_mutexattr_t*) { + ret i32 0 +} diff --git a/llvm/test/Transforms/GVN/2009-03-10-PREOnVoid.ll b/llvm/test/Transforms/GVN/2009-03-10-PREOnVoid.ll index 89d6a5f982b8..fd31fce59a84 100644 --- a/llvm/test/Transforms/GVN/2009-03-10-PREOnVoid.ll +++ b/llvm/test/Transforms/GVN/2009-03-10-PREOnVoid.ll @@ -53,30 +53,58 @@ bb11: ; preds = %bb7, %bb5 unreachable } -declare i32 @pthread_once(i32*, void ()*) +define i32 @pthread_once(i32*, void ()*) { + ret i32 0 +} -declare i8* @pthread_getspecific(i32) +define i8* @pthread_getspecific(i32) { + ret i8* null +} -declare i32 @pthread_setspecific(i32, i8*) +define i32 @pthread_setspecific(i32, i8*) { + ret i32 0 +} -declare i32 @pthread_create(i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*) +define i32 @pthread_create(i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*) { + ret i32 0 +} -declare i32 @pthread_cancel(i32) +define i32 @pthread_cancel(i32) { + ret i32 0 +} -declare i32 @pthread_mutex_lock(%struct.pthread_mutex_t*) +define i32 @pthread_mutex_lock(%struct.pthread_mutex_t*) { + ret i32 0 +} -declare i32 @pthread_mutex_trylock(%struct.pthread_mutex_t*) +define i32 @pthread_mutex_trylock(%struct.pthread_mutex_t*) { + ret i32 0 +} -declare i32 @pthread_mutex_unlock(%struct.pthread_mutex_t*) +define i32 @pthread_mutex_unlock(%struct.pthread_mutex_t*) { + ret i32 0 +} -declare i32 @pthread_mutex_init(%struct.pthread_mutex_t*, %struct.__sched_param*) +define i32 @pthread_mutex_init(%struct.pthread_mutex_t*, %struct.__sched_param*) { + ret i32 0 +} -declare i32 @pthread_key_create(i32*, void (i8*)*) +define i32 @pthread_key_create(i32*, void (i8*)*) { + ret i32 0 +} -declare i32 @pthread_key_delete(i32) +define i32 @pthread_key_delete(i32) { + ret i32 0 +} -declare i32 @pthread_mutexattr_init(%struct.__sched_param*) +define i32 @pthread_mutexattr_init(%struct.__sched_param*) { + ret i32 0 +} -declare i32 @pthread_mutexattr_settype(%struct.__sched_param*, i32) +define i32 @pthread_mutexattr_settype(%struct.__sched_param*, i32) { + ret i32 0 +} -declare i32 @pthread_mutexattr_destroy(%struct.__sched_param*) +define i32 @pthread_mutexattr_destroy(%struct.__sched_param*) { + ret i32 0 +} diff --git a/llvm/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll b/llvm/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll index a1b69efe1a76..d6a565ad10a8 100644 --- a/llvm/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll +++ b/llvm/test/Transforms/GlobalOpt/2009-02-15-BitcastAlias.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -globalopt -@g = external global i32 +@g = global i32 0 @a = alias bitcast (i32* @g to i8*) diff --git a/llvm/test/Transforms/GlobalOpt/alias-resolve.ll b/llvm/test/Transforms/GlobalOpt/alias-resolve.ll index 5e229b942680..64e3d88af8aa 100644 --- a/llvm/test/Transforms/GlobalOpt/alias-resolve.ll +++ b/llvm/test/Transforms/GlobalOpt/alias-resolve.ll @@ -9,8 +9,10 @@ @bar1 = alias void ()* @bar2 ; CHECK: @bar1 = alias void ()* @bar2 -declare void @bar2() -; CHECK: declare void @bar2() +define void @bar2() { + ret void +} +; CHECK: define void @bar2() define void @baz() { entry: diff --git a/llvm/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll b/llvm/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll index c27fe0ab6a6d..7f9bd9e40dcb 100644 --- a/llvm/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll +++ b/llvm/test/Transforms/InstCombine/2007-09-10-AliasConstFold.ll @@ -3,7 +3,9 @@ @__gthrw_pthread_cancel = alias weak i32 (i32)* @pthread_cancel ; [#uses=1] @__gthread_active_ptr.5335 = internal constant i8* bitcast (i32 (i32)* @__gthrw_pthread_cancel to i8*) ; [#uses=1] -declare extern_weak i32 @pthread_cancel(i32) +define weak i32 @pthread_cancel(i32) { + ret i32 0 +} define i1 @__gthread_active_p() { entry: diff --git a/llvm/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll b/llvm/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll index 23ee12ba754f..c7cef752dcc9 100644 --- a/llvm/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll +++ b/llvm/test/Transforms/InstCombine/2007-09-17-AliasConstFold2.ll @@ -3,7 +3,9 @@ @A = alias weak void ()* @B ; [#uses=1] -declare extern_weak void @B() +define weak void @B() { + ret void +} define i32 @active() { entry: diff --git a/llvm/test/Transforms/MetaRenamer/metarenamer.ll b/llvm/test/Transforms/MetaRenamer/metarenamer.ll index 4020e1045081..6297af62ff0c 100644 --- a/llvm/test/Transforms/MetaRenamer/metarenamer.ll +++ b/llvm/test/Transforms/MetaRenamer/metarenamer.ll @@ -14,7 +14,9 @@ target triple = "x86_64-pc-linux-gnu" @func_7_xxx = alias weak i32 (...)* @aliased_func_7_xxx -declare i32 @aliased_func_7_xxx(...) +define i32 @aliased_func_7_xxx(...) { + ret i32 0 +} define i32 @func_3_xxx() nounwind uwtable ssp { ret i32 3 diff --git a/llvm/test/Verifier/alias.ll b/llvm/test/Verifier/alias.ll new file mode 100644 index 000000000000..e3636bc7017f --- /dev/null +++ b/llvm/test/Verifier/alias.ll @@ -0,0 +1,12 @@ +; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s + + +declare void @f() +@fa = alias void ()* @f +; CHECK: Alias must point to a definition +; CHECK-NEXT: @fa + +@g = external global i32 +@ga = alias i32* @g +; CHECK: Alias must point to a definition +; CHECK-NEXT: @ga