Skip to content

[WebAssembly] Use 64-bit table when targeting wasm64 #92042

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions lld/test/wasm/shared64.s
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ get_local_func_address:
# CHECK-NEXT: Index: 0
# CHECK-NEXT: ElemType: FUNCREF
# CHECK-NEXT: Limits:
# CHECK-NEXT: Flags: [ IS_64 ]
# CHECK-NEXT: Minimum: 0x2
# CHECK-NEXT: - Module: env
# CHECK-NEXT: Field: __stack_pointer
Expand All @@ -170,11 +171,6 @@ get_local_func_address:
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: GlobalType: I64
# CHECK-NEXT: GlobalMutable: false
# CHECK-NEXT: - Module: env
# CHECK-NEXT: Field: __table_base32
# CHECK-NEXT: Kind: GLOBAL
# CHECK-NEXT: GlobalType: I32
# CHECK-NEXT: GlobalMutable: false
# CHECK-NEXT: - Module: GOT.mem
# CHECK-NEXT: Field: indirect_func
# CHECK-NEXT: Kind: GLOBAL
Expand Down Expand Up @@ -209,7 +205,7 @@ get_local_func_address:
# CHECK-NEXT: Segments:
# CHECK-NEXT: - Offset:
# CHECK-NEXT: Opcode: GLOBAL_GET
# CHECK-NEXT: Index: 3
# CHECK-NEXT: Index: 2
# CHECK-NEXT: Functions: [ 3, 2 ]

# check the generated code in __wasm_call_ctors and __wasm_apply_data_relocs functions
Expand All @@ -223,7 +219,7 @@ get_local_func_address:
# DIS-NEXT: i64.const 4
# DIS-NEXT: global.get 1
# DIS-NEXT: i64.add
# DIS-NEXT: global.get 5
# DIS-NEXT: global.get 4
# DIS-NEXT: i64.store 0:p2align=2
# DIS-NEXT: i64.const 12
# DIS-NEXT: global.get 1
Expand All @@ -242,12 +238,12 @@ get_local_func_address:
# DIS-NEXT: i64.const 24
# DIS-NEXT: global.get 1
# DIS-NEXT: i64.add
# DIS-NEXT: global.get 6
# DIS-NEXT: global.get 5
# DIS-NEXT: i64.store 0:p2align=2
# DIS-NEXT: i64.const 32
# DIS-NEXT: global.get 1
# DIS-NEXT: i64.add
# DIS-NEXT: global.get 7
# DIS-NEXT: global.get 6
# DIS-NEXT: i32.const 4
# DIS-NEXT: i32.add
# DIS-NEXT: i32.store 0
Expand Down
10 changes: 0 additions & 10 deletions lld/wasm/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -870,13 +870,6 @@ static void createSyntheticSymbols() {
WasmSym::tableBase = createUndefinedGlobal("__table_base", globalType);
WasmSym::memoryBase->markLive();
WasmSym::tableBase->markLive();
if (is64) {
WasmSym::tableBase32 =
createUndefinedGlobal("__table_base32", &globalTypeI32);
WasmSym::tableBase32->markLive();
} else {
WasmSym::tableBase32 = nullptr;
}
} else {
// For non-PIC code
WasmSym::stackPointer = createGlobalVariable("__stack_pointer", true);
Expand Down Expand Up @@ -923,9 +916,6 @@ static void createOptionalSymbols() {
WasmSym::heapEnd = symtab->addOptionalDataSymbol("__heap_end");
WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base");
if (config->is64.value_or(false))
WasmSym::definedTableBase32 =
symtab->addOptionalDataSymbol("__table_base32");
}

// For non-shared memory programs we still need to define __tls_base since we
Expand Down
2 changes: 0 additions & 2 deletions lld/wasm/Symbols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ GlobalSymbol *WasmSym::tlsSize;
GlobalSymbol *WasmSym::tlsAlign;
UndefinedGlobal *WasmSym::tableBase;
DefinedData *WasmSym::definedTableBase;
UndefinedGlobal *WasmSym::tableBase32;
DefinedData *WasmSym::definedTableBase32;
UndefinedGlobal *WasmSym::memoryBase;
DefinedData *WasmSym::definedMemoryBase;
TableSymbol *WasmSym::indirectFunctionTable;
Expand Down
5 changes: 0 additions & 5 deletions lld/wasm/Symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,11 +603,6 @@ struct WasmSym {
// Used in PIC code for offset of indirect function table
static UndefinedGlobal *tableBase;
static DefinedData *definedTableBase;
// 32-bit copy in wasm64 to work around init expr limitations.
// These can potentially be removed again once we have
// https://github.com/WebAssembly/extended-const
static UndefinedGlobal *tableBase32;
static DefinedData *definedTableBase32;

// __memory_base
// Used in PIC code for offset of global data
Expand Down
8 changes: 3 additions & 5 deletions lld/wasm/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,12 +584,10 @@ void ElemSection::writeBody() {
initExpr.Extended = false;
if (ctx.isPic) {
initExpr.Inst.Opcode = WASM_OPCODE_GLOBAL_GET;
initExpr.Inst.Value.Global =
(config->is64.value_or(false) ? WasmSym::tableBase32
: WasmSym::tableBase)
->getGlobalIndex();
initExpr.Inst.Value.Global = WasmSym::tableBase->getGlobalIndex();
} else {
initExpr.Inst.Opcode = WASM_OPCODE_I32_CONST;
bool is64 = config->is64.value_or(false);
initExpr.Inst.Opcode = is64 ? WASM_OPCODE_I64_CONST : WASM_OPCODE_I32_CONST;
initExpr.Inst.Value.Int32 = config->tableBase;
}
writeInitExpr(os, initExpr);
Expand Down
10 changes: 4 additions & 6 deletions lld/wasm/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,8 @@ static void finalizeIndirectFunctionTable() {
limits.Flags |= WASM_LIMITS_FLAG_HAS_MAX;
limits.Maximum = limits.Minimum;
}
if (config->is64.value_or(false))
limits.Flags |= WASM_LIMITS_FLAG_IS_64;
WasmSym::indirectFunctionTable->setLimits(limits);
}

Expand Down Expand Up @@ -1691,12 +1693,8 @@ void Writer::createSyntheticSectionsPostLayout() {
void Writer::run() {
// For PIC code the table base is assigned dynamically by the loader.
// For non-PIC, we start at 1 so that accessing table index 0 always traps.
if (!ctx.isPic) {
if (WasmSym::definedTableBase)
WasmSym::definedTableBase->setVA(config->tableBase);
if (WasmSym::definedTableBase32)
WasmSym::definedTableBase32->setVA(config->tableBase);
}
if (!ctx.isPic && WasmSym::definedTableBase)
WasmSym::definedTableBase->setVA(config->tableBase);

log("-- createOutputSegments");
createOutputSegments();
Expand Down
12 changes: 0 additions & 12 deletions llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -885,18 +885,6 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
Table->setNoStrip();
MIB.addImm(0);
}
// See if we must truncate the function pointer.
// CALL_INDIRECT takes an i32, but in wasm64 we represent function pointers
// as 64-bit for uniformity with other pointer types.
// See also: WebAssemblyISelLowering.cpp: LowerCallResults
if (Subtarget->hasAddr64()) {
auto Wrap = BuildMI(*FuncInfo.MBB, std::prev(FuncInfo.InsertPt), MIMD,
TII.get(WebAssembly::I32_WRAP_I64));
Register Reg32 = createResultReg(&WebAssembly::I32RegClass);
Wrap.addReg(Reg32, RegState::Define);
Wrap.addReg(CalleeReg);
CalleeReg = Reg32;
}
}

for (unsigned ArgReg : Args)
Expand Down
14 changes: 0 additions & 14 deletions llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,20 +576,6 @@ LowerCallResults(MachineInstr &CallResults, DebugLoc DL, MachineBasicBlock *BB,
const MCInstrDesc &MCID = TII.get(CallOp);
MachineInstrBuilder MIB(MF, MF.CreateMachineInstr(MCID, DL));

// See if we must truncate the function pointer.
// CALL_INDIRECT takes an i32, but in wasm64 we represent function pointers
// as 64-bit for uniformity with other pointer types.
// See also: WebAssemblyFastISel::selectCall
if (IsIndirect && MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()) {
Register Reg32 =
MF.getRegInfo().createVirtualRegister(&WebAssembly::I32RegClass);
auto &FnPtr = CallParams.getOperand(0);
BuildMI(*BB, CallResults.getIterator(), DL,
TII.get(WebAssembly::I32_WRAP_I64), Reg32)
.addReg(FnPtr.getReg());
FnPtr.setReg(Reg32);
}

// Move the function pointer to the end of the arguments for indirect calls
if (IsIndirect) {
auto FnPtr = CallParams.getOperand(0);
Expand Down
14 changes: 0 additions & 14 deletions llvm/test/CodeGen/WebAssembly/fast-isel-call-indirect64.ll

This file was deleted.

5 changes: 2 additions & 3 deletions llvm/test/CodeGen/WebAssembly/function-pointer64.ll
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ entry:
; CHECK: .functype foo (i64) -> ()
; CHECK-NEXT: i32.const 1
; CHECK-NEXT: local.get 0
; CHECK-NEXT: i32.wrap_i64
; CHECK-NEXT: call_indirect (i32) -> ()
; REF: call_indirect __indirect_function_table, (i32) -> ()

Expand All @@ -53,10 +52,10 @@ entry:
; YAML: - Type: CODE
; YAML: - Type: R_WASM_TABLE_INDEX_SLEB64
; YAML-NEXT: Index: 0
; YAML-NEXT: Offset: 0x16
; YAML-NEXT: Offset: 0x15
; YAML: - Type: R_WASM_TABLE_INDEX_SLEB64
; YAML-NEXT: Index: 0
; YAML-NEXT: Offset: 0x29
; YAML-NEXT: Offset: 0x28

; YAML: - Type: DATA
; YAML: - Type: R_WASM_TABLE_INDEX_I64
Expand Down
Loading