mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-03 03:36:07 +00:00

Reland of 00bf4755. This patches fixes the visibility and linkage information of symbols referring to IR globals. Emission of external declarations is now done in the first execution of emitConstantPool rather than in emitLinkage (and a few other places). This is the point where we have already gathered information about used symbols (by running the MC Lower PrePass) and not yet started emitting any functions so that any declarations that need to be emitted are done so at the top of the file before any functions. This changes the order of a few directives in the final asm file which required an update to a few tests. Reviewed By: sbc100 Differential Revision: https://reviews.llvm.org/D118995
77 lines
2.9 KiB
LLVM
77 lines
2.9 KiB
LLVM
; RUN: llc < %s --mtriple=wasm32-unknown-unknown -asm-verbose=false -mattr=+reference-types | FileCheck %s
|
|
|
|
%funcref = type i8 addrspace(20)* ;; addrspace 20 is nonintegral
|
|
|
|
@funcref_table = local_unnamed_addr addrspace(1) global [0 x %funcref] undef
|
|
|
|
define %funcref @get_funcref_from_table(i32 %i) {
|
|
; CHECK-LABEL: get_funcref_from_table:
|
|
; CHECK-NEXT: .functype get_funcref_from_table (i32) -> (funcref)
|
|
; CHECK-NEXT: local.get 0
|
|
; CHECK-NEXT: table.get funcref_table
|
|
; CHECK-NEXT: end_function
|
|
%p = getelementptr [0 x %funcref], [0 x %funcref] addrspace (1)* @funcref_table, i32 0, i32 %i
|
|
%ref = load %funcref, %funcref addrspace(1)* %p
|
|
ret %funcref %ref
|
|
}
|
|
|
|
define %funcref @get_funcref_from_table_const() {
|
|
; CHECK-LABEL: get_funcref_from_table_const:
|
|
; CHECK-NEXT: .functype get_funcref_from_table_const () -> (funcref)
|
|
; CHECK-NEXT: i32.const 0
|
|
; CHECK-NEXT: table.get funcref_table
|
|
; CHECK-NEXT: end_function
|
|
%p = getelementptr [0 x %funcref], [0 x %funcref] addrspace (1)* @funcref_table, i32 0, i32 0
|
|
%ref = load %funcref, %funcref addrspace(1)* %p
|
|
ret %funcref %ref
|
|
}
|
|
|
|
define %funcref @get_funcref_from_table_with_offset(i32 %i) {
|
|
; CHECK-LABEL: get_funcref_from_table_with_offset:
|
|
; CHECK-NEXT: .functype get_funcref_from_table_with_offset (i32) -> (funcref)
|
|
; CHECK-NEXT: local.get 0
|
|
; CHECK-NEXT: i32.const 2
|
|
; CHECK-NEXT: i32.add
|
|
; CHECK-NEXT: table.get funcref_table
|
|
; CHECK-NEXT: end_function
|
|
%off = add nsw i32 %i, 2
|
|
%p = getelementptr [0 x %funcref], [0 x %funcref] addrspace (1)* @funcref_table, i32 0, i32 %off
|
|
%ref = load %funcref, %funcref addrspace(1)* %p
|
|
ret %funcref %ref
|
|
}
|
|
|
|
|
|
define %funcref @get_funcref_from_table_with_var_offset(i32 %i, i32 %j) {
|
|
; CHECK-LABEL: get_funcref_from_table_with_var_offset:
|
|
; CHECK-NEXT: .functype get_funcref_from_table_with_var_offset (i32, i32) -> (funcref)
|
|
; CHECK-NEXT: local.get 0
|
|
; CHECK-NEXT: local.get 1
|
|
; CHECK-NEXT: i32.add
|
|
; CHECK-NEXT: table.get funcref_table
|
|
; CHECK-NEXT: end_function
|
|
%off = add nsw i32 %i, %j
|
|
%p = getelementptr [0 x %funcref], [0 x %funcref] addrspace (1)* @funcref_table, i32 0, i32 %off
|
|
%ref = load %funcref, %funcref addrspace(1)* %p
|
|
ret %funcref %ref
|
|
}
|
|
|
|
declare i32 @get_offset()
|
|
|
|
define %funcref @get_funcref_from_table_with_var_offset2(i32 %i) {
|
|
; CHECK-LABEL: get_funcref_from_table_with_var_offset2:
|
|
; CHECK-NEXT: .functype get_funcref_from_table_with_var_offset2 (i32) -> (funcref)
|
|
; CHECK-NEXT: local.get 0
|
|
; CHECK-NEXT: call get_offset
|
|
; CHECK-NEXT: i32.add
|
|
; CHECK-NEXT: table.get funcref_table
|
|
; CHECK-NEXT: end_function
|
|
%j = call i32 @get_offset()
|
|
%off = add nsw i32 %i, %j
|
|
%p = getelementptr [0 x %funcref], [0 x %funcref] addrspace (1)* @funcref_table, i32 0, i32 %off
|
|
%ref = load %funcref, %funcref addrspace(1)* %p
|
|
ret %funcref %ref
|
|
}
|
|
|
|
; CHECK: .tabletype funcref_table, funcref
|
|
; CHECK-LABEL: funcref_table:
|